-- 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, } }