118 lines
4.3 KiB
Lua
118 lines
4.3 KiB
Lua
local lfs = require "lfs"
|
|
local cmark = require "cmark"
|
|
|
|
cg.addPath("src", ".")
|
|
cg.addPath("resources", ".")
|
|
|
|
cg.addPath("hx/out", ".")
|
|
|
|
cg.doTemplateFile "lib.cgt"
|
|
|
|
cg.opt.doctype = "<!DOCTYPE html>"
|
|
|
|
cg.opt.renderMarkdown = function(src, no_header_links)
|
|
local doc = cmark.parse_document(src, string.len(src), cmark.OPT_UNSAFE)
|
|
|
|
for cur, entering, node_type in cmark.walk(doc) do
|
|
if entering then
|
|
if node_type == cmark.NODE_CODE_BLOCK then
|
|
-- Syntax highlighting with Bat and AHA
|
|
local lang = cmark.node_get_fence_info(cur)
|
|
local tmpfp = os.tmpname()
|
|
local proc = #lang > 0
|
|
and io.popen(
|
|
"bat --color always --style plain --language " .. lang .. " | aha --no-header >" .. tmpfp,
|
|
"w"
|
|
)
|
|
or io.popen("aha --no-header >" .. tmpfp, "w")
|
|
proc:write(cmark.node_get_literal(cur))
|
|
proc:close()
|
|
|
|
local tmpf = io.open(tmpfp, "r")
|
|
local new = cmark.node_new(cmark.NODE_HTML_BLOCK)
|
|
cmark.node_set_literal(new, [[<pre class="codeblock"><code>]] .. tmpf:read "*a" .. [[</code></pre>]])
|
|
cmark.node_replace(cur, new)
|
|
tmpf:close()
|
|
os.remove(tmpfp)
|
|
elseif node_type == cmark.NODE_LINK then
|
|
-- This basically reimplements links in order to make them open in a new tab.
|
|
|
|
-- Opening A
|
|
local start = cmark.node_new(cmark.NODE_HTML_INLINE)
|
|
cmark.node_set_literal(start, [[<a target="_blank" href="]] .. cmark.node_get_url(cur) .. [[">]])
|
|
cmark.node_insert_before(cur, start)
|
|
|
|
-- Content of link node
|
|
-- Spins in one loop for some reason
|
|
local children = {}
|
|
local child = cmark.node_first_child(cur)
|
|
while child do
|
|
table.insert(children, child)
|
|
child = cmark.node_next(child)
|
|
end
|
|
|
|
for _, c in ipairs(children) do
|
|
cmark.node_insert_before(cur, c)
|
|
end
|
|
|
|
-- Closing A
|
|
local close = cmark.node_new(cmark.NODE_HTML_INLINE)
|
|
cmark.node_set_literal(close, [[</a>]])
|
|
cmark.node_insert_before(cur, close)
|
|
|
|
-- Remove original
|
|
cmark.node_unlink(cur)
|
|
elseif not no_header_links and node_type == cmark.NODE_HEADING then
|
|
local level = cmark.node_get_heading_level(cur)
|
|
local id = ""
|
|
for n, e, _ in cmark.walk(cur) do
|
|
if e then
|
|
id = id .. (cmark.node_get_literal(n) or "")
|
|
end
|
|
end
|
|
|
|
id = id:lower():gsub(" ", "-"):gsub("['!.?#@,%(%)%[%]{}%%]+", "")
|
|
|
|
local pref = cmark.node_new(cmark.NODE_HTML_BLOCK)
|
|
cmark.node_set_literal(
|
|
pref,
|
|
string.format([[<a href="#%s" class="headerlink"><h%d id="%s">]], id, level, id)
|
|
)
|
|
cmark.node_insert_before(cur, pref)
|
|
|
|
local text = cmark.node_new(cmark.NODE_CUSTOM_BLOCK)
|
|
|
|
-- Content of header node
|
|
-- Spins in one loop for some reason
|
|
local children = {}
|
|
local child = cmark.node_first_child(cur)
|
|
while child do
|
|
table.insert(children, child)
|
|
child = cmark.node_next(child)
|
|
end
|
|
|
|
for _, c in ipairs(children) do
|
|
cmark.node_append_child(text, c)
|
|
end
|
|
|
|
cmark.node_insert_before(cur, text)
|
|
|
|
local suff = cmark.node_new(cmark.NODE_HTML_BLOCK)
|
|
cmark.node_set_literal(suff, string.format([[</h%d></a>]], level))
|
|
cmark.node_insert_before(cur, suff)
|
|
|
|
cmark.node_unlink(cur)
|
|
end
|
|
end
|
|
end
|
|
|
|
return cmark.render_html(doc, cmark.OPT_UNSAFE)
|
|
end
|
|
|
|
cg.opt.articles = {}
|
|
for fpath in lfs.dir "meta" do
|
|
if fpath ~= "." and fpath ~= ".." then
|
|
local meta = loadfile("meta/" .. fpath)()
|
|
table.insert(cg.opt.articles, meta)
|
|
end
|
|
end
|