Skip to content

Commit 3f9c03a

Browse files
author
St-Ex
authored
include-files: add automatic shifting (#105)
1 parent 2833e88 commit 3f9c03a

File tree

7 files changed

+110
-8
lines changed

7 files changed

+110
-8
lines changed

include-files/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ DIFF ?= diff --strip-trailing-cr -u
33
test: sample.md file-a.md file-b.md file-c.md include-files.lua
44
@pandoc --lua-filter=include-files.lua --to=native $< \
55
| $(DIFF) expected.native -
6+
@pandoc --lua-filter=include-files.lua -M include-auto --to=native $< \
7+
| $(DIFF) expected-auto.native -
68

79
expected.native: sample.md file-a.md file-b.md file-c.md include-files.lua
810
pandoc --lua-filter=include-files.lua --output $@ $<
911

12+
expected-auto.native: sample.md file-a.md file-b.md file-c.md include-files.lua
13+
pandoc --lua-filter=include-files.lua --output $@ $<
14+
1015
.PHONY: test

include-files/README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,36 @@ Metadata from included files is discarded.
1616
The default is to include the subdocuments unchanged, but it can
1717
be convenient to modify the level of headers; a top-level header
1818
in an included file should be a second or third-level header in
19-
the final document. Use the `shift-heading-level-by` attribute to
20-
control header shifting.
19+
the final document.
20+
21+
#### Manual shifting
22+
23+
Use the `shift-heading-level-by` attribute to control header
24+
shifting.
25+
26+
#### Automatic shifting
27+
28+
1. Add metadata `-M include-auto` to enable automatic shifting.
29+
2. Do not specify `shift-heading-level-by`
30+
3. It will be inferred to the last heading level encountered
31+
32+
_Example_ :
33+
34+
````md
35+
# Title f
36+
37+
This is `file-f.md`.
38+
39+
## Subtitle f
40+
41+
```{.include} >> equivalent to {.include shift-heading-level-by=2}
42+
file-a.md
43+
```
44+
45+
```{.include shift-heading-level-by=1} >> force shift to be 1
46+
file-a.md
47+
```
48+
````
2149

2250
### Comments
2351

@@ -37,7 +65,7 @@ Included files can in turn include other files. Note that all
3765
filenames must be relative to the directory from which pandoc is
3866
run. I.e., if a file `a/b.md` is included in the main document,
3967
and another file `a/b/c.md` should be included, the full relative
40-
path must be used. Writing `b/c.md` in `a/b.md` would *not* work.
68+
path must be used. Writing `b/c.md` in `a/b.md` would _not_ work.
4169

4270
## Example
4371

include-files/expected-auto.native

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[Header 1 ("section-1",[],[]) [Str "Section",Space,Str "1"]
2+
,Para [Str "Thanks",Space,Str "everyone!"]
3+
,Header 2 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
4+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
5+
,Header 2 ("file-b",[],[]) [Str "File",Space,Str "b"]
6+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-b.md",Str "."]
7+
,Para [Str "It",Space,Str "has",Space,Str "two",Space,Str "paragraphs",Space,Str "and",Space,Str "a",Space,Str "header."]
8+
,Header 1 ("different-format",[],[]) [Str "Different",Space,Str "format"]
9+
,Header 2 ("org-header",[],[]) [Str "Org",Space,Str "header"]
10+
,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str "."]
11+
,Header 1 ("recursive-transclusion",[],[]) [Str "Recursive",Space,Str "transclusion"]
12+
,Header 2 ("title-f",[],[]) [Str "Title",Space,Str "f"]
13+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-f.md",Str "."]
14+
,Header 3 ("subtitle-f",[],[]) [Str "Subtitle",Space,Str "f"]
15+
,Header 4 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
16+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
17+
,Header 3 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
18+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
19+
,Header 1 ("appendix",[],[]) [Str "Appendix"]
20+
,Para [Str "More",Space,Str "info",Space,Str "goes",Space,Str "here."]
21+
,Header 2 ("questionaire",[],[]) [Str "Questionaire"]
22+
,BulletList
23+
[[Plain [Str "Is",Space,Str "this",Space,Str "good?"]]]]

include-files/expected.native

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[Header 1 ("section-1",[],[]) [Str "Section",Space,Str "1"]
22
,Para [Str "Thanks",Space,Str "everyone!"]
3+
,Header 1 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
34
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
45
,Header 1 ("file-b",[],[]) [Str "File",Space,Str "b"]
56
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-b.md",Str "."]
@@ -8,7 +9,12 @@
89
,Header 2 ("org-header",[],[]) [Str "Org",Space,Str "header"]
910
,Para [Str "This",Space,Str "is",Space,Emph [Str "emphasized"],Str "."]
1011
,Header 1 ("recursive-transclusion",[],[]) [Str "Recursive",Space,Str "transclusion"]
12+
,Header 1 ("title-f",[],[]) [Str "Title",Space,Str "f"]
1113
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-f.md",Str "."]
14+
,Header 2 ("subtitle-f",[],[]) [Str "Subtitle",Space,Str "f"]
15+
,Header 1 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
16+
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
17+
,Header 2 ("title-of-file-a",[],[]) [Str "Title",Space,Str "of",Space,Str "file-a"]
1218
,Para [Str "This",Space,Str "is",Space,Code ("",[],[]) "file-a.md",Str "."]
1319
,Header 1 ("appendix",[],[]) [Str "Appendix"]
1420
,Para [Str "More",Space,Str "info",Space,Str "goes",Space,Str "here."]

include-files/file-a.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
# Title of file-a
2+
13
This is `file-a.md`.

include-files/file-f.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
# Title f
2+
13
This is `file-f.md`.
24

3-
``` {.include}
5+
## Subtitle f
6+
7+
```{.include}
8+
file-a.md
9+
```
10+
11+
```{.include shift-heading-level-by=1}
412
file-a.md
513
```

include-files/include-files.lua

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@
66
-- pandoc's List type
77
local List = require 'pandoc.List'
88

9+
--- Get include auto mode
10+
local include_auto = false
11+
function get_vars (meta)
12+
if meta['include-auto'] then
13+
include_auto = true
14+
end
15+
end
16+
17+
--- Keep last heading level found
18+
local last_heading_level = 0
19+
function update_last_level(header)
20+
last_heading_level = header.level
21+
end
22+
923
--- Shift headings in block list by given number
1024
local function shift_headings(blocks, shift_by)
1125
if not shift_by then
@@ -32,9 +46,21 @@ function transclude (cb)
3246

3347
-- Markdown is used if this is nil.
3448
local format = cb.attributes['format']
35-
local shift_heading_level_by =
36-
tonumber(cb.attributes['shift-heading-level-by'])
3749

50+
-- Attributes shift headings
51+
local shift_heading_level_by = 0
52+
local shift_input = cb.attributes['shift-heading-level-by']
53+
if shift_input then
54+
shift_heading_level_by = tonumber(shift_input)
55+
else
56+
if include_auto then
57+
-- Auto shift headings
58+
shift_heading_level_by = last_heading_level
59+
end
60+
end
61+
62+
--- keep track of level before recusion
63+
local buffer_last_heading_level = last_heading_level
3864

3965
local blocks = List:new()
4066
for line in cb.text:gmatch('[^\n]+') do
@@ -44,11 +70,14 @@ function transclude (cb)
4470
io.stderr:write("Cannot open file " .. line .. " | Skipping includes\n")
4571
else
4672
local contents = pandoc.read(fh:read '*a', format).blocks
73+
last_heading_level = 0
4774
-- recursive transclusion
4875
contents = pandoc.walk_block(
4976
pandoc.Div(contents),
50-
{CodeBlock = transclude}
77+
{ Header = update_last_level, CodeBlock = transclude }
5178
).content
79+
--- reset to level before recursion
80+
last_heading_level = buffer_last_heading_level
5281
blocks:extend(shift_headings(contents, shift_heading_level_by))
5382
fh:close()
5483
end
@@ -58,5 +87,6 @@ function transclude (cb)
5887
end
5988

6089
return {
61-
{CodeBlock = transclude}
90+
{ Meta = get_vars },
91+
{ Header = update_last_level, CodeBlock = transclude }
6292
}

0 commit comments

Comments
 (0)