Skip to content

Commit 50cbeba

Browse files
committed
Add markdown figure filters.
1 parent 5d2024b commit 50cbeba

File tree

5 files changed

+226
-0
lines changed

5 files changed

+226
-0
lines changed

markdown-figures/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.PHONY: test
2+
3+
test:

markdown-figures/README.md

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Support for figures in Markdown
2+
3+
This filter provides two syntaxs to represent figures in markdown.
4+
5+
## Explicit syntax
6+
7+
The explicit syntax is constructed using a `div` with "figure" class. The
8+
caption is also specified using a `div` but with a "caption" class.
9+
10+
Here is an example.
11+
12+
```
13+
::: { .figure }
14+
15+
content.
16+
17+
:::: {.caption }
18+
caption
19+
::::
20+
21+
:::
22+
```
23+
24+
All elements inside the figure that are an image without a caption in its own
25+
paragraph become html's `img` tags.
26+
27+
Here is an example of figure containing two images and a caption.
28+
29+
```{markdown}
30+
::: { .figure }
31+
32+
![](test/media/rId25.jpg "")
33+
34+
![](test/media/rId25.jpg "")
35+
36+
:::: {.caption }
37+
caption
38+
::::
39+
40+
:::
41+
```
42+
43+
This will result in a single figure containing multiple images.
44+
45+
```
46+
$ pandoc -f markdown -t native --lua-filter=md-figure-explicit.lua fig-explicit.md
47+
48+
[Figure ("",[],[]) (Caption (Just []) [Para [Str "caption"]])
49+
[ Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")]
50+
, Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")]]]
51+
```
52+
53+
54+
```{html}
55+
<figure>
56+
<img src="test/media/rId25.jpg" />
57+
<img src="test/media/rId25.jpg" />
58+
<figcaption><p>caption</p></figcaption>
59+
</figure>
60+
```
61+
62+
This will result in a single figure containing multiple images.
63+
64+
## Implicit syntax
65+
66+
The second syntax uses the last paragraph inside the figure as the caption.
67+
68+
```{markdown}
69+
::: { .figure }
70+
71+
72+
![](test/media/rId25.jpg "")
73+
74+
![](test/media/rId25.jpg "")
75+
76+
This is a caption with
77+
multiple lines
78+
79+
:::
80+
81+
```
82+
83+
This results in the following output:
84+
85+
86+
```
87+
$ pandoc -f markdown -t native --lua-filter=md-figure-implicit.lua fig-implict.md
88+
[Figure ("",[],[])
89+
(Caption
90+
(Just [])
91+
[ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "caption",Space,Str "with",SoftBreak,Str "multiple",Space,Str "lines"]])
92+
[Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")],Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")]]]
93+
```
94+
95+
```{html}
96+
<figure>
97+
<img src="test/media/rId25.jpg" />
98+
<img src="test/media/rId25.jpg" />
99+
<figcaption><p>This is a caption with multiple lines</p></figcaption>
100+
</figure>
101+
```
102+
103+
## Sample Firefox's HTML rendering
104+
105+
For the implicit syntax example, this is firefox's render.
106+
107+
![Example](render.png)
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--- Translate Divs with the "figure" class into Figure elements.
2+
-- The contents of last child Div with the "caption" class will be used as the
3+
-- figure caption.
4+
function Div(div)
5+
6+
local content = div.content
7+
local attr = div.attr
8+
local null_caption = {
9+
short = {},
10+
long = {}
11+
}
12+
13+
if attr.classes:includes "figure" then
14+
15+
local new_content = pandoc.List({})
16+
17+
-- A div with the caption class is captured as the figure's
18+
-- caption.
19+
for _,elem in pairs(div.content) do
20+
if elem.t == 'Div' then
21+
null_caption.long = elem.content
22+
else
23+
new_content:insert(elem)
24+
end
25+
end
26+
27+
28+
-- Remove the figure for `SimpleFigure` with no caption inside a Figure.
29+
local final_content = pandoc.List({})
30+
31+
for _,elem in pairs(new_content) do
32+
-- Check that it is a simple figure with no caption
33+
if elem.t == 'Para' and
34+
#elem.content == 1 and
35+
elem.content[1].t == 'Image' and
36+
#elem.content[1].caption == 0 then
37+
38+
local image = elem.content[1]
39+
final_content:insert(pandoc.Plain({image}))
40+
else
41+
final_content:insert(elem)
42+
end
43+
end
44+
45+
-- Remove the figure class in the output
46+
attr.classes = attr.classes:filter(
47+
function(c) return c ~= "figure" end)
48+
49+
return pandoc.Figure(final_content, null_caption, attr)
50+
end
51+
52+
-- Return an identical div when it lacks the "figure" class.
53+
return pandoc.Div(content, attr)
54+
end
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
--- Translate Divs with the "figure" class into Figure elements.
2+
-- The contents of last paragraph became the figure caption will be used as the
3+
-- figure caption.
4+
function Div(div)
5+
6+
local content = div.content
7+
local attr = div.attr
8+
local null_caption = {
9+
short = {},
10+
long = {}
11+
}
12+
13+
if attr.classes:includes "figure" then
14+
15+
local new_content = pandoc.List({})
16+
17+
-- Capture the last element
18+
local last_elem = nil
19+
20+
for _,elem in pairs(div.content) do
21+
if last_elem then
22+
new_content:insert(last_elem)
23+
end
24+
last_elem = elem
25+
end
26+
27+
-- If the last element is a paragraph, use it as caption.
28+
if last_elem then
29+
if last_elem.t == 'Para' then
30+
null_caption.long = { last_elem }
31+
else
32+
new_content:insert(last_elem)
33+
end
34+
end
35+
36+
-- Remove the figure for `SimpleFigure` with no caption inside a Figure.
37+
local final_content = pandoc.List({})
38+
39+
for _,elem in pairs(new_content) do
40+
-- Check that it is a simple figure with no caption
41+
if elem.t == 'Para' and
42+
#elem.content == 1 and
43+
elem.content[1].t == 'Image' and
44+
#elem.content[1].caption == 0 then
45+
46+
local image = elem.content[1]
47+
final_content:insert(pandoc.Plain({image}))
48+
else
49+
final_content:insert(elem)
50+
end
51+
end
52+
53+
-- Remove the figure class in the output
54+
attr.classes = attr.classes:filter(
55+
function(c) return c ~= "figure" end)
56+
57+
return pandoc.Figure(final_content, null_caption, attr)
58+
end
59+
60+
-- Return an identical div when it lacks the "figure" class.
61+
return pandoc.Div(content, attr)
62+
end

markdown-figures/render.png

10.1 KB
Loading

0 commit comments

Comments
 (0)