Skip to content

Instantly share code, notes, and snippets.

@tarleb
Created July 15, 2022 12:54
Show Gist options
  • Save tarleb/a0646da1834318d4f71a780edaf9f870 to your computer and use it in GitHub Desktop.
Save tarleb/a0646da1834318d4f71a780edaf9f870 to your computer and use it in GitHub Desktop.
Custom syntax extension
--[[
Add support for a custom inline syntax.
This pandoc Lua filter allows to add a custom markup syntax
extension. It is designed to be adjustable; it should not be
necessary to modify the code below the separator line.
The example here allows to add highlighted text by enclosing the
text with `==` on each side. Pandoc supports this for HTML output
out of the box. Other outputs will need additional filters.
Copyright: © 2022 Albert Krewinkel
License: MIT
]]
-- Lua pattern matching the opening markup string.
local opening = [[==]]
-- Lua pattern matching the closing markup string.
local closing = [[==]]
-- Toggle whether the opening markup may be followed by whitespace.
local nospace = true
-- Function converting the enclosed inlines to their internal pandoc
-- representation.
local function markup_inlines (inlines)
return pandoc.Span(inlines, {class="mark"})
end
------------------------------------------------------------------------
local function is_space (inline)
return inline and
(inline.t == 'Space' or
inline.t == 'LineBreak' or
inline.t == 'SoftBreak')
end
function Inlines (inlines)
local result = pandoc.Inlines{}
local markup = nil
local start = nil
for i, inline in ipairs(inlines) do
if inline.tag == 'Str' then
if not markup then
local first = inline.text:match('^' .. opening .. '(.*)')
if first then
start = inline -- keep element around in case the
-- markup is not closed. Check if the
-- closing pattern is already in this
-- string.
local selfclosing = first:match('(.*)' .. closing .. '$')
if selfclosing then
result:insert(markup_inlines{pandoc.Str(selfclosing)})
elseif nospace and first == '' and is_space(inlines[i+1]) then
-- the opening pattern is followed by a space, but the
-- config disallows this.
result:insert(inline)
else
markup = pandoc.Inlines{pandoc.Str(first)}
end
else
result:insert(inline)
end
else
local last = inline.text:match('(.*)' .. closing .. '$')
if last then
markup:insert(pandoc.Str(last))
result:insert(markup_inlines(markup))
markup = nil
else
markup:insert(inline)
end
end
else
local acc = markup or result
acc:insert(inline)
end
end
-- keep unterminated markup
if markup then
markup:remove(1) -- the stripped-down first element
result:insert(start)
result:extend(markup)
end
return result
end
@TanteTroll
Copy link

Thanks a lot for sharing your work! I would love to make this work for obsidian compatibility but keep running into the following error message:

Error: Command failed: C:/Users/danie/AppData/Local/Pandoc/pandoc.exe --from=markdown-raw_tex+tex_math_single_backslash --to=html --katex --citeproc --bibliography=Bibliography.bib --csl=Chicago-origdate.csl --lua-filter=highlights.lua
Error running filter highlights.lua:
highlights.lua:41: attempt to call a nil value (field 'Inlines')
stack traceback:
highlights.lua:41: in function 'Inlines'

Could you take a moment to explain to me what I may be doing wrong? Thanks!

@tarleb
Copy link
Author

tarleb commented Sep 19, 2022

The most likely cause is an outdated pandoc version: the pandoc.Inlines function was added in pandoc 2.17, I think. Try updating to the latest version.

@ReaderGuy42
Copy link

ReaderGuy42 commented Dec 12, 2022

@tarleb
Thanks for this!! What would I have to add so the highlighting filter also triggers if the == is before a period or any other symbols like commas, apostrophes, etc.? so: ==highlighting==. or ==highlighting==,
As is it seems that this only works if it starts and stops with a space.
Thanks!

@tarleb
Copy link
Author

tarleb commented Dec 13, 2022

I don't have time to look into this right now, sorry. But why not try the latest pandoc nightly which includes this?

@TanteTroll
Copy link

Btw, since the last Pandoc update it just worked, thanks very much!

@kirmaha
Copy link

kirmaha commented Apr 10, 2024

I don't have time to look into this right now, sorry. But why not try the latest pandoc nightly which includes this?

As the link is down, I could not see this. But my guess is: you were talking about pandoc --from=markdown+mark, which enables highlighted text without the need of a Lua script.

@tarleb
Copy link
Author

tarleb commented Apr 10, 2024

Yes, exactly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment