diff --git a/markdown-figures/Makefile b/markdown-figures/Makefile new file mode 100644 index 00000000..d12e2106 --- /dev/null +++ b/markdown-figures/Makefile @@ -0,0 +1,3 @@ +.PHONY: test + +test: diff --git a/markdown-figures/README.md b/markdown-figures/README.md new file mode 100644 index 00000000..d624b32e --- /dev/null +++ b/markdown-figures/README.md @@ -0,0 +1,107 @@ +# Support for figures in Markdown + +This filter provides two syntaxs to represent figures in markdown. + +## Explicit syntax + +The explicit syntax is constructed using a `div` with "figure" class. The +caption is also specified using a `div` but with a "caption" class. + +Here is an example. + +``` +::: { .figure } + +content. + +:::: {.caption } +caption +:::: + +::: +``` + +All elements inside the figure that are an image without a caption in its own +paragraph become html's `img` tags. + +Here is an example of figure containing two images and a caption. + +```{markdown} +::: { .figure } + +![](test/media/rId25.jpg "") + +![](test/media/rId25.jpg "") + +:::: {.caption } +caption +:::: + +::: +``` + +This will result in a single figure containing multiple images. + +``` +$ pandoc -f markdown -t native --lua-filter=md-figure-explicit.lua fig-explicit.md + +[Figure ("",[],[]) (Caption (Just []) [Para [Str "caption"]]) + [ Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")] + , Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")]]] +``` + + +```{html} +
+ + +

caption

+
+``` + +This will result in a single figure containing multiple images. + +## Implicit syntax + +The second syntax uses the last paragraph inside the figure as the caption. + +```{markdown} +::: { .figure } + + +![](test/media/rId25.jpg "") + +![](test/media/rId25.jpg "") + +This is a caption with +multiple lines + +::: + +``` + +This results in the following output: + + +``` +$ pandoc -f markdown -t native --lua-filter=md-figure-implicit.lua fig-implict.md +[Figure ("",[],[]) + (Caption + (Just []) + [ Para [Str "This",Space,Str "is",Space,Str "a",Space,Str "caption",Space,Str "with",SoftBreak,Str "multiple",Space,Str "lines"]]) + [Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")],Plain [Image ("",[],[]) [] ("test/media/rId25.jpg","")]]] +``` + +```{html} +
+ + +

This is a caption with multiple lines

+
+``` + +## Sample Firefox's HTML rendering + +For the implicit syntax example, this is firefox's render. + +![Example](render.png) diff --git a/markdown-figures/md-figure-explicit.lua b/markdown-figures/md-figure-explicit.lua new file mode 100644 index 00000000..444e67a4 --- /dev/null +++ b/markdown-figures/md-figure-explicit.lua @@ -0,0 +1,54 @@ +--- Translate Divs with the "figure" class into Figure elements. +-- The contents of last child Div with the "caption" class will be used as the +-- figure caption. +function Div(div) + + local content = div.content + local attr = div.attr + local null_caption = { + short = {}, + long = {} + } + + if attr.classes:includes "figure" then + + local new_content = pandoc.List({}) + + -- A div with the caption class is captured as the figure's + -- caption. + for _,elem in pairs(div.content) do + if elem.t == 'Div' then + null_caption.long = elem.content + else + new_content:insert(elem) + end + end + + + -- Remove the figure for `SimpleFigure` with no caption inside a Figure. + local final_content = pandoc.List({}) + + for _,elem in pairs(new_content) do + -- Check that it is a simple figure with no caption + if elem.t == 'Para' and + #elem.content == 1 and + elem.content[1].t == 'Image' and + #elem.content[1].caption == 0 then + + local image = elem.content[1] + final_content:insert(pandoc.Plain({image})) + else + final_content:insert(elem) + end + end + + -- Remove the figure class in the output + attr.classes = attr.classes:filter( + function(c) return c ~= "figure" end) + + return pandoc.Figure(final_content, null_caption, attr) + end + + -- Return an identical div when it lacks the "figure" class. + return pandoc.Div(content, attr) +end diff --git a/markdown-figures/md-figure-implicit.lua b/markdown-figures/md-figure-implicit.lua new file mode 100644 index 00000000..d92308b9 --- /dev/null +++ b/markdown-figures/md-figure-implicit.lua @@ -0,0 +1,62 @@ +--- Translate Divs with the "figure" class into Figure elements. +-- The contents of last paragraph became the figure caption will be used as the +-- figure caption. +function Div(div) + + local content = div.content + local attr = div.attr + local null_caption = { + short = {}, + long = {} + } + + if attr.classes:includes "figure" then + + local new_content = pandoc.List({}) + + -- Capture the last element + local last_elem = nil + + for _,elem in pairs(div.content) do + if last_elem then + new_content:insert(last_elem) + end + last_elem = elem + end + + -- If the last element is a paragraph, use it as caption. + if last_elem then + if last_elem.t == 'Para' then + null_caption.long = { last_elem } + else + new_content:insert(last_elem) + end + end + + -- Remove the figure for `SimpleFigure` with no caption inside a Figure. + local final_content = pandoc.List({}) + + for _,elem in pairs(new_content) do + -- Check that it is a simple figure with no caption + if elem.t == 'Para' and + #elem.content == 1 and + elem.content[1].t == 'Image' and + #elem.content[1].caption == 0 then + + local image = elem.content[1] + final_content:insert(pandoc.Plain({image})) + else + final_content:insert(elem) + end + end + + -- Remove the figure class in the output + attr.classes = attr.classes:filter( + function(c) return c ~= "figure" end) + + return pandoc.Figure(final_content, null_caption, attr) + end + + -- Return an identical div when it lacks the "figure" class. + return pandoc.Div(content, attr) +end diff --git a/markdown-figures/render.png b/markdown-figures/render.png new file mode 100644 index 00000000..17f878ea Binary files /dev/null and b/markdown-figures/render.png differ