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 ```
105 lines
2.6 KiB
Plaintext
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
|