Skip to content

Commit

Permalink
Add markdown figure filters.
Browse files Browse the repository at this point in the history
  • Loading branch information
argent0 committed Jul 30, 2021
1 parent 5d2024b commit 50cbeba
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 0 deletions.
3 changes: 3 additions & 0 deletions markdown-figures/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.PHONY: test

test:
107 changes: 107 additions & 0 deletions markdown-figures/README.md
Original file line number Diff line number Diff line change
@@ -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}
<figure>
<img src="test/media/rId25.jpg" />
<img src="test/media/rId25.jpg" />
<figcaption><p>caption</p></figcaption>
</figure>
```

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}
<figure>
<img src="test/media/rId25.jpg" />
<img src="test/media/rId25.jpg" />
<figcaption><p>This is a caption with multiple lines</p></figcaption>
</figure>
```

## Sample Firefox's HTML rendering

For the implicit syntax example, this is firefox's render.

![Example](render.png)
54 changes: 54 additions & 0 deletions markdown-figures/md-figure-explicit.lua
Original file line number Diff line number Diff line change
@@ -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
62 changes: 62 additions & 0 deletions markdown-figures/md-figure-implicit.lua
Original file line number Diff line number Diff line change
@@ -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
Binary file added markdown-figures/render.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 50cbeba

Please sign in to comment.