This repository contains a small Lua-based AST filter for
Apex that unwraps certain block
elements so they are not wrapped in an extra <p> tag after rendering.
It uses the same Pandoc JSON filter protocol described in the Pandoc filter documentation, so it can also be used directly with Pandoc.
The filter operates on the Pandoc JSON AST and performs two related transformations:
-
Angle‑prefixed paragraphs: Any paragraph whose text begins with
<(a left angle bracket followed by a space) is treated as preformatted/HTML. The paragraph is converted from:{ "t": "Para", "c": [ ... inlines ... ] }into a:
{ "t": "RawBlock", "c": ["html", "< ..."] }This removes the wrapping
<p>tag while preserving any surrounding container, such as a block quote. -
Single‑image paragraphs: Any paragraph whose only inline is an
Imageis unwrapped into a bare<img>tag. This is useful for figure‑style constructs where you do not want a<p>wrapping the image.
In both cases, the filter only ever removes a wrapping paragraph; it does not change whether the content is inside a block quote, div, or other container.
Once this filter is published in the central directory, you will be able to install it automatically with:
apex --install-filter unwrapThis will clone the repository into your user filters directory:
$XOWNS_CONFIG_HOME/apex/filters/unwrapor~/.config/apex/filters/unwrap
After installation, you can enable the filter with:
apex --filter unwrap input.md > output.htmlYou can also run the Lua script directly from anywhere using the
--lua-filter flag:
apex --lua-filter /path/to/unwrap.lua input.md > output.htmlIf you prefer to install manually:
-
Ensure you have a Lua interpreter and the
dkjsonJSON library available. On macOS with Homebrew Lua, a typical setup is:brew install luarocks luarocks install dkjson
-
Copy
unwrap.luainto your filters directory:mkdir -p ~/.config/apex/filters cp unwrap.lua ~/.config/apex/filters/unwrap chmod +x ~/.config/apex/filters/unwrap
-
Run Apex with the filter:
apex --filter unwrap input.md > output.html
Because this is a standard Pandoc JSON filter, you can also use it with Pandoc:
pandoc input.md -t json \
| lua unwrap.lua \
| pandoc -f json -t html -o output.htmlThe filter:
- Reads the entire Pandoc JSON document from
stdinusingdkjson. - Walks the
blocksarray recursively:- Inside containers like
BlockQuote, it rewrites only the child blocks, so the block quote itself is preserved.
- Inside containers like
- For each block:
- If it is a paragraph starting with
<, it is converted to aRawBlock "html"using the concatenated inline text. - If it is a paragraph containing exactly one
Imageinline, it is converted to aRawBlock "html"that renders a single<img>element, preserving:- the image URL and title,
- the alt text (from the image inlines),
- any id, classes, or key‑value attributes from the Pandoc
Attrtriple.
- If it is a paragraph starting with
- Writes the modified JSON document to
stdout.