Skip to content

Commit 70c0661

Browse files
b3tarleb
authored andcommitted
include-code-files: Initial import
1 parent 386ec08 commit 70c0661

File tree

5 files changed

+149
-0
lines changed

5 files changed

+149
-0
lines changed

include-code-files/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
DIFF ?= diff --strip-trailing-cr -u
2+
3+
test: sample.md include-code-files.lua
4+
@pandoc --lua-filter=include-code-files.lua --to=native $< \
5+
| $(DIFF) expected.native -
6+
7+
expected.native: sample.md include-code-files.lua
8+
pandoc --lua-filter=include-code-files.lua --output $@ $<
9+
10+
.PHONY: test

include-code-files/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# include-code-files
2+
3+
Filter to include code from source files.
4+
5+
The filter is largely inspired by [pandoc-include-code](https://github.com/owickstrom/pandoc-include-code).
6+
7+
## Usage
8+
9+
The filter recognizes code blocks with the `include` attribute present. It
10+
swaps the content of the code block with contents from a file.
11+
12+
### Including Files
13+
14+
The simplest way to use this filter is to include an entire file:
15+
16+
```{include="hello.c"}
17+
```
18+
19+
You can still use other attributes, and classes, to control the code blocks:
20+
21+
```{.c include="hello.c" numberLines}
22+
```
23+
24+
### Ranges
25+
26+
If you want to include a specific range of lines, use `startLine` and `endLine`:
27+
28+
```{include="hello.c" startLine=35 endLine=80}
29+
```
30+
31+
### Dedent
32+
33+
Using the `dedent` attribute, you can have whitespaces removed on each line,
34+
where possible (non-whitespace character will not be removed even if they occur
35+
in the dedent area).
36+
37+
```{include="hello.c" dedent=4}
38+
```
39+
40+
### Line Numbers
41+
42+
If you include the `numberLines` class in your code block, and use `include`,
43+
the `startFrom` attribute will be added with respect to the included code's
44+
location in the source file.
45+
46+
```{include="hello.c" startLine=35 endLine=80 .numberLines}
47+
```
48+
49+
## Example
50+
51+
An HTML can be produced with this command:
52+
53+
pandoc --lua-filter=include-code-files.lua sample.md --output result.html
54+

include-code-files/expected.native

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[Header 1 ("inclusion",[],[]) [Str "Inclusion"]
2+
,CodeBlock ("",["lua","numberLines"],[]) "--- include-code-files.lua \8211 filter to include code from source files\n---\n--- Copyright: \169 2020 Bruno BEAUFILS\n--- License: MIT \8211 see LICENSE file for details\n\n--- Dedent a line\nlocal function dedent (line, n)\n return line:sub(1,n):gsub(\" \",\"\") .. line:sub(n+1)\nend\n\n--- Filter function for code blocks\nlocal function transclude (cb)\n if cb.attributes.include then\n local content = \"\"\n local fh = io.open(cb.attributes.include)\n if not fh then\n io.stderr:write(\"Cannot open file \" .. cb.attributes.include .. \" | Skipping includes\\n\")\n else\n local number = 1\n local start = 1\n if cb.attributes.startLine then\n cb.attributes.startFrom = cb.attributes.startLine\n start = tonumber(cb.attributes.startLine)\n end\n for line in fh:lines (\"L\")\n do\n if cb.attributes.dedent then\n line = dedent(line, cb.attributes.dedent)\n end\n if number >= start then\n if not cb.attributes.endLine or number <= tonumber(cb.attributes.endLine) then\n content = content .. line\n end\n end\n number = number + 1\n end \n fh:close()\n end \n -- remove key-value pair for used keys\n cb.attributes.include = nil\n cb.attributes.startLine = nil\n cb.attributes.endLine = nil\n cb.attributes.dedent = nil\n -- return final code block\n return pandoc.CodeBlock(content, cb.attr)\n end\nend\n\nreturn {\n { CodeBlock = transclude }\n}\n"
3+
,Header 1 ("ranges",[],[]) [Str "Ranges"]
4+
,CodeBlock ("",["lua","numberLines"],[("startFrom","7")]) "local function dedent (line, n)\n return line:sub(1,n):gsub(\" \",\"\") .. line:sub(n+1)\nend\n"
5+
,Header 1 ("detent",[],[]) [Str "Detent"]
6+
,Para [Code ("",[],[]) "detent",Space,Str "removes",Space,Str "specified",Space,Str "number",Space,Str "of",Space,Str "whitespaces",Space,Str "(and",Space,Str "only",SoftBreak,Str "whitespaces)",Space,Str "from",Space,Str "beginning",Space,Str "of",Space,Str "each",Space,Str "line"]
7+
,CodeBlock ("",["lua","bash","numberLines"],[("startFrom","8")]) "return line:sub(1,n):gsub(\" \",\"\") .. line:sub(n+1)\n"
8+
,CodeBlock ("",["lua","numberLines"],[("startFrom","50")]) "{CodeBlock = transclude }\n"]
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--- include-code-files.lua – filter to include code from source files
2+
---
3+
--- Copyright: © 2020 Bruno BEAUFILS
4+
--- License: MIT – see LICENSE file for details
5+
6+
--- Dedent a line
7+
local function dedent (line, n)
8+
return line:sub(1,n):gsub(" ","") .. line:sub(n+1)
9+
end
10+
11+
--- Filter function for code blocks
12+
local function transclude (cb)
13+
if cb.attributes.include then
14+
local content = ""
15+
local fh = io.open(cb.attributes.include)
16+
if not fh then
17+
io.stderr:write("Cannot open file " .. cb.attributes.include .. " | Skipping includes\n")
18+
else
19+
local number = 1
20+
local start = 1
21+
if cb.attributes.startLine then
22+
cb.attributes.startFrom = cb.attributes.startLine
23+
start = tonumber(cb.attributes.startLine)
24+
end
25+
for line in fh:lines ("L")
26+
do
27+
if cb.attributes.dedent then
28+
line = dedent(line, cb.attributes.dedent)
29+
end
30+
if number >= start then
31+
if not cb.attributes.endLine or number <= tonumber(cb.attributes.endLine) then
32+
content = content .. line
33+
end
34+
end
35+
number = number + 1
36+
end
37+
fh:close()
38+
end
39+
-- remove key-value pair for used keys
40+
cb.attributes.include = nil
41+
cb.attributes.startLine = nil
42+
cb.attributes.endLine = nil
43+
cb.attributes.dedent = nil
44+
-- return final code block
45+
return pandoc.CodeBlock(content, cb.attr)
46+
end
47+
end
48+
49+
return {
50+
{ CodeBlock = transclude }
51+
}

include-code-files/sample.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
author: me
3+
title: Including Hello World
4+
---
5+
6+
# Inclusion
7+
8+
``` {include="include-code-files.lua" .lua .numberLines}
9+
```
10+
11+
# Ranges
12+
13+
``` {include="include-code-files.lua" .lua startLine=7 endLine=9 .numberLines}
14+
```
15+
16+
# Detent
17+
18+
`detent` removes specified number of whitespaces (and only
19+
whitespaces) from beginning of each line
20+
21+
``` {include="include-code-files.lua" .lua startLine=8 endLine=8 dedent=4 .bash .numberLines}
22+
```
23+
24+
``` {include="include-code-files.lua" .lua startLine=50 endLine=50 dedent=5 .numberLines}
25+
```
26+

0 commit comments

Comments
 (0)