69 lines
2.0 KiB
Lua
69 lines
2.0 KiB
Lua
-- IMPORTANT: for distribution the first 10 lines are changed to:
|
|
-- local fennel = mod
|
|
-- Initial setup for development:
|
|
-- Enables Fennel for Lisp-Lua embeded compatibility
|
|
-- Cfr. https://fennel-lang.org
|
|
local src_root = pandoc.path.directory(PANDOC_SCRIPT_FILE)
|
|
local fennel_lua = pandoc.path.join({src_root, "../opt/fennel.lua"})
|
|
package.path = package.path .. ";" .. fennel_lua
|
|
local fennel = require("fennel")
|
|
-- IMPORTANT: code for distribution starts after this line.
|
|
--[[
|
|
-- Lua LPeg shortcuts
|
|
local P, S, R, Cf, Cc, Ct, V, Cs, Cg, Cb, B, C, Cmt =
|
|
lpeg.P, lpeg.S, lpeg.R, lpeg.Cf, lpeg.Cc, lpeg.Ct, lpeg.V,
|
|
lpeg.Cs, lpeg.Cg, lpeg.Cb, lpeg.B, lpeg.C, lpeg.Cmt
|
|
|
|
-- Lexical elements
|
|
local space = S(" \t\r\n")
|
|
local lbracket = P"("
|
|
local rbracket = P")"
|
|
local word = (1 - (space + lbracket + rbracket))
|
|
|
|
-- Grammar for Pandoc parser that converts:
|
|
-- Lisp expression => pandoc.Plain
|
|
-- Lisp list => pandoc.Span
|
|
-- Lisp atom => pandoc.Str
|
|
G = P{
|
|
"Doc";
|
|
Doc = space^0 * Ct(V"SExpr"^0) * space^0 / pandoc.Pandoc;
|
|
SExpr = (V"List" + V"Atom");
|
|
List = lbracket * V"SExpr"^0 * rbracket / embed;
|
|
Atom = space + V"Word";
|
|
Word = word^1 / pandoc.Str;
|
|
}
|
|
]]--
|
|
|
|
-- Evals Lisp code
|
|
-- @param code string: code to evaluate
|
|
-- @return table: evaluation result as {bool, string, string, string}
|
|
local function eval(code)
|
|
is_passed, out = pcall (
|
|
function () return fennel.eval(code) end,
|
|
function (e) return e end
|
|
)
|
|
lua = ""
|
|
out = tostring(out)
|
|
preview = out:gsub("\n.*", "")
|
|
if is_passed then
|
|
lua = fennel.compileString(code)
|
|
end
|
|
return {is_passed = is_passed, preview = preview, out = out, lua = lua}
|
|
end
|
|
|
|
return {
|
|
{
|
|
CodeBlock = function (block)
|
|
if block.classes:includes("eval") then
|
|
local raw = block.text
|
|
print("⚙️ ", raw)
|
|
local res = eval(raw)
|
|
print("", res["is_passed"], "→", res["preview"])
|
|
if block.classes:includes("replace") then
|
|
return pandoc.CodeBlock(res["out"], {code=raw})
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
}
|