From 8bdc6035a8ad221f92973d08979d8d7898cfeb41 Mon Sep 17 00:00:00 2001 From: perro Date: Tue, 28 Mar 2023 13:25:02 -0700 Subject: [PATCH] Bug fixed and more refactoring --- dist/lin.lua | 384 ++++++++++++++++++++++++----------------------- src/literate.lua | 314 +++++++++++++++++++------------------- src/locale.yaml | 4 +- 3 files changed, 359 insertions(+), 343 deletions(-) diff --git a/dist/lin.lua b/dist/lin.lua index 5c5a311..bfeff01 100644 --- a/dist/lin.lua +++ b/dist/lin.lua @@ -6461,7 +6461,7 @@ local nat = {} function nat.get(str) return str end ------------------------------------ LITERATE ---------------------------------- +---------------------------------- LITERATE ---------------------------------- -- Variable for all literate stuff local lit = {} @@ -6491,193 +6491,6 @@ lit.metastruct = { }, } -function lit.stringify(content) - if pandoc.utils.type(content) == "Inlines" then - return pandoc.utils.stringify(content:walk { - Quoted = function(quoted) - local quote = (quoted.quotetype == SingleQuoted and '"' or "'") - quoted = pandoc.utils.stringify(quoted.content) - return pandoc.Str(quote .. quoted .. quote) - end, - RawInline = function(rawinline) - return pandoc.Str(rawinline.text:gsub("\\n", "\n"):gsub("\\t", "\t")) - end, - Inline = function(inline) - return pandoc.utils.stringify(inline) - end, - }) - else - return pandoc.utils.stringify(content) - end -end - -function lit.meta2table(meta) - for k, v in pairs(meta) do - if pandoc.utils.type(v) == "table" then - meta[k] = lit.meta2table(v) - else - v = lit.stringify(v) - print(v) - if v == "true" or v == "false" then - v = v == "true" - -- WARN!! - elseif tonumber(v) then - v = tonumber(v) - end - meta[k] = v - end - end - return meta -end - --- Messages for the user -lit.msg = lit.meta2table(pandoc.read([[--- -INFO: - parsing: - en: Parsing:\n#1 - es: Realizando análisis sintáctico:\n#1 -WARNING: - foo: - en: bar - es: baz -ERROR: - invalid_key: - en: Invalid key '#1' with value '#2' - es: Clave '#1' inválida con valor '#2' - invalid_path: - en: Invalid path '#1' in key '#2' - es: Ruta '#1' inválida en clave '#2' - invalid_type: - en: Invalid type '#1' in key '#2' - es: Tipo '#1' inválido en clave '#2' - invalid_value: - en: Invalid value '#1' in key '#2' - es: Valor '#1' inválido en clave '#2' - no_key: - en: Key '#1' not found - es: Clave '#1' no encontrada - aborted: - en: Aborted due previous errors - es: Abortado debido a previos errores - yaml_empty: - en: Empty YAML - es: YAML vacío - yaml_invalid: - en: Invalid YAML - es: YAML inválido -... -]]).meta) - -function lit.debuglevel(str) - if str == "ERROR" then - lit.status = false - return 2 - elseif str == "WARNING" then - return 1 - else - return 0 - end -end - -function lit.setmsg(msg, ...) - local lang = os.lang() - msg = (msg[lang] ~= nil and msg[lang] or msg) - for i, str in ipairs({...}) do - msg = msg:gsub("#" .. i, str) - end - return msg -end - -function lit.getmsg(key, ...) - local levelname = "INFO" - local level = 0 - for mtype, msgs in pairs(lit.msg) do - if msgs[key] ~= nil then - key = lit.setmsg(msgs[key], ...) - levelname, level = mtype, lit.debuglevel(mtype) - break - end - end - return key, levelname, level -end - -function lit.puts(key, ...) - local verbosity = lit.debuglevel(PANDOC_STATE.verbosity) - local msg, levelname, level = lit.getmsg(key, ...) - if level >= verbosity then - print("[" .. levelname .. "] [LIT] " .. msg) - end -end - -function lit.getmetaval(meta, key) - local mtype = pandoc.utils.type(meta[key]) - local mval = meta[key] - if mtype == "Inlines" then - mval = pandoc.utils.stringify(mval) - mtype = pandoc.utils.type(mval) - end - return mval, mtype -end - -function lit.checkmetaextra(meta) - for key, val in pairs(meta) do - local missing1 = lit.metastruct["mandatory"][key] == nil - local missing2 = lit.metastruct["optional"][key] == nil - local mval = lit.getmetaval(meta, key) - if missing1 and missing2 then - lit.puts("invalid_key", key, mval) - end - end -end - -function lit.checkmetatype(type, meta, key) - local mval, mtype = lit.getmetaval(meta, key) - if type ~= mtype then - if type == "path" then - if not(pandoc.path.directory(mval):isdir()) then - lit.puts("invalid_path", mval, key) - end - else - lit.puts("invalid_type", mtype, key) - end - end -end - --- TODO: has bug -function lit.checkmetatable(table, meta, key) - local mval = lit.getmetaval(meta, key) - for _, pattern in pairs(table) do - if mval:match("^" .. pattern .. "$") == nil then - lit.puts("invalid_value", mval, key) - end - end -end - -function lit.checkmeta(meta, kind) - for key, val in pairs(lit.metastruct[kind]) do - if meta[key] == nil then - if kind == "mandatory" then - lit.puts("no_key", key) - end - else - if type(val) == "table" then - lit.checkmetatable(val, meta, key) - else - lit.checkmetatype(val, meta, key) - end - end - end -end - -function lit.setmeta(meta) - lit.checkmeta(meta, "mandatory") - lit.checkmeta(meta, "optional") - lit.checkmetaextra(meta) - -- TODO checks for 2) duplicates - -- Set defaults if lit.status = true - return meta -end - -- Grammars lit.g = {} @@ -6718,6 +6531,200 @@ function lit.eval(code) end ]]-- +function lit.stringify_quoted(quoted) + local quote = (quoted.quotetype == SingleQuoted and '"' or "'") + quoted = pandoc.utils.stringify(quoted.content) + return pandoc.Str(quote .. quoted .. quote) +end + +function lit.stringify_rawinline(rawinline) + local str = rawinline.text + str = str:gsub("\\n", "\n"):gsub("\\t", "\t") + return pandoc.Str(str) +end + +function lit.stringify(content) + if pandoc.utils.type(content) == "Inlines" then + return pandoc.utils.stringify(content:walk { + Quoted = function(e) return lit.stringify_quoted(e) end, + RawInline = function(e) return lit.stringify_rawinline(e) end, + Inline = function(inline) return pandoc.utils.stringify(inline) end, + }) + else + return pandoc.utils.stringify(content) + end +end + +function lit.string2other(str) + if str == "true" or str == "false" then + return str == "true" + -- WARN "1" always num; cfr. https://pandoc.org/lua-filters.html#type-metavalue + elseif tonumber(str) then + return tonumber(str) + else + return str + end +end + +function lit.meta2table(meta) + for k, v in pairs(meta) do + if pandoc.utils.type(v) == "table" then + meta[k] = lit.meta2table(v) + else + meta[k] = lit.string2other(lit.stringify(v)) + end + end + return meta +end + +function lit.debuglevel(str) + if str == "ERROR" then + lit.status = false + return 2 + elseif str == "WARNING" then + return 1 + else + return 0 + end +end + +function lit.setmsg(msg, ...) + local lang = os.lang() + msg = (msg[lang] ~= nil and msg[lang] or msg) + for i, str in ipairs({...}) do + msg = msg:gsub("#" .. i, str) + end + return msg +end + +function lit.getmsg(key, ...) + local msg = lit.meta2table(pandoc.read([[--- +INFO: + parsing: + en: Parsing:\n#1 + es: Realizando análisis sintáctico:\n#1 +WARNING: + foo: + en: bar + es: baz +ERROR: + invalid_key: + en: Invalid key '#1' + es: Clave '#1' inválida + invalid_path: + en: Invalid path '#1' in key '#2' + es: Ruta '#1' inválida en clave '#2' + invalid_type: + en: Invalid type '#1' in key '#2' + es: Tipo '#1' inválido en clave '#2' + invalid_value: + en: Invalid value '#1' in key '#2' + es: Valor '#1' inválido en clave '#2' + no_key: + en: Key '#1' not found + es: Clave '#1' no encontrada + aborted: + en: Aborted due previous errors + es: Abortado debido a previos errores + yaml_empty: + en: Empty YAML + es: YAML vacío + yaml_invalid: + en: Invalid YAML + es: YAML inválido +... +]]).meta) + local levelname, level = "INFO", 0 + for mtype, msgs in pairs(msg) do + if msgs[key] ~= nil then + key = lit.setmsg(msgs[key], ...) + levelname, level = mtype, lit.debuglevel(mtype) + break + end + end + return key, levelname, level +end + +function lit.puts(key, ...) + local verbosity = lit.debuglevel(PANDOC_STATE.verbosity) + local msg, levelname, level = lit.getmsg(key, ...) + if level >= verbosity then + print("[" .. levelname .. "] [LIT] " .. msg) + end +end + +function lit.getmetaval(meta, key) + local mtype = pandoc.utils.type(meta[key]) + local mval = meta[key] + if mtype == "Inlines" then + mval = pandoc.utils.stringify(mval) + mtype = pandoc.utils.type(mval) + end + return mval, mtype +end + +function lit.checkextra(meta) + for key, val in pairs(meta) do + local missing1 = lit.metastruct["mandatory"][key] == nil + local missing2 = lit.metastruct["optional"][key] == nil + local mval = lit.getmetaval(meta, key) + if missing1 and missing2 then + lit.puts("invalid_key", key) + end + end +end + +function lit.checkmeta_type(type, meta, key) + local mval, mtype = lit.getmetaval(meta, key) + if type ~= mtype then + if type == "path" then + if not(pandoc.path.directory(mval):isdir()) then + lit.puts("invalid_path", mval, key) + end + else + lit.puts("invalid_type", mtype, key) + end + end +end + +function lit.checkmeta_match(table, mval, key) + for _, pattern in pairs(table) do + if mval:match("^" .. pattern .. "$") then + return "" + end + end + return key +end + +function lit.checkmeta_table(table, meta, key) + local mval = lit.getmetaval(meta, key) + local err = lit.checkmeta_match(table, mval, key) + if not(err:isempty()) then + lit.puts("invalid_value", mval, err) + end +end + +function lit.checkmeta(meta, kind) + 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 + lit.checkmeta_table(val, meta, key) + elseif meta[key] then + lit.checkmeta_type(val, meta, key) + end + end +end + +function lit.setmeta(meta) + lit.checkmeta(meta, "mandatory") + lit.checkmeta(meta, "optional") + lit.checkextra(meta) + -- TODO checks for 2) duplicates + -- Set defaults if lit.status = true + return meta +end + -- TODO function lit.assert(e, status) if status == false then @@ -6728,6 +6735,7 @@ function lit.assert(e, status) end function lit.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 diff --git a/src/literate.lua b/src/literate.lua index e8557ba..7b0d467 100644 --- a/src/literate.lua +++ b/src/literate.lua @@ -1,4 +1,4 @@ ------------------------------------ LITERATE ---------------------------------- +---------------------------------- LITERATE ---------------------------------- -- Variable for all literate stuff local lit = {} @@ -28,158 +28,6 @@ lit.metastruct = { }, } -function lit.stringify(content) - if pandoc.utils.type(content) == "Inlines" then - return pandoc.utils.stringify(content:walk { - Quoted = function(quoted) - local quote = (quoted.quotetype == SingleQuoted and '"' or "'") - quoted = pandoc.utils.stringify(quoted.content) - return pandoc.Str(quote .. quoted .. quote) - end, - RawInline = function(rawinline) - return pandoc.Str(rawinline.text:gsub("\\n", "\n"):gsub("\\t", "\t")) - end, - Inline = function(inline) - return pandoc.utils.stringify(inline) - end, - }) - else - return pandoc.utils.stringify(content) - end -end - -function lit.meta2table(meta) - for k, v in pairs(meta) do - if pandoc.utils.type(v) == "table" then - meta[k] = lit.meta2table(v) - else - v = lit.stringify(v) - print(v) - if v == "true" or v == "false" then - v = v == "true" - -- WARN!! - elseif tonumber(v) then - v = tonumber(v) - end - meta[k] = v - end - end - return meta -end - --- Messages for the user -lit.msg = lit.meta2table(pandoc.read([[#locale()]]).meta) - -function lit.debuglevel(str) - if str == "ERROR" then - lit.status = false - return 2 - elseif str == "WARNING" then - return 1 - else - return 0 - end -end - -function lit.setmsg(msg, ...) - local lang = os.lang() - msg = (msg[lang] ~= nil and msg[lang] or msg) - for i, str in ipairs({...}) do - msg = msg:gsub("#" .. i, str) - end - return msg -end - -function lit.getmsg(key, ...) - local levelname = "INFO" - local level = 0 - for mtype, msgs in pairs(lit.msg) do - if msgs[key] ~= nil then - key = lit.setmsg(msgs[key], ...) - levelname, level = mtype, lit.debuglevel(mtype) - break - end - end - return key, levelname, level -end - -function lit.puts(key, ...) - local verbosity = lit.debuglevel(PANDOC_STATE.verbosity) - local msg, levelname, level = lit.getmsg(key, ...) - if level >= verbosity then - print("[" .. levelname .. "] [LIT] " .. msg) - end -end - -function lit.getmetaval(meta, key) - local mtype = pandoc.utils.type(meta[key]) - local mval = meta[key] - if mtype == "Inlines" then - mval = pandoc.utils.stringify(mval) - mtype = pandoc.utils.type(mval) - end - return mval, mtype -end - -function lit.checkmetaextra(meta) - for key, val in pairs(meta) do - local missing1 = lit.metastruct["mandatory"][key] == nil - local missing2 = lit.metastruct["optional"][key] == nil - local mval = lit.getmetaval(meta, key) - if missing1 and missing2 then - lit.puts("invalid_key", key, mval) - end - end -end - -function lit.checkmetatype(type, meta, key) - local mval, mtype = lit.getmetaval(meta, key) - if type ~= mtype then - if type == "path" then - if not(pandoc.path.directory(mval):isdir()) then - lit.puts("invalid_path", mval, key) - end - else - lit.puts("invalid_type", mtype, key) - end - end -end - --- TODO: has bug -function lit.checkmetatable(table, meta, key) - local mval = lit.getmetaval(meta, key) - for _, pattern in pairs(table) do - if mval:match("^" .. pattern .. "$") == nil then - lit.puts("invalid_value", mval, key) - end - end -end - -function lit.checkmeta(meta, kind) - for key, val in pairs(lit.metastruct[kind]) do - if meta[key] == nil then - if kind == "mandatory" then - lit.puts("no_key", key) - end - else - if type(val) == "table" then - lit.checkmetatable(val, meta, key) - else - lit.checkmetatype(val, meta, key) - end - end - end -end - -function lit.setmeta(meta) - lit.checkmeta(meta, "mandatory") - lit.checkmeta(meta, "optional") - lit.checkmetaextra(meta) - -- TODO checks for 2) duplicates - -- Set defaults if lit.status = true - return meta -end - -- Grammars lit.g = {} @@ -220,6 +68,165 @@ function lit.eval(code) end ]]-- +function lit.stringify_quoted(quoted) + local quote = (quoted.quotetype == SingleQuoted and '"' or "'") + quoted = pandoc.utils.stringify(quoted.content) + return pandoc.Str(quote .. quoted .. quote) +end + +function lit.stringify_rawinline(rawinline) + local str = rawinline.text + str = str:gsub("\\n", "\n"):gsub("\\t", "\t") + return pandoc.Str(str) +end + +function lit.stringify(content) + if pandoc.utils.type(content) == "Inlines" then + return pandoc.utils.stringify(content:walk { + Quoted = function(e) return lit.stringify_quoted(e) end, + RawInline = function(e) return lit.stringify_rawinline(e) end, + Inline = function(inline) return pandoc.utils.stringify(inline) end, + }) + else + return pandoc.utils.stringify(content) + end +end + +function lit.string2other(str) + if str == "true" or str == "false" then + return str == "true" + -- WARN "1" always num; cfr. https://pandoc.org/lua-filters.html#type-metavalue + elseif tonumber(str) then + return tonumber(str) + else + return str + end +end + +function lit.meta2table(meta) + for k, v in pairs(meta) do + if pandoc.utils.type(v) == "table" then + meta[k] = lit.meta2table(v) + else + meta[k] = lit.string2other(lit.stringify(v)) + end + end + return meta +end + +function lit.debuglevel(str) + if str == "ERROR" then + lit.status = false + return 2 + elseif str == "WARNING" then + return 1 + else + return 0 + end +end + +function lit.setmsg(msg, ...) + local lang = os.lang() + msg = (msg[lang] ~= nil and msg[lang] or msg) + for i, str in ipairs({...}) do + msg = msg:gsub("#" .. i, str) + end + return msg +end + +function lit.getmsg(key, ...) + local msg = lit.meta2table(pandoc.read([[#locale()]]).meta) + local levelname, level = "INFO", 0 + for mtype, msgs in pairs(msg) do + if msgs[key] ~= nil then + key = lit.setmsg(msgs[key], ...) + levelname, level = mtype, lit.debuglevel(mtype) + break + end + end + return key, levelname, level +end + +function lit.puts(key, ...) + local verbosity = lit.debuglevel(PANDOC_STATE.verbosity) + local msg, levelname, level = lit.getmsg(key, ...) + if level >= verbosity then + print("[" .. levelname .. "] [LIT] " .. msg) + end +end + +function lit.getmetaval(meta, key) + local mtype = pandoc.utils.type(meta[key]) + local mval = meta[key] + if mtype == "Inlines" then + mval = pandoc.utils.stringify(mval) + mtype = pandoc.utils.type(mval) + end + return mval, mtype +end + +function lit.checkextra(meta) + for key, val in pairs(meta) do + local missing1 = lit.metastruct["mandatory"][key] == nil + local missing2 = lit.metastruct["optional"][key] == nil + local mval = lit.getmetaval(meta, key) + if missing1 and missing2 then + lit.puts("invalid_key", key) + end + end +end + +function lit.checkmeta_type(type, meta, key) + local mval, mtype = lit.getmetaval(meta, key) + if type ~= mtype then + if type == "path" then + if not(pandoc.path.directory(mval):isdir()) then + lit.puts("invalid_path", mval, key) + end + else + lit.puts("invalid_type", mtype, key) + end + end +end + +function lit.checkmeta_match(table, mval, key) + for _, pattern in pairs(table) do + if mval:match("^" .. pattern .. "$") then + return "" + end + end + return key +end + +function lit.checkmeta_table(table, meta, key) + local mval = lit.getmetaval(meta, key) + local err = lit.checkmeta_match(table, mval, key) + if not(err:isempty()) then + lit.puts("invalid_value", mval, err) + end +end + +function lit.checkmeta(meta, kind) + 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 + lit.checkmeta_table(val, meta, key) + elseif meta[key] then + lit.checkmeta_type(val, meta, key) + end + end +end + +function lit.setmeta(meta) + lit.checkmeta(meta, "mandatory") + lit.checkmeta(meta, "optional") + lit.checkextra(meta) + -- TODO checks for 2) duplicates + -- Set defaults if lit.status = true + return meta +end + -- TODO function lit.assert(e, status) if status == false then @@ -230,6 +237,7 @@ function lit.assert(e, status) end function lit.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 diff --git a/src/locale.yaml b/src/locale.yaml index e8eacb3..14478bb 100644 --- a/src/locale.yaml +++ b/src/locale.yaml @@ -9,8 +9,8 @@ WARNING: es: baz ERROR: invalid_key: - en: Invalid key '#1' with value '#2' - es: Clave '#1' inválida con valor '#2' + en: Invalid key '#1' + es: Clave '#1' inválida invalid_path: en: Invalid path '#1' in key '#2' es: Ruta '#1' inválida en clave '#2'