diff --git a/dist/lin.lua b/dist/lin.lua index 3bbf1fe..e161cb1 100644 --- a/dist/lin.lua +++ b/dist/lin.lua @@ -6718,141 +6718,134 @@ ERROR: end end --- TODO -function lit.assert(e, status) - if status == false then - lit.puts("aborted") - os.exit(1) - end - return e +function lit.insert(code) + return code end -function lit.getblock(codeblock) +function lit.parse(blocks) - local function checkextra(meta) - for key, val in pairs(meta) do - local missing1 = lit.metastruct["mandatory"][key] == nil - local missing2 = lit.metastruct["optional"][key] == nil - if missing1 and missing2 then - lit.puts("invalid_key", key) - end + local function parse(codeblock, islast) + + local function checkextra(meta) + for key, val in pairs(meta) do + local missing1 = lit.metastruct["mandatory"][key] == nil + local missing2 = lit.metastruct["optional"][key] == nil + if missing1 and missing2 then + lit.puts("invalid_key", key) + end + end + end + + local function checkmeta(meta, kind) + + local function checktype(type1, meta, key) + local val = meta[key] + local type2 = type(val) + if type1 ~= type2 then + if type1 == "path" then + if not(pandoc.path.directory(val):isdir()) then + lit.puts("invalid_path", val, key) + end + else + lit.puts("invalid_type", type2, key) + end + end + end + + local function checktable(table, meta, key) + + local function checkmatch(table, val, key) + for _, pattern in pairs(table) do + if val:match("^" .. pattern .. "$") then + return "" + end + end + return key + end + + local val = tostring(meta[key]) + local err = checkmatch(table, val, key) + if not(err:isempty()) then + lit.puts("invalid_value", val, err) + end + end + + for key, val in pairs(lit.metastruct[kind]) do + if meta[key] == nil and kind == "mandatory" then + lit.puts("no_key", key) + elseif meta[key] and type(val) == "table" then + checktable(val, meta, key) + elseif meta[key] then + checktype(val, meta, key) + end + end + end + + local function setmeta(meta) + local tmeta = lit.meta2table(meta) + checkmeta(tmeta, "mandatory") + checkmeta(tmeta, "optional") + checkextra(tmeta) + -- TODO checks for 2) duplicates + -- Set defaults if lit.status = true + return meta + end + + local function parseyaml(rawyaml) + -- TODO io.try + local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1") + if yaml:read("*l"):sub(1, 1) == "{" then + yaml = pandoc.read(rawyaml).meta + if pandoc.utils.stringify(yaml):isempty() then + lit.puts("yaml_empty") + else + return setmeta(yaml) + end + else + lit.puts("yaml_invalid") + return nil + end + end + + local function inspect(parsed) + lit.puts("parsing", table.concat(parsed, ""):indent()) + local yaml = parseyaml(parsed[1]) + -- TODO: parsecode + return "TODO" + end + + local parsed = lpeg.match(lit.g("block"), codeblock.text) + parsed = (parsed ~= nil and inspect(parsed) or parsed) + if islast and not(lit.status) then + lit.puts("aborted") + os.exit(1) end + return codeblock + end + + local function lastblockindex() + local last = 0 + blocks:walk { CodeBlock = function(_) last = last + 1 end } + return last end - local function checkmeta(meta, kind) - - local function checktype(type1, meta, key) - local val = meta[key] - local type2 = type(val) - if type1 ~= type2 then - if type1 == "path" then - if not(pandoc.path.directory(val):isdir()) then - lit.puts("invalid_path", val, key) - end - else - lit.puts("invalid_type", type2, key) - end - end + local curr = 0 + return blocks:walk { + CodeBlock = function(codeblock) + curr = curr + 1 + return parse(codeblock, curr == lastblockindex()) end - - local function checktable(table, meta, key) - - local function checkmatch(table, val, key) - for _, pattern in pairs(table) do - if val:match("^" .. pattern .. "$") then - return "" - end - end - return key - end - - local val = meta[key] - local err = checkmatch(table, val, key) - if not(err:isempty()) then - lit.puts("invalid_value", val, err) - end - end - - for key, val in pairs(lit.metastruct[kind]) do - if meta[key] == nil and kind == "mandatory" then - lit.puts("no_key", key) - elseif meta[key] and type(val) == "table" then - checktable(val, meta, key) - elseif meta[key] then - checktype(val, meta, key) - end - end - end - - local function setmeta(meta) - local tmeta = lit.meta2table(meta) - checkmeta(tmeta, "mandatory") - checkmeta(tmeta, "optional") - checkextra(tmeta) - -- TODO checks for 2) duplicates - -- Set defaults if lit.status = true - return meta - end - - local function parseyaml(rawyaml) - -- TODO io.try - local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1") - if yaml:read("*l"):sub(1, 1) == "{" then - yaml = pandoc.read(rawyaml).meta - if pandoc.utils.stringify(yaml):isempty() then - lit.puts("yaml_empty") - else - return setmeta(yaml) - end - else - lit.puts("yaml_invalid") - return nil - end - end - - local function inspect(parsed) - lit.puts("parsing", table.concat(parsed, ""):indent()) - local yaml = parseyaml(parsed[1]) - -- TODO: parsecode - return "TODO" - end - - local parsed = lpeg.match(lit.g("block"), codeblock.text) - parsed = (parsed ~= nil and inspect(parsed) or parsed) - return codeblock, lit.status -end - -function lit.getinsert(code) - return code, lit.status + } end ------------------------------------ PANDOC ----------------------------------- -local litstatus = true - return { + -- Parses and evals literate blocks + { Blocks = function(blocks) return lit.parse(blocks) end }, + -- Parses and inserts literate evals + { Code = function(code) return lit.insert(code) end }, { - -- Parses and evals literate blocks - CodeBlock = function(codeblock) - codeblock, litstatus = lit.getblock(codeblock) - return codeblock - end, - -- Asserts literate - Pandoc = function(pandoc) - return lit.assert(pandoc, litstatus) - end, - }, - { - -- Parses literate inserts - Code = function(code) - code, litstatus = lit.getinsert(code) - return code - end, - -- Asserts literate - Pandoc = function(pandoc) - return lit.assert(pandoc, litstatus) - end, - }, { -- Parses and evals natural programming -- TODO Inlines = function(inlines) diff --git a/src/literate.lua b/src/literate.lua index 4095fc3..6223537 100644 --- a/src/literate.lua +++ b/src/literate.lua @@ -165,112 +165,124 @@ function lit.puts(key, ...) end end --- TODO -function lit.assert(e, status) - if status == false then - lit.puts("aborted") - os.exit(1) - end - return e +function lit.insert(code) + return code end -function lit.getblock(codeblock) +function lit.parse(blocks) - local function checkextra(meta) - for key, val in pairs(meta) do - local missing1 = lit.metastruct["mandatory"][key] == nil - local missing2 = lit.metastruct["optional"][key] == nil - if missing1 and missing2 then - lit.puts("invalid_key", key) - end + local function parse(codeblock, islast) + + local function checkextra(meta) + for key, val in pairs(meta) do + local missing1 = lit.metastruct["mandatory"][key] == nil + local missing2 = lit.metastruct["optional"][key] == nil + if missing1 and missing2 then + lit.puts("invalid_key", key) + end + end + end + + local function checkmeta(meta, kind) + + local function checktype(type1, meta, key) + local val = meta[key] + local type2 = type(val) + if type1 ~= type2 then + if type1 == "path" then + if not(pandoc.path.directory(val):isdir()) then + lit.puts("invalid_path", val, key) + end + else + lit.puts("invalid_type", type2, key) + end + end + end + + local function checktable(table, meta, key) + + local function checkmatch(table, val, key) + for _, pattern in pairs(table) do + if val:match("^" .. pattern .. "$") then + return "" + end + end + return key + end + + local val = tostring(meta[key]) + local err = checkmatch(table, val, key) + if not(err:isempty()) then + lit.puts("invalid_value", val, err) + end + end + + for key, val in pairs(lit.metastruct[kind]) do + if meta[key] == nil and kind == "mandatory" then + lit.puts("no_key", key) + elseif meta[key] and type(val) == "table" then + checktable(val, meta, key) + elseif meta[key] then + checktype(val, meta, key) + end + end + end + + local function setmeta(meta) + local tmeta = lit.meta2table(meta) + checkmeta(tmeta, "mandatory") + checkmeta(tmeta, "optional") + checkextra(tmeta) + -- TODO checks for 2) duplicates + -- Set defaults if lit.status = true + return meta + end + + local function parseyaml(rawyaml) + -- TODO io.try + local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1") + if yaml:read("*l"):sub(1, 1) == "{" then + yaml = pandoc.read(rawyaml).meta + if pandoc.utils.stringify(yaml):isempty() then + lit.puts("yaml_empty") + else + return setmeta(yaml) + end + else + lit.puts("yaml_invalid") + return nil + end + end + + local function inspect(parsed) + lit.puts("parsing", table.concat(parsed, ""):indent()) + local yaml = parseyaml(parsed[1]) + -- TODO: parsecode + return "TODO" + end + + local parsed = lpeg.match(lit.g("block"), codeblock.text) + parsed = (parsed ~= nil and inspect(parsed) or parsed) + if islast and not(lit.status) then + lit.puts("aborted") + os.exit(1) end + return codeblock + end + + local function lastblockindex() + local last = 0 + blocks:walk { CodeBlock = function(_) last = last + 1 end } + return last end - local function checkmeta(meta, kind) - - local function checktype(type1, meta, key) - local val = meta[key] - local type2 = type(val) - if type1 ~= type2 then - if type1 == "path" then - if not(pandoc.path.directory(val):isdir()) then - lit.puts("invalid_path", val, key) - end - else - lit.puts("invalid_type", type2, key) - end - end + local curr = 0 + return blocks:walk { + CodeBlock = function(codeblock) + curr = curr + 1 + return parse(codeblock, curr == lastblockindex()) end - - local function checktable(table, meta, key) - - local function checkmatch(table, val, key) - for _, pattern in pairs(table) do - if val:match("^" .. pattern .. "$") then - return "" - end - end - return key - end - - local val = meta[key] - local err = checkmatch(table, val, key) - if not(err:isempty()) then - lit.puts("invalid_value", val, err) - end - end - - for key, val in pairs(lit.metastruct[kind]) do - if meta[key] == nil and kind == "mandatory" then - lit.puts("no_key", key) - elseif meta[key] and type(val) == "table" then - checktable(val, meta, key) - elseif meta[key] then - checktype(val, meta, key) - end - end - end - - local function setmeta(meta) - local tmeta = lit.meta2table(meta) - checkmeta(tmeta, "mandatory") - checkmeta(tmeta, "optional") - checkextra(tmeta) - -- TODO checks for 2) duplicates - -- Set defaults if lit.status = true - return meta - end - - local function parseyaml(rawyaml) - -- TODO io.try - local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1") - if yaml:read("*l"):sub(1, 1) == "{" then - yaml = pandoc.read(rawyaml).meta - if pandoc.utils.stringify(yaml):isempty() then - lit.puts("yaml_empty") - else - return setmeta(yaml) - end - else - lit.puts("yaml_invalid") - return nil - end - end - - local function inspect(parsed) - lit.puts("parsing", table.concat(parsed, ""):indent()) - local yaml = parseyaml(parsed[1]) - -- TODO: parsecode - return "TODO" - end - - local parsed = lpeg.match(lit.g("block"), codeblock.text) - parsed = (parsed ~= nil and inspect(parsed) or parsed) - return codeblock, lit.status -end - -function lit.getinsert(code) - return code, lit.status + } end return lit diff --git a/src/pandoc.lua b/src/pandoc.lua index 53d9e6c..7d3a73b 100644 --- a/src/pandoc.lua +++ b/src/pandoc.lua @@ -1,30 +1,11 @@ ------------------------------------ PANDOC ----------------------------------- -local litstatus = true - return { + -- Parses and evals literate blocks + { Blocks = function(blocks) return lit.parse(blocks) end }, + -- Parses and inserts literate evals + { Code = function(code) return lit.insert(code) end }, { - -- Parses and evals literate blocks - CodeBlock = function(codeblock) - codeblock, litstatus = lit.getblock(codeblock) - return codeblock - end, - -- Asserts literate - Pandoc = function(pandoc) - return lit.assert(pandoc, litstatus) - end, - }, - { - -- Parses literate inserts - Code = function(code) - code, litstatus = lit.getinsert(code) - return code - end, - -- Asserts literate - Pandoc = function(pandoc) - return lit.assert(pandoc, litstatus) - end, - }, { -- Parses and evals natural programming -- TODO Inlines = function(inlines)