so that we can put 2 selectors next to each other and still be able to tell where one ends and the other one begins
107 lines
2.7 KiB
Plaintext
107 lines
2.7 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
|
|
|
|
-- config command like this in site.moon:
|
|
-- require("renderers.markdown").cmd = "pandoc --mathjax >"
|
|
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
|