miti.sh/renderers/markdown.moon
Catalin Constantin Mititiuc 766c9bad62 Use '_' instead of '.' for numbering cosmo escapes
because it gets syntax highlighted weird because '.' is not valid for
like a variable name so the syntax highlighter is splitting the escape
phrase at the '.' which means that phrase won't match when unescaped so
it fails to get unescaped

for example, this would fail:

```
 $$ct
```
2025-06-25 21:10:30 -07:00

105 lines
2.6 KiB
Plaintext

Path = require "sitegen.path"
dollar_temp = "z000sitegen_markdown00dollar0000"
-- a constructor for quote delimited strings
simple_string = (delim) ->
import P from require "lpeg"
inner = P("\\#{delim}") + "\\\\" + (1 - P delim)
inner = inner^0
P(delim) * inner * P(delim)
lua_string = ->
import P, C, Cmt, Cb, Cg from require "lpeg"
check_lua_string = (str, pos, right, left) ->
#left == #right
string_open = P"[" * P"="^0 * "["
string_close = P"]" * P"="^0 * "]"
valid_close = Cmt C(string_close) * Cb"string_open", check_lua_string
Cg(string_open, "string_open") *
(1 - valid_close)^0 * string_close
-- returns a pattern that parses a cosmo template. Can be used to have
-- pre-processors ignore text that would be handled by cosmo
parse_cosmo = ->
import P, R, Cmt, Cs, V from require "lpeg"
curly = P {
P"{" * (
simple_string("'") +
simple_string('"') +
lua_string! +
V(1) +
(P(1) - "}")
)^0 * P"}"
}
alphanum = R "az", "AZ", "09", "__"
P"$" * alphanum^1 * (curly)^-1
escape_cosmo = (str) ->
escapes = {}
import P, R, Cmt, Cs, V from require "lpeg"
counter = 0
cosmo = parse_cosmo! / (tpl) ->
counter += 1
key = "#{dollar_temp}_#{counter}"
escapes[key] = tpl
key
patt = Cs (cosmo + P(1))^0 * P(-1)
str = patt\match(str) or str, escapes
str, escapes
unescape_cosmo = (str, escapes) ->
import P, R, Cmt, Cs from require "lpeg"
escape_patt = P(dollar_temp) * P("_") * R("09")^1 / (key) ->
escapes[key] or error "bad key for unescape_cosmo"
patt = Cs (escape_patt + P(1))^0 * P(-1)
assert patt\match(str)
needs_shell_escape = (str) -> not not str\match "[^%w_-]"
shell_escape = (str) -> str\gsub "'", "''"
_prepare_command = (cmd, ...) ->
args = for x in *{...}
if needs_shell_escape x then "'#{shell_escape x}'" else x
args = table.concat args, " "
"#{cmd} #{args}"
write_exec = (cmd, content) ->
fname = os.tmpname!
f = assert io.popen _prepare_command(cmd, fname), "w"
with f\write content
f\close!
fname
class PandocRenderer extends require "sitegen.renderers.html"
@escape_cosmo: escape_cosmo
@unescape_cosmo: unescape_cosmo
@parse_cosmo: parse_cosmo
source_ext: "md"
ext: "html"
cmd: "pandoc --mathjax --lua-filter pygments.lua >"
pandoc: (content) => Path.read_file write_exec @@cmd, content
render: (page, md_source) =>
md_source = page\pipe "renderer.markdown.pre_render", md_source
md_source, escapes = escape_cosmo md_source
html_source = assert @pandoc md_source
html_source = unescape_cosmo html_source, escapes
super page, html_source