From 5b9d776dfb2db57c89a2324c44cdf5431d8e7472 Mon Sep 17 00:00:00 2001 From: perro Date: Sat, 1 Jul 2023 09:56:06 -0700 Subject: [PATCH] Fixed workflow with checks; added (incomplete) call function --- dist/lin.bundle.lua | 225 ++++++++++++++++------------- dist/lin.min.lua | 225 ++++++++++++++++------------- scripts/make_dist.lua | 2 +- src/literate.lua | 227 ++++++++++++++++-------------- tests/asts/pass.lit.infos.md.json | 2 +- tests/fail.lit.errors.md | 2 +- tests/pass.lit.infos.md | 30 +++- 7 files changed, 399 insertions(+), 314 deletions(-) diff --git a/dist/lin.bundle.lua b/dist/lin.bundle.lua index 15e3887..e65cd90 100644 --- a/dist/lin.bundle.lua +++ b/dist/lin.bundle.lua @@ -6602,18 +6602,22 @@ dog.import() ---------------------------------- LITERATE ---------------------------------- --- Variable for all literate stuff +-- Stores all literate stuff local lit = {} --- Status indicator +-- Indicates status lit.status = true --- Grammars +-- Stores literate functions +lit.fns = {} + +-- Returns specific grammar function lit.g(name) - -- Variable for grammars collection + -- Stores all grammars local grammars = {} + -- 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 @@ -6627,11 +6631,11 @@ function lit.g(name) local yamlheader = space^0 * P"---" * space^0 * newline local yamlfooter = space^0 * P"..." * space^0 * newline^-1 local yamlbody = -yamlfooter * any^0 * newline - local id = R("az", "AZ") * R("az", "AZ", "09")^0 - local ref = -B"\\" * P"#" * C(id) + local label = R("az", "AZ") * R("az", "AZ", "09", "__")^0 + local ref = -B"\\" * P"#" * C(label) local notref = (1 - ref)^0 - -- Declaration grammar + -- Function declaration grammar grammars["declaration"] = P { "Declaration"; Declaration = Ct(V"YAML" * V"Code", "name"); @@ -6639,7 +6643,7 @@ function lit.g(name) Code = C((any + newline)^0); } - -- References grammar + -- Argument references grammar grammars["references"] = notref * P { "References"; References = Ct((ref * notref)^0); @@ -6709,7 +6713,7 @@ ERROR: ]]).meta) local levelname, level, lang = "INFO", 0, os.lang() for mtype, msgs in pairs(msg) do - if msgs[key] ~= nil then + if msgs[key] then key = (msgs[key][lang] ~= nil and msgs[key][lang] or msgs[key]["en"]) for i, str in ipairs({...}) do key = key:gsub("#" .. i, str) @@ -6728,35 +6732,17 @@ ERROR: end end --- Examinates (parses and evaluates) document +-- Parses and evaluates literate functions in document function lit.exam(doc) - -- Evaluates code declaration - -- Evals Lisp code - --[[ - local function eval(code) - local is_passed, out = pcall ( - function () return fennel.eval(code) end, - function (e) return e end - ) - local lua = "" - local out = tostring(out) - local 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 - ]]-- + -- Extracts function declarations + local function extract(codeblock) - -- Parses code declaration - local function parse(codeblock) + -- Checks function declarations + local function check(match) - -- Checks code declarations - local function check(parsed) - - -- Indicates if checks passes - local ispass = true + -- Stores valid declaration + local declaration = {} -- Valid metadata structure local metastruct = { @@ -6783,6 +6769,9 @@ function lit.exam(doc) } -- Language commands + -- Eachs command is a table of table; + -- First table indicates one or more internal or external evaluations + -- Second table indicates one or more commands to try local langcmds = { ["lua"] = {["int_eval"] = { "CMD1", "CMD2", } }, ["fennel"] = {["int_eval"] = { "CMD1", "CMD2", } }, @@ -6793,36 +6782,39 @@ function lit.exam(doc) ["graphviz"] = {["ext_eval"] = { "CMD1", "CMD2", } }, } - -- Prints error and does not pass the check + -- Prints error + -- Since error messages debuglevel are "ERROR", lit.status turns false + -- Flush the declaration to avoid storage in lit.fns local function putserr(...) lit.puts(...) - ispass = false + declaration = {} end - -- Adds 'eval' key in meta - -- This keys indicates what to eval - local function addeval(meta) - meta["eval"] = {} - if ispass then - if meta["lang"] and meta["cmd"] then - lit.puts("ignore_lang", meta["cmd"], meta["lang"]) - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - elseif not(meta["lang"]) and not(meta["cmd"])then - meta["lang"] = "lua" - meta["eval"] = langcmds["lua"] - elseif meta["lang"] and not(meta["cmd"]) then - meta["eval"] = langcmds[meta["lang"]] - elseif not(meta["lang"]) and meta["cmd"] then - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - end + -- Adds 'eval' key in declaration + -- This key indicates what to eval + local function addeval() + declaration["eval"] = {} + -- If lang and cmd are present, ignores lang and use cmd as eval + if declaration["lang"] and declaration["cmd"] then + lit.puts("ignore_lang", declaration["cmd"], declaration["lang"]) + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } + -- If neither lang or cmd are presents, defaults lang and eval to lua + elseif not(declaration["lang"]) and not(declaration["cmd"])then + declaration["lang"] = "lua" + declaration["eval"] = langcmds["lua"] + -- If only lang present, eval is lang + elseif declaration["lang"] and not(declaration["cmd"]) then + declaration["eval"] = langcmds[declaration["lang"]] + -- If only cmd present, eval is cmd + elseif not(declaration["lang"]) and declaration["cmd"] then + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } end - return meta end - -- Checks for valid command - local function checkcmd(meta) - if meta["cmd"] then - local cmd = meta["cmd"]:split()[1] + -- Checks for valid command for Unix systems + local function checkcmd() + if declaration["cmd"] then + local cmd = declaration["cmd"]:split()[1] if os.isunix() then local status = io.try("type", cmd) if not(status) then @@ -6834,9 +6826,9 @@ function lit.exam(doc) end end - -- Checks for extra and unwanted metadata - local function checkextra(meta) - for key, _ in pairs(meta) do + -- Checks for extra, unwanted and wrong metadata + local function checkextra() + for key, _ in pairs(declaration) do local missing1 = metastruct["mandatory"][key] == nil local missing2 = metastruct["optional"][key] == nil if missing1 and missing2 then @@ -6846,11 +6838,11 @@ function lit.exam(doc) end -- Checks for valid metadata - local function checkmeta(metadata, kind) + local function checkmeta(kind) -- Checks for valid metadata type - local function checktype(type1, meta, key) - local val = meta[key] + local function checktype(type1, key) + local val = declaration[key] local type2 = type(val) if type1 ~= type2 then if type1 == "path" then @@ -6864,8 +6856,8 @@ function lit.exam(doc) end -- Checks for valid metadata pattern - local function checkpattern(table, meta, key) - local val = tostring(meta[key]) + local function checkpattern(table, key) + local val = tostring(declaration[key]) local err = key for _, pattern in pairs(table) do if val:match("^" .. pattern .. "$") then @@ -6879,12 +6871,12 @@ function lit.exam(doc) end for key, val in pairs(metastruct[kind]) do - if metadata[key] == nil and kind == "mandatory" then + if declaration[key] == nil and kind == "mandatory" then putserr("no_key", key) - elseif metadata[key] and type(val) == "table" then - checkpattern(val, metadata, key) - elseif metadata[key] then - checktype(val, metadata, key) + elseif declaration[key] and type(val) == "table" then + checkpattern(val, key) + elseif declaration[key] then + checktype(val, key) end end end @@ -6892,55 +6884,85 @@ function lit.exam(doc) -- Parses metadata local function parsemeta(yaml) local isok, res = pcall(pandoc.read, yaml) - local meta = {} if isok and not(pandoc.utils.stringify(res.meta):isempty()) then - meta = pandoc.metatotable(res.meta) - checkmeta(meta, "mandatory") - checkmeta(meta, "optional") - checkextra(meta) - checkcmd(meta) + declaration = pandoc.metatotable(res.meta) + checkmeta("mandatory") + checkmeta("optional") + checkextra() + checkcmd() + if next(declaration) then addeval() end elseif isok and pandoc.utils.stringify(res.meta):isempty() then putserr("meta_empty") else putserr("meta_invalid") end - return addeval(meta) end -- TODO - -- NOTE: if not valid code, return meta["eval"] = {} - local function checkcode(code, meta) - local references = lpeg.match(lit.g("references"), code) + -- Parses code + local function parsecode(rawcode) + local code = "" + local references = lpeg.match(lit.g("references"), rawcode) if references then for _, ref in ipairs(references) do print("reference:", ref) end end - return "TODO" + declaration["code"] = code end - lit.puts("checking", table.concat(parsed, ""):indent()) - local meta = parsemeta(parsed[1]) - -- TODO - -- Add each meta to a variable - -- Remove meta if doesn't pass checkcode - meta["code"] = checkcode(parsed[2], meta) - return meta + if match then + lit.puts("checking", table.concat(match, ""):indent()) + parsemeta(match[1]) + if next(declaration) then parsecode(match[2]) end + end + return declaration end - local parsed = lpeg.match(lit.g("declaration"), codeblock.text) - local checked = (parsed ~= nil and check(parsed) or parsed) - -- TODO: - -- evaluated = eval(checked) - -- TODO: write evaluated and do overrides with warns - -- return evaluated + local parsed = check(lpeg.match(lit.g("declaration"), codeblock.text)) + if next(parsed) then + -- TODO: + -- Eval parsed lit.fns and modify code block accordingly + lit.fns[parsed["id"]] = parsed + end return codeblock end - -- TODO - -- Evals and inserts inline code - local function insert(code) - return code + -- Calls literate functions + local function call(el) + + -- TODO + -- Calls literate functions in code inlines + local function codecall(code) + return pandoc.Str("EVAL: " .. pandoc.utils.stringify(code)) + end + + local function metacall(meta) + local function inlinescall(inlines) + return inlines:walk { + Code = function(code) return codecall(code) end + } + end + + for key, val in pairs(meta) do + if pandoc.utils.type(val) == "Inlines" then + meta[key] = inlinescall(val) + elseif pandoc.utils.type(val) == "List" then + for i, item in ipairs(val) do + if pandoc.utils.type(item) == "Inlines" then + meta[key][i] = inlinescall(item) + end + end + end + end + return meta + end + + if pandoc.utils.type(el) == "Meta" then + return metacall(el) + else + return codecall(el) + end end -- Asserts literate status @@ -6951,9 +6973,10 @@ function lit.exam(doc) end end - return doc:walk { CodeBlock = function(block) return parse(block) end } - :walk { Code = function(inline) return insert(inline) end } - :walk { Pandoc = function(_) assert() end } + doc = doc:walk { CodeBlock = function(block) return extract(block) end } + doc = doc:walk { Meta = function(meta) return call(meta) end } + doc = doc:walk { Code = function(code) return call(code) end } + return doc:walk { Pandoc = function(_) assert() end } end ------------------------------------ PANDOC ----------------------------------- diff --git a/dist/lin.min.lua b/dist/lin.min.lua index 73d33c0..4ddbbd7 100644 --- a/dist/lin.min.lua +++ b/dist/lin.min.lua @@ -14,18 +14,22 @@ dog.import() ---------------------------------- LITERATE ---------------------------------- --- Variable for all literate stuff +-- Stores all literate stuff local lit = {} --- Status indicator +-- Indicates status lit.status = true --- Grammars +-- Stores literate functions +lit.fns = {} + +-- Returns specific grammar function lit.g(name) - -- Variable for grammars collection + -- Stores all grammars local grammars = {} + -- 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 @@ -39,11 +43,11 @@ function lit.g(name) local yamlheader = space^0 * P"---" * space^0 * newline local yamlfooter = space^0 * P"..." * space^0 * newline^-1 local yamlbody = -yamlfooter * any^0 * newline - local id = R("az", "AZ") * R("az", "AZ", "09")^0 - local ref = -B"\\" * P"#" * C(id) + local label = R("az", "AZ") * R("az", "AZ", "09", "__")^0 + local ref = -B"\\" * P"#" * C(label) local notref = (1 - ref)^0 - -- Declaration grammar + -- Function declaration grammar grammars["declaration"] = P { "Declaration"; Declaration = Ct(V"YAML" * V"Code", "name"); @@ -51,7 +55,7 @@ function lit.g(name) Code = C((any + newline)^0); } - -- References grammar + -- Argument references grammar grammars["references"] = notref * P { "References"; References = Ct((ref * notref)^0); @@ -121,7 +125,7 @@ ERROR: ]]).meta) local levelname, level, lang = "INFO", 0, os.lang() for mtype, msgs in pairs(msg) do - if msgs[key] ~= nil then + if msgs[key] then key = (msgs[key][lang] ~= nil and msgs[key][lang] or msgs[key]["en"]) for i, str in ipairs({...}) do key = key:gsub("#" .. i, str) @@ -140,35 +144,17 @@ ERROR: end end --- Examinates (parses and evaluates) document +-- Parses and evaluates literate functions in document function lit.exam(doc) - -- Evaluates code declaration - -- Evals Lisp code - --[[ - local function eval(code) - local is_passed, out = pcall ( - function () return fennel.eval(code) end, - function (e) return e end - ) - local lua = "" - local out = tostring(out) - local 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 - ]]-- + -- Extracts function declarations + local function extract(codeblock) - -- Parses code declaration - local function parse(codeblock) + -- Checks function declarations + local function check(match) - -- Checks code declarations - local function check(parsed) - - -- Indicates if checks passes - local ispass = true + -- Stores valid declaration + local declaration = {} -- Valid metadata structure local metastruct = { @@ -195,6 +181,9 @@ function lit.exam(doc) } -- Language commands + -- Eachs command is a table of table; + -- First table indicates one or more internal or external evaluations + -- Second table indicates one or more commands to try local langcmds = { ["lua"] = {["int_eval"] = { "CMD1", "CMD2", } }, ["fennel"] = {["int_eval"] = { "CMD1", "CMD2", } }, @@ -205,36 +194,39 @@ function lit.exam(doc) ["graphviz"] = {["ext_eval"] = { "CMD1", "CMD2", } }, } - -- Prints error and does not pass the check + -- Prints error + -- Since error messages debuglevel are "ERROR", lit.status turns false + -- Flush the declaration to avoid storage in lit.fns local function putserr(...) lit.puts(...) - ispass = false + declaration = {} end - -- Adds 'eval' key in meta - -- This keys indicates what to eval - local function addeval(meta) - meta["eval"] = {} - if ispass then - if meta["lang"] and meta["cmd"] then - lit.puts("ignore_lang", meta["cmd"], meta["lang"]) - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - elseif not(meta["lang"]) and not(meta["cmd"])then - meta["lang"] = "lua" - meta["eval"] = langcmds["lua"] - elseif meta["lang"] and not(meta["cmd"]) then - meta["eval"] = langcmds[meta["lang"]] - elseif not(meta["lang"]) and meta["cmd"] then - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - end + -- Adds 'eval' key in declaration + -- This key indicates what to eval + local function addeval() + declaration["eval"] = {} + -- If lang and cmd are present, ignores lang and use cmd as eval + if declaration["lang"] and declaration["cmd"] then + lit.puts("ignore_lang", declaration["cmd"], declaration["lang"]) + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } + -- If neither lang or cmd are presents, defaults lang and eval to lua + elseif not(declaration["lang"]) and not(declaration["cmd"])then + declaration["lang"] = "lua" + declaration["eval"] = langcmds["lua"] + -- If only lang present, eval is lang + elseif declaration["lang"] and not(declaration["cmd"]) then + declaration["eval"] = langcmds[declaration["lang"]] + -- If only cmd present, eval is cmd + elseif not(declaration["lang"]) and declaration["cmd"] then + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } end - return meta end - -- Checks for valid command - local function checkcmd(meta) - if meta["cmd"] then - local cmd = meta["cmd"]:split()[1] + -- Checks for valid command for Unix systems + local function checkcmd() + if declaration["cmd"] then + local cmd = declaration["cmd"]:split()[1] if os.isunix() then local status = io.try("type", cmd) if not(status) then @@ -246,9 +238,9 @@ function lit.exam(doc) end end - -- Checks for extra and unwanted metadata - local function checkextra(meta) - for key, _ in pairs(meta) do + -- Checks for extra, unwanted and wrong metadata + local function checkextra() + for key, _ in pairs(declaration) do local missing1 = metastruct["mandatory"][key] == nil local missing2 = metastruct["optional"][key] == nil if missing1 and missing2 then @@ -258,11 +250,11 @@ function lit.exam(doc) end -- Checks for valid metadata - local function checkmeta(metadata, kind) + local function checkmeta(kind) -- Checks for valid metadata type - local function checktype(type1, meta, key) - local val = meta[key] + local function checktype(type1, key) + local val = declaration[key] local type2 = type(val) if type1 ~= type2 then if type1 == "path" then @@ -276,8 +268,8 @@ function lit.exam(doc) end -- Checks for valid metadata pattern - local function checkpattern(table, meta, key) - local val = tostring(meta[key]) + local function checkpattern(table, key) + local val = tostring(declaration[key]) local err = key for _, pattern in pairs(table) do if val:match("^" .. pattern .. "$") then @@ -291,12 +283,12 @@ function lit.exam(doc) end for key, val in pairs(metastruct[kind]) do - if metadata[key] == nil and kind == "mandatory" then + if declaration[key] == nil and kind == "mandatory" then putserr("no_key", key) - elseif metadata[key] and type(val) == "table" then - checkpattern(val, metadata, key) - elseif metadata[key] then - checktype(val, metadata, key) + elseif declaration[key] and type(val) == "table" then + checkpattern(val, key) + elseif declaration[key] then + checktype(val, key) end end end @@ -304,55 +296,85 @@ function lit.exam(doc) -- Parses metadata local function parsemeta(yaml) local isok, res = pcall(pandoc.read, yaml) - local meta = {} if isok and not(pandoc.utils.stringify(res.meta):isempty()) then - meta = pandoc.metatotable(res.meta) - checkmeta(meta, "mandatory") - checkmeta(meta, "optional") - checkextra(meta) - checkcmd(meta) + declaration = pandoc.metatotable(res.meta) + checkmeta("mandatory") + checkmeta("optional") + checkextra() + checkcmd() + if next(declaration) then addeval() end elseif isok and pandoc.utils.stringify(res.meta):isempty() then putserr("meta_empty") else putserr("meta_invalid") end - return addeval(meta) end -- TODO - -- NOTE: if not valid code, return meta["eval"] = {} - local function checkcode(code, meta) - local references = lpeg.match(lit.g("references"), code) + -- Parses code + local function parsecode(rawcode) + local code = "" + local references = lpeg.match(lit.g("references"), rawcode) if references then for _, ref in ipairs(references) do print("reference:", ref) end end - return "TODO" + declaration["code"] = code end - lit.puts("checking", table.concat(parsed, ""):indent()) - local meta = parsemeta(parsed[1]) - -- TODO - -- Add each meta to a variable - -- Remove meta if doesn't pass checkcode - meta["code"] = checkcode(parsed[2], meta) - return meta + if match then + lit.puts("checking", table.concat(match, ""):indent()) + parsemeta(match[1]) + if next(declaration) then parsecode(match[2]) end + end + return declaration end - local parsed = lpeg.match(lit.g("declaration"), codeblock.text) - local checked = (parsed ~= nil and check(parsed) or parsed) - -- TODO: - -- evaluated = eval(checked) - -- TODO: write evaluated and do overrides with warns - -- return evaluated + local parsed = check(lpeg.match(lit.g("declaration"), codeblock.text)) + if next(parsed) then + -- TODO: + -- Eval parsed lit.fns and modify code block accordingly + lit.fns[parsed["id"]] = parsed + end return codeblock end - -- TODO - -- Evals and inserts inline code - local function insert(code) - return code + -- Calls literate functions + local function call(el) + + -- TODO + -- Calls literate functions in code inlines + local function codecall(code) + return pandoc.Str("EVAL: " .. pandoc.utils.stringify(code)) + end + + local function metacall(meta) + local function inlinescall(inlines) + return inlines:walk { + Code = function(code) return codecall(code) end + } + end + + for key, val in pairs(meta) do + if pandoc.utils.type(val) == "Inlines" then + meta[key] = inlinescall(val) + elseif pandoc.utils.type(val) == "List" then + for i, item in ipairs(val) do + if pandoc.utils.type(item) == "Inlines" then + meta[key][i] = inlinescall(item) + end + end + end + end + return meta + end + + if pandoc.utils.type(el) == "Meta" then + return metacall(el) + else + return codecall(el) + end end -- Asserts literate status @@ -363,9 +385,10 @@ function lit.exam(doc) end end - return doc:walk { CodeBlock = function(block) return parse(block) end } - :walk { Code = function(inline) return insert(inline) end } - :walk { Pandoc = function(_) assert() end } + doc = doc:walk { CodeBlock = function(block) return extract(block) end } + doc = doc:walk { Meta = function(meta) return call(meta) end } + doc = doc:walk { Code = function(code) return call(code) end } + return doc:walk { Pandoc = function(_) assert() end } end ------------------------------------ PANDOC ----------------------------------- diff --git a/scripts/make_dist.lua b/scripts/make_dist.lua index fb25553..2e5a236 100644 --- a/scripts/make_dist.lua +++ b/scripts/make_dist.lua @@ -25,7 +25,7 @@ local function make_dist(name, bundle) local fnl = chomp(optpath .. "fennel.lua"):gsub("\nreturn mod\n", "\nlocal fnl = mod\n") local dog = chomp(optpath .. "dog.lua"):gsub("\nreturn dog\n", "") local nat = chomp("src/natural.lua"):gsub("\nreturn nat\n", "") - local lit = chomp("src/literate.lua"):gsub("#locale%(%)", ("src/locale.yaml"):readtext()) + local lit = chomp("src/literate.lua"):gsub("`locale%(%)`", ("src/locale.yaml"):readtext()) local pan = chomp("src/pandoc.lua") local license = string.strip([[ Computable Pandoc: diff --git a/src/literate.lua b/src/literate.lua index d1e5976..65bbe19 100644 --- a/src/literate.lua +++ b/src/literate.lua @@ -1,17 +1,21 @@ ---------------------------------- LITERATE ---------------------------------- --- Variable for all literate stuff +-- Stores all literate stuff local lit = {} --- Status indicator +-- Indicates status lit.status = true --- Grammars +-- Stores literate functions +lit.fns = {} + +-- Returns specific grammar function lit.g(name) - -- Variable for grammars collection + -- Stores all grammars local grammars = {} + -- 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 @@ -25,11 +29,11 @@ function lit.g(name) local yamlheader = space^0 * P"---" * space^0 * newline local yamlfooter = space^0 * P"..." * space^0 * newline^-1 local yamlbody = -yamlfooter * any^0 * newline - local id = R("az", "AZ") * R("az", "AZ", "09")^0 - local ref = -B"\\" * P"#" * C(id) + local label = R("az", "AZ") * R("az", "AZ", "09", "__")^0 + local ref = -B"\\" * P"#" * C(label) local notref = (1 - ref)^0 - -- Declaration grammar + -- Function declaration grammar grammars["declaration"] = P { "Declaration"; Declaration = Ct(V"YAML" * V"Code", "name"); @@ -37,7 +41,7 @@ function lit.g(name) Code = C((any + newline)^0); } - -- References grammar + -- Argument references grammar grammars["references"] = notref * P { "References"; References = Ct((ref * notref)^0); @@ -63,10 +67,10 @@ function lit.puts(yaml_key, ...) -- Gets located message local function getmsg(key, ...) - local msg = pandoc.metatotable(pandoc.read([[#locale()]]).meta) + local msg = pandoc.metatotable(pandoc.read([[`locale()`]]).meta) local levelname, level, lang = "INFO", 0, os.lang() for mtype, msgs in pairs(msg) do - if msgs[key] ~= nil then + if msgs[key] then key = (msgs[key][lang] ~= nil and msgs[key][lang] or msgs[key]["en"]) for i, str in ipairs({...}) do key = key:gsub("#" .. i, str) @@ -85,35 +89,17 @@ function lit.puts(yaml_key, ...) end end --- Examinates (parses and evaluates) document +-- Parses and evaluates literate functions in document function lit.exam(doc) - -- Evaluates code declaration - -- Evals Lisp code - --[[ - local function eval(code) - local is_passed, out = pcall ( - function () return fennel.eval(code) end, - function (e) return e end - ) - local lua = "" - local out = tostring(out) - local 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 - ]]-- + -- Extracts function declarations + local function extract(codeblock) - -- Parses code declaration - local function parse(codeblock) + -- Checks function declarations + local function check(match) - -- Checks code declarations - local function check(parsed) - - -- Indicates if checks passes - local ispass = true + -- Stores valid declaration + local declaration = {} -- Valid metadata structure local metastruct = { @@ -140,6 +126,9 @@ function lit.exam(doc) } -- Language commands + -- Eachs command is a table of table; + -- First table indicates one or more internal or external evaluations + -- Second table indicates one or more commands to try local langcmds = { ["lua"] = {["int_eval"] = { "CMD1", "CMD2", } }, ["fennel"] = {["int_eval"] = { "CMD1", "CMD2", } }, @@ -150,36 +139,39 @@ function lit.exam(doc) ["graphviz"] = {["ext_eval"] = { "CMD1", "CMD2", } }, } - -- Prints error and does not pass the check + -- Prints error + -- Since error messages debuglevel are "ERROR", lit.status turns false + -- Flush the declaration to avoid storage in lit.fns local function putserr(...) lit.puts(...) - ispass = false + declaration = {} end - -- Adds 'eval' key in meta - -- This keys indicates what to eval - local function addeval(meta) - meta["eval"] = {} - if ispass then - if meta["lang"] and meta["cmd"] then - lit.puts("ignore_lang", meta["cmd"], meta["lang"]) - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - elseif not(meta["lang"]) and not(meta["cmd"])then - meta["lang"] = "lua" - meta["eval"] = langcmds["lua"] - elseif meta["lang"] and not(meta["cmd"]) then - meta["eval"] = langcmds[meta["lang"]] - elseif not(meta["lang"]) and meta["cmd"] then - meta["eval"] = {["ext_eval"] = { meta["cmd"] } } - end + -- Adds 'eval' key in declaration + -- This key indicates what to eval + local function addeval() + declaration["eval"] = {} + -- If lang and cmd are present, ignores lang and use cmd as eval + if declaration["lang"] and declaration["cmd"] then + lit.puts("ignore_lang", declaration["cmd"], declaration["lang"]) + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } + -- If neither lang or cmd are presents, defaults lang and eval to lua + elseif not(declaration["lang"]) and not(declaration["cmd"])then + declaration["lang"] = "lua" + declaration["eval"] = langcmds["lua"] + -- If only lang present, eval is lang + elseif declaration["lang"] and not(declaration["cmd"]) then + declaration["eval"] = langcmds[declaration["lang"]] + -- If only cmd present, eval is cmd + elseif not(declaration["lang"]) and declaration["cmd"] then + declaration["eval"] = {["ext_eval"] = { declaration["cmd"] } } end - return meta end - -- Checks for valid command - local function checkcmd(meta) - if meta["cmd"] then - local cmd = meta["cmd"]:split()[1] + -- Checks for valid command for Unix systems + local function checkcmd() + if declaration["cmd"] then + local cmd = declaration["cmd"]:split()[1] if os.isunix() then local status = io.try("type", cmd) if not(status) then @@ -191,9 +183,9 @@ function lit.exam(doc) end end - -- Checks for extra and unwanted metadata - local function checkextra(meta) - for key, _ in pairs(meta) do + -- Checks for extra, unwanted and wrong metadata + local function checkextra() + for key, _ in pairs(declaration) do local missing1 = metastruct["mandatory"][key] == nil local missing2 = metastruct["optional"][key] == nil if missing1 and missing2 then @@ -203,11 +195,11 @@ function lit.exam(doc) end -- Checks for valid metadata - local function checkmeta(metadata, kind) + local function checkmeta(kind) -- Checks for valid metadata type - local function checktype(type1, meta, key) - local val = meta[key] + local function checktype(type1, key) + local val = declaration[key] local type2 = type(val) if type1 ~= type2 then if type1 == "path" then @@ -221,8 +213,8 @@ function lit.exam(doc) end -- Checks for valid metadata pattern - local function checkpattern(table, meta, key) - local val = tostring(meta[key]) + local function checkpattern(table, key) + local val = tostring(declaration[key]) local err = key for _, pattern in pairs(table) do if val:match("^" .. pattern .. "$") then @@ -236,12 +228,12 @@ function lit.exam(doc) end for key, val in pairs(metastruct[kind]) do - if metadata[key] == nil and kind == "mandatory" then + if declaration[key] == nil and kind == "mandatory" then putserr("no_key", key) - elseif metadata[key] and type(val) == "table" then - checkpattern(val, metadata, key) - elseif metadata[key] then - checktype(val, metadata, key) + elseif declaration[key] and type(val) == "table" then + checkpattern(val, key) + elseif declaration[key] then + checktype(val, key) end end end @@ -249,55 +241,85 @@ function lit.exam(doc) -- Parses metadata local function parsemeta(yaml) local isok, res = pcall(pandoc.read, yaml) - local meta = {} if isok and not(pandoc.utils.stringify(res.meta):isempty()) then - meta = pandoc.metatotable(res.meta) - checkmeta(meta, "mandatory") - checkmeta(meta, "optional") - checkextra(meta) - checkcmd(meta) + declaration = pandoc.metatotable(res.meta) + checkmeta("mandatory") + checkmeta("optional") + checkextra() + checkcmd() + if next(declaration) then addeval() end elseif isok and pandoc.utils.stringify(res.meta):isempty() then putserr("meta_empty") else putserr("meta_invalid") end - return addeval(meta) end -- TODO - -- NOTE: if not valid code, return meta["eval"] = {} - local function checkcode(code, meta) - local references = lpeg.match(lit.g("references"), code) + -- Parses code + local function parsecode(rawcode) + local code = "" + local references = lpeg.match(lit.g("references"), rawcode) if references then for _, ref in ipairs(references) do print("reference:", ref) end end - return "TODO" + declaration["code"] = code end - lit.puts("checking", table.concat(parsed, ""):indent()) - local meta = parsemeta(parsed[1]) - -- TODO - -- Add each meta to a variable - -- Remove meta if doesn't pass checkcode - meta["code"] = checkcode(parsed[2], meta) - return meta + if match then + lit.puts("checking", table.concat(match, ""):indent()) + parsemeta(match[1]) + if next(declaration) then parsecode(match[2]) end + end + return declaration end - local parsed = lpeg.match(lit.g("declaration"), codeblock.text) - local checked = (parsed ~= nil and check(parsed) or parsed) - -- TODO: - -- evaluated = eval(checked) - -- TODO: write evaluated and do overrides with warns - -- return evaluated + local parsed = check(lpeg.match(lit.g("declaration"), codeblock.text)) + if next(parsed) then + -- TODO: + -- Eval parsed lit.fns and modify code block accordingly + lit.fns[parsed["id"]] = parsed + end return codeblock end - -- TODO - -- Evals and inserts inline code - local function insert(code) - return code + -- Calls literate functions + local function call(el) + + -- TODO + -- Calls literate functions in code inlines + local function codecall(code) + return pandoc.Str("EVAL: " .. pandoc.utils.stringify(code)) + end + + local function metacall(meta) + local function inlinescall(inlines) + return inlines:walk { + Code = function(code) return codecall(code) end + } + end + + for key, val in pairs(meta) do + if pandoc.utils.type(val) == "Inlines" then + meta[key] = inlinescall(val) + elseif pandoc.utils.type(val) == "List" then + for i, item in ipairs(val) do + if pandoc.utils.type(item) == "Inlines" then + meta[key][i] = inlinescall(item) + end + end + end + end + return meta + end + + if pandoc.utils.type(el) == "Meta" then + return metacall(el) + else + return codecall(el) + end end -- Asserts literate status @@ -308,7 +330,8 @@ function lit.exam(doc) end end - return doc:walk { CodeBlock = function(block) return parse(block) end } - :walk { Code = function(inline) return insert(inline) end } - :walk { Pandoc = function(_) assert() end } + doc = doc:walk { CodeBlock = function(block) return extract(block) end } + doc = doc:walk { Meta = function(meta) return call(meta) end } + doc = doc:walk { Code = function(code) return call(code) end } + return doc:walk { Pandoc = function(_) assert() end } end diff --git a/tests/asts/pass.lit.infos.md.json b/tests/asts/pass.lit.infos.md.json index bfb020d..a653225 100644 --- a/tests/asts/pass.lit.infos.md.json +++ b/tests/asts/pass.lit.infos.md.json @@ -1 +1 @@ -{"pandoc-api-version":[1,23],"meta":{},"blocks":[{"t":"Header","c":[1,["calls-before-declarations",[],[]],[{"t":"Str","c":"Calls"},{"t":"Space"},{"t":"Str","c":"Before"},{"t":"Space"},{"t":"Str","c":"Declarations"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn1()``fn2()"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(true)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(2.0, 3.1)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n: false)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(b: 4, a: 5)"]}]}]]},{"t":"Header","c":[1,["declarations",[],[]],[{"t":"Str","c":"Declarations"}]]},{"t":"Para","c":[{"t":"Str","c":"All"},{"t":"Space"},{"t":"Str","c":"literate"},{"t":"Space"},{"t":"Str","c":"declarations"},{"t":"Space"},{"t":"Str","c":"goes"},{"t":"Space"},{"t":"Str","c":"in"},{"t":"Space"},{"t":"Str","c":"code"},{"t":"Space"},{"t":"Str","c":"blocks"},{"t":"Space"},{"t":"Str","c":"that"},{"t":"Space"},{"t":"Str","c":"should"},{"t":"Space"},{"t":"Str","c":"be"},{"t":"Space"},{"t":"Str","c":"printed"},{"t":"Space"},{"t":"Str","c":"on"},{"t":"SoftBreak"},{"t":"Code","c":[["",[],[]],"--verbose"]},{"t":"Str","c":"."}]},{"t":"Para","c":[{"t":"Str","c":"Minimal"},{"t":"Space"},{"t":"Str","c":"(Lua"},{"t":"Space"},{"t":"Str","c":"by"},{"t":"Space"},{"t":"Str","c":"default):"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn1\n...\n1 + 2 + 3"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"scape:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn2\n...\n\"\\#x\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"arg:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn3\nargs:\n n: str\n...\n#n == #n"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"lang"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"args:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn4\nlang: fennel\nargs:\n a: 1\n b: 2\n...\n(* #a #b)"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"cmd"},{"t":"Space"},{"t":"Str","c":"(ignores"},{"t":"Space"},{"t":"Str","c":"lang):"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn5\ncmd: python -E -X utf8\nargs:\n n: 2\n...\n#n + #n"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"shift:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn6\nshift: true\n...\n\"The literate block is shifted by its eval result.\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"wipe:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn7\nwipe: true\n...\n\"This evals but it is wipe from doc.\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"typed:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn4\ntyped: true\nargs:\n a: 1\n b: 2\n...\n#a * #b"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"link"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"alt:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn8\nlang: graphviz\nlink: ./graph.png\nalt: A graph. \n...\ndigraph G {\n a -> b;\n b -> c\n c -> a;\n}"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"img"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"alt:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn9\nlang: graphviz\nimg: ./graph.png\nalt: A graph. \n...\ndigraph G {\n a -> b;\n b -> c\n c -> a;\n}"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"dump"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"quote:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn10\ndump: ./dump.txt\nquote: true\n...\nThis code is saved into './dump.txt' because of 'dump'.\nThis code is not evaluated because 'quote' is true."]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn11\nargs:\n x: 2 \n...\n#fn1() * x"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function"},{"t":"Space"},{"t":"Str","c":"with"},{"t":"Space"},{"t":"Str","c":"args:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn12\nargs: \n y: 1\n z: 2\n...\n#y + #fn4(3, 4) + #z"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn13\nargs:\n a: 1\n...\n#a + #fn4(#a, #fn1())"]},{"t":"Header","c":[1,["code-blocks-that-are-not-declarations",[],[]],[{"t":"Str","c":"Code"},{"t":"Space"},{"t":"Str","c":"Blocks"},{"t":"Space"},{"t":"Str","c":"That"},{"t":"Space"},{"t":"Str","c":"Are"},{"t":"Space"},{"t":"Str","c":"Not"},{"t":"Space"},{"t":"Str","c":"Declarations"}]]},{"t":"Para","c":[{"t":"Str","c":"Always"},{"t":"Space"},{"t":"Str","c":"ignored:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\necho \"Ignore me!\""]},{"t":"Header","c":[1,["calls-and-data-types",[],[]],[{"t":"Str","c":"Calls"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"Data"},{"t":"Space"},{"t":"Str","c":"Types"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(true)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(false)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3([])"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3([0, 1])"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3({})"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3({\"k1\": 1, \"k2\": 2})"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(3)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn5(1.0)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn5(\"str\")"]}]}]]},{"t":"Header","c":[1,["messy-calls",[],[]],[{"t":"Str","c":"Messy"},{"t":"Space"},{"t":"Str","c":"Calls"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn1( )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(\"\\\"str\\\"\")"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( 4)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(5 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( 6 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( n: 7)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n: 8 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( n: 9 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n:10)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 6, b: 7)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 8 , b: 9)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 10 , b: 11)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 12 , b: 13)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 14 , b: 15 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(a:16,b:17)"]}]}]]}]} +{"pandoc-api-version":[1,23],"meta":{"bool":{"t":"MetaBool","c":true},"float":{"t":"MetaInlines","c":[{"t":"Str","c":"1.1"}]},"fn1_test":{"t":"MetaInlines","c":[{"t":"Code","c":[["",[],[]],"fn1()"]}]},"fn2_test":{"t":"MetaInlines","c":[{"t":"Str","c":"Another"},{"t":"Space"},{"t":"Str","c":"test"},{"t":"Space"},{"t":"Code","c":[["",[],[]],"fn2()"]}]},"int":{"t":"MetaInlines","c":[{"t":"Str","c":"1"}]},"list":{"t":"MetaList","c":[{"t":"MetaBool","c":true},{"t":"MetaInlines","c":[{"t":"Str","c":"1"}]},{"t":"MetaInlines","c":[{"t":"Str","c":"1.1"}]},{"t":"MetaInlines","c":[{"t":"Str","c":"foo"},{"t":"Space"},{"t":"Str","c":"all"}]},{"t":"MetaInlines","c":[{"t":"Code","c":[["",[],[]],"fn1()"]}]},{"t":"MetaInlines","c":[{"t":"Str","c":"Another"},{"t":"Space"},{"t":"Str","c":"test"},{"t":"Space"},{"t":"Code","c":[["",[],[]],"fn2()"]}]}]},"string":{"t":"MetaInlines","c":[{"t":"Str","c":"foo"},{"t":"Space"},{"t":"Str","c":"all"}]}},"blocks":[{"t":"Header","c":[1,["calls-before-declarations",[],[]],[{"t":"Str","c":"Calls"},{"t":"Space"},{"t":"Str","c":"Before"},{"t":"Space"},{"t":"Str","c":"Declarations"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn1()``fn2()"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(true)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(2.0, 3.1)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n: false)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(b: 4, a: 5)"]}]}]]},{"t":"Header","c":[1,["declarations",[],[]],[{"t":"Str","c":"Declarations"}]]},{"t":"Para","c":[{"t":"Str","c":"All"},{"t":"Space"},{"t":"Str","c":"literate"},{"t":"Space"},{"t":"Str","c":"declarations"},{"t":"Space"},{"t":"Str","c":"goes"},{"t":"Space"},{"t":"Str","c":"in"},{"t":"Space"},{"t":"Str","c":"code"},{"t":"Space"},{"t":"Str","c":"blocks"},{"t":"Space"},{"t":"Str","c":"that"},{"t":"Space"},{"t":"Str","c":"should"},{"t":"Space"},{"t":"Str","c":"be"},{"t":"Space"},{"t":"Str","c":"printed"},{"t":"Space"},{"t":"Str","c":"on"},{"t":"SoftBreak"},{"t":"Code","c":[["",[],[]],"--verbose"]},{"t":"Str","c":"."}]},{"t":"Para","c":[{"t":"Str","c":"Minimal"},{"t":"Space"},{"t":"Str","c":"(Lua"},{"t":"Space"},{"t":"Str","c":"by"},{"t":"Space"},{"t":"Str","c":"default):"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn1\n...\n1 + 2 + 3"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"scape:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn2\n...\n\"\\#x\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"arg:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn3\nargs:\n n: str\n...\n#n == #n"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"lang"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"args:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn4\nlang: fennel\nargs:\n a: 1\n b: 2\n...\n(* #a #b)"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"cmd"},{"t":"Space"},{"t":"Str","c":"(ignores"},{"t":"Space"},{"t":"Str","c":"lang):"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn5\ncmd: python -E -X utf8\nargs:\n n: 2\n...\n#n + #n"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"shift:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn6\nshift: true\n...\n\"The literate block is shifted by its eval result.\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"wipe:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn7\nwipe: true\n...\n\"This evals but it is wipe from doc.\""]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"typed:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn4\ntyped: true\nargs:\n a: 1\n b: 2\n...\n#a * #b"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"link"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"alt:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn8\nlang: graphviz\nlink: ./graph.png\nalt: A graph.\n...\ndigraph G {\n a -> b;\n b -> c\n c -> a;\n}"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"img"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"alt:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn9\nlang: graphviz\nimg: ./graph.png\nalt: A graph.\n...\ndigraph G {\n a -> b;\n b -> c\n c -> a;\n}"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"dump"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"quote:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn10\ndump: ./dump.txt\nquote: true\n...\nThis code is saved into './dump.txt' because of 'dump'.\nThis code is not evaluated because 'quote' is true."]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn11\nargs:\n x: 2\n...\n`fn1()` * x"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function"},{"t":"Space"},{"t":"Str","c":"with"},{"t":"Space"},{"t":"Str","c":"args:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn12\nargs:\n y: 1\n z: 2\n...\n#y + `fn4(3, 4)` + #z"]},{"t":"Para","c":[{"t":"Str","c":"With"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"inner"},{"t":"Space"},{"t":"Str","c":"function:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\nid: fn13\nargs:\n a: 1\n...\n#a + `fn4(#a, `fn1()`)`"]},{"t":"Header","c":[1,["code-blocks-that-are-not-declarations",[],[]],[{"t":"Str","c":"Code"},{"t":"Space"},{"t":"Str","c":"Blocks"},{"t":"Space"},{"t":"Str","c":"That"},{"t":"Space"},{"t":"Str","c":"Are"},{"t":"Space"},{"t":"Str","c":"Not"},{"t":"Space"},{"t":"Str","c":"Declarations"}]]},{"t":"Para","c":[{"t":"Str","c":"Always"},{"t":"Space"},{"t":"Str","c":"ignored:"}]},{"t":"CodeBlock","c":[["",[],[]],"---\necho \"Ignore me!\""]},{"t":"Header","c":[1,["calls-and-data-types",[],[]],[{"t":"Str","c":"Calls"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"Data"},{"t":"Space"},{"t":"Str","c":"Types"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(true)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(false)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3([])"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3([0, 1])"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3({})"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3({\"k1\": 1, \"k2\": 2})"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(3)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn5(1.0)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn5(\"str\")"]}]}]]},{"t":"Header","c":[1,["messy-calls",[],[]],[{"t":"Str","c":"Messy"},{"t":"Space"},{"t":"Str","c":"Calls"}]]},{"t":"BulletList","c":[[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn1( )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(\"\\\"str\\\"\")"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( 4)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(5 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( 6 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( n: 7)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n: 8 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3( n: 9 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn3(n:10)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 6, b: 7)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 8 , b: 9)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 10 , b: 11)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 12 , b: 13)"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4( a: 14 , b: 15 )"]}]}],[{"t":"Plain","c":[{"t":"Code","c":[["",[],[]],"fn4(a:16,b:17)"]}]}]]}]} diff --git a/tests/fail.lit.errors.md b/tests/fail.lit.errors.md index 01031f4..a85b4a9 100644 --- a/tests/fail.lit.errors.md +++ b/tests/fail.lit.errors.md @@ -109,7 +109,7 @@ Infinite loop: args: x: 1 ... - #fn1(2) * #x + `fn1(2)` * #x Invalid code: diff --git a/tests/pass.lit.infos.md b/tests/pass.lit.infos.md index 1e026b3..c9b4a85 100644 --- a/tests/pass.lit.infos.md +++ b/tests/pass.lit.infos.md @@ -1,3 +1,19 @@ +--- +bool: true +int: 1 +float: 1.1 +string: foo all +list: +- true +- 1 +- 1.1 +- foo all +- "`fn1()`" +- Another test `fn2()` +fn1_test: "`fn1()`" +fn2_test: Another test `fn2()` +... + # Calls Before Declarations - `fn1()``fn2()` @@ -88,7 +104,7 @@ With link and alt: id: fn8 lang: graphviz link: ./graph.png - alt: A graph. + alt: A graph. ... digraph G { a -> b; @@ -102,7 +118,7 @@ With img and alt: id: fn9 lang: graphviz img: ./graph.png - alt: A graph. + alt: A graph. ... digraph G { a -> b; @@ -125,19 +141,19 @@ With inner function: --- id: fn11 args: - x: 2 + x: 2 ... - #fn1() * x + `fn1()` * x With inner function with args: --- id: fn12 - args: + args: y: 1 z: 2 ... - #y + #fn4(3, 4) + #z + #y + `fn4(3, 4)` + #z With inner inner function: @@ -146,7 +162,7 @@ With inner inner function: args: a: 1 ... - #a + #fn4(#a, #fn1()) + #a + `fn4(#a, `fn1()`)` # Code Blocks That Are Not Declarations