From edc1d06bec5155ab2cd78338fd70c59d0ea1175e Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 20 Sep 2018 15:29:07 +0200 Subject: [PATCH] initial templatization of types and variables --- .gitignore | 2 + docgen/doc.lua | 180 +++++++++++++++++++++++++++++++++++++ docgen/eolian_utils.lua | 97 -------------------- docgen/mono.lua | 9 +- docgen/writer.lua | 53 ----------- gendoc.lua | 185 ++++++++++++-------------------------- templates/alias.txt | 19 ++++ templates/struct_enum.txt | 27 ++++++ templates/variable.txt | 19 ++++ 9 files changed, 307 insertions(+), 284 deletions(-) create mode 100644 .gitignore create mode 100644 docgen/doc.lua create mode 100644 templates/alias.txt create mode 100644 templates/struct_enum.txt create mode 100644 templates/variable.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac33ba8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dokuwiki +*.luac diff --git a/docgen/doc.lua b/docgen/doc.lua new file mode 100644 index 0000000..3059387 --- /dev/null +++ b/docgen/doc.lua @@ -0,0 +1,180 @@ +local eolian = require("eolian") +local eoutils = require("docgen.eolian_utils") +local writer = require("docgen.writer") + +local M = {} + +local has_notes = false +local has_title = false +local root_nspace + +local make_link = function(target, title) + local buf = { "[[" } + if type(target) == "table" then + if target[#target] == false then + target[#target] = nil + target = ":" .. root_nspace .. "-include:" + .. table.concat(target, ":") + else + target[#target] = nil + target = ":" .. root_nspace .. ":" + .. table.concat(target, ":") + end + end + buf[#buf + 1] = target:lower() + buf[#buf + 1] = "|" + if not title then + buf[#buf + 1] = target + elseif type(title) == "string" then + buf[#buf + 1] = title + else + buf[#buf + 1] = title() + end + buf[#buf + 1] = "]]" + return table.concat(buf) +end + +local make_i = function(str) + return "//" .. str .. "//" +end + +local escape_par = function(eos, str) + local tok = eolian.doc_token_init() + local notetypes = has_notes and { + [eolian.doc_token_type.MARK_NOTE] = "\n", + [eolian.doc_token_type.MARK_WARNING] = "\n", + [eolian.doc_token_type.MARK_REMARK] = "\n", + [eolian.doc_token_type.MARK_TODO] = "\n**TODO:** " + } or {} + local hasraw, hasnote = false, false + local tokf = function() + str = eolian.documentation_tokenize(str, tok) + return not not str + end + local buf = {} + while tokf() do + local tp = tok:type_get() + local tag = notetypes[tp] + if tag then + buf[#buf + 1] = tag + hasnote = true + else + if not hasraw then + buf[#buf + 1] = "%%" + hasraw = true + end + if tp == eolian.doc_token_type.REF then + local reft = eoutils.tok_ref_resolve(tok, eos, true) + local str = tok:text_get() + if str:sub(1, 1) == "[" then + str = str:sub(2, #str - 1) + end + buf[#buf + 1] = "%%" + buf[#buf + 1] = make_link(reft, str) + buf[#buf + 1] = "%%" + else + local str = tok:text_get() + assert(str, "internal tokenizer error") + -- replace possible %% chars + str = str:gsub("%%%%", "%%%%%%%%%%%%") + if tp == eolian.doc_token_type.MARKUP_MONOSPACE then + buf[#buf + 1] = "%%''" .. str .. "''%%" + else + buf[#buf + 1] = str + end + end + end + end + buf[#buf + 1] = "%%" + if hasnote then + buf[#buf + 1] = "\n" + end + return table.concat(buf) +end + +local gen_doc_refd = function(str, eos) + if not str then + return nil + end + local pars = eolian.documentation_string_split(str) + for i = 1, #pars do + pars[i] = escape_par(eos, pars[i]) + end + return table.concat(pars, "\n\n") +end + +local add_since = function(str, since) + if not since then + return str + end + local ret = make_i("Since " .. since) + if not str then + return ret + end + return str .. "\n\n" .. ret +end + +M.brief_str_get = function(eos, obj, obj2) + if not obj and not obj2 then + return "No description supplied." + end + if not obj then + obj = obj2 + end + return gen_doc_refd(obj:summary_get(), eos) +end + +M.full_str_get = function(eos, obj, obj2, write_since) + if not obj and not obj2 then + return "No description supplied." + end + if not obj then + obj, obj2 = obj2, obj + end + local sum1 = obj:summary_get() + local desc1 = obj:description_get() + local edoc = "" + local since + if obj2 then + local sum2 = obj2:summary_get() + local desc2 = obj2:descirption_get() + if not desc2 then + if sum2 then + edoc = "\n\n" .. sum2 + end + else + edoc = "\n\n" .. sum2 .. "\n\n" .. desc2 + end + if write_since then + since = obj2:since_get() + end + end + if not since and write_since then + since = obj:since_get() + end + if not desc1 then + return add_since(gen_doc_refd(sum1 .. edoc, eos), since) + end + return add_since(gen_doc_refd(sum1 .. "\n\n" .. desc1 .. edoc, eos), since) +end + +M.title_str_get = function(str) + if has_title then + return "~~Title: " .. str .. "~~" + end + return str +end + +M.editable_get = function(ns, name) + local buf = writer.Buffer() + buf:write_editable(ns, name) + return buf:finish():sub(1, #buf - 2) +end + +M.init = function(root, use_notes, use_title) + root_nspace = root + has_notes = use_notes + has_title = use_title +end + +return M diff --git a/docgen/eolian_utils.lua b/docgen/eolian_utils.lua index 00f0d72..412c3c1 100644 --- a/docgen/eolian_utils.lua +++ b/docgen/eolian_utils.lua @@ -86,103 +86,6 @@ M.func_nspaces_get = function(obj, cl, root) return tbl end -local gen_doc_refd = function(str, eos) - if not writer then - writer = require("docgen.writer") - end - if not str then - return nil - end - local pars = eolian.documentation_string_split(str) - for i = 1, #pars do - pars[i] = writer.Buffer():write_par(pars[i], eos):finish() - end - return table.concat(pars, "\n\n") -end - -local add_since = function(str, since) - if not writer then - writer = require("docgen.writer") - end - if not since then - return str - end - local buf = writer.Buffer() - if not str then - buf:write_i("Since " .. since) - return buf:finish() - end - buf:write_raw(str) - buf:write_nl(2) - buf:write_i("Since " .. since) - return buf:finish() -end - -M.doc_summary_get = function(obj) - if not obj then - return nil - end - return obj:summary_get() -end - -M.doc_description_get = function(obj) - if not obj then - return nil - end - return obj:description_get() -end - -M.doc_since_get = function(obj) - if not obj then - return nil - end - return obj:since_get() -end - -M.doc_brief_get = function(eos, obj, obj2) - if not obj and not obj2 then - return "No description supplied." - end - if not obj then - obj = obj2 - end - return gen_doc_refd(obj:summary_get(), eos) -end - -M.doc_full_get = function(eos, obj, obj2, write_since) - if not obj and not obj2 then - return "No description supplied." - end - if not obj then - obj, obj2 = obj2, obj - end - local sum1 = obj:summary_get() - local desc1 = obj:description_get() - local edoc = "" - local since - if obj2 then - local sum2 = obj2:summary_get() - local desc2 = obj2:descirption_get() - if not desc2 then - if sum2 then - edoc = "\n\n" .. sum2 - end - else - edoc = "\n\n" .. sum2 .. "\n\n" .. desc2 - end - if write_since then - since = obj2:since_get() - end - end - if not since and write_since then - since = obj:since_get() - end - if not desc1 then - return add_since(gen_doc_refd(sum1 .. edoc, eos), since) - end - return add_since(gen_doc_refd(sum1 .. "\n\n" .. desc1 .. edoc, eos), since) -end - local class_type_str = { [eolian.class_type.REGULAR] = "class", [eolian.class_type.ABSTRACT] = "class", diff --git a/docgen/mono.lua b/docgen/mono.lua index 3d764a0..e771ca9 100644 --- a/docgen/mono.lua +++ b/docgen/mono.lua @@ -3,6 +3,7 @@ local writer = require("docgen.writer") local eolian = require("eolian") local eoutils = require("docgen.eolian_utils") +local docm = require("docgen.doc") local eos @@ -210,14 +211,14 @@ local find_parent_briefdoc find_parent_briefdoc = function(fulln, cl) local pimpl, pcl = find_parent_impl(fulln, cl) if not pimpl then - return eoutils.doc_brief_get(eos) + return docm.brief_str_get(eos) end local pdoc = pimpl:documentation_get(eolian.function_type.METHOD) local pdocf = eoutils.impl_fallback_doc_get(pimpl) if not pdoc and not pdocf then return find_parent_briefdoc(fulln, pcl) end - return eoutils.doc_brief_get(eos, pdocf) + return docm.brief_str_get(eos, pdocf) end @@ -230,7 +231,7 @@ local write_description = function(f, impl, func, cl) if over and not doc and not docf then bdoc = find_parent_briefdoc(impl:name_get(), cl) else - bdoc = eoutils.doc_brief_get(eos, docf) + bdoc = docm.brief_str_get(eos, docf) end if bdoc ~= "No description supplied." then f:write_raw(bdoc) @@ -573,7 +574,7 @@ M.build_class = function(cl) f:write_h(cl:name_get() .. " (" .. eoutils.class_type_str_get(cl) .. ")", 1) f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, cl:documentation_get(), nil, true)) + f:write_raw(docm.full_str_get(eos, cl:documentation_get(), nil, true)) f:write_nl(2) f:write_editable(cln, "description") diff --git a/docgen/writer.lua b/docgen/writer.lua index 288e21c..cf7bd41 100644 --- a/docgen/writer.lua +++ b/docgen/writer.lua @@ -326,59 +326,6 @@ writers["dokuwiki"] = util.Object:clone { return self end, - write_par = function(self, str, eos) - local tokp = eolian.doc_token_init() - local notetypes = M.has_feature("notes") and { - [eolian.doc_token_type.MARK_NOTE] = "\n", - [eolian.doc_token_type.MARK_WARNING] = "\n", - [eolian.doc_token_type.MARK_REMARK] = "\n", - [eolian.doc_token_type.MARK_TODO] = "\n**TODO:** " - } or {} - local hasraw, hasnote = false, false - local tokf = function() - str = eolian.documentation_tokenize(str, tokp) - return not not str - end - while tokf() do - local tp = tokp:type_get() - local tag = notetypes[tp] - if tag then - self:write_raw(tag) - hasnote = true - else - if not hasraw then - self:write_raw("%%") - hasraw = true - end - if tp == eolian.doc_token_type.REF then - local reft = eoutils.tok_ref_resolve(tokp, eos, true) - local str = tokp:text_get() - if str:sub(1, 1) == "[" then - str = str:sub(2, #str - 1) - end - self:write_raw("%%") - self:write_link(reft, str) - self:write_raw("%%") - else - local str = tokp:text_get() - assert(str, "internal tokenizer error") - -- replace possible %% chars - str = str:gsub("%%%%", "%%%%%%%%%%%%") - if tp == eolian.doc_token_type.MARKUP_MONOSPACE then - self:write_raw("%%''" .. str .. "''%%") - else - self:write_raw(str) - end - end - end - end - self:write_raw("%%") - if hasnote then - self:write_raw("\n") - end - return self - end, - write_folded = function(self, title, func) if M.has_feature("folds") then self:write_raw("++++ ", title, " |\n\n") diff --git a/gendoc.lua b/gendoc.lua index 9cfddce..0e9c87d 100644 --- a/gendoc.lua +++ b/gendoc.lua @@ -2,8 +2,11 @@ local getopt = require("getopt") local serializer = require("serializer") +local template = require("template") + local eolian = require("eolian") local eoutils = require("docgen.eolian_utils") +local docm = require("docgen.doc") local stats = require("docgen.stats") local dutil = require("docgen.util") @@ -15,6 +18,21 @@ local eos local printgen = function() end +local render_template = function(tpath, ns, title, ctx) + local nctx = { + doc = docm, eos = eos, eolian = eolian, + eoutils = eoutils, title = docm.title_str_get(title), page_ns = ns + } + if ctx then + nctx = setmetatable(nctx, { __index = ctx }) + end + local f = writer.Writer(ns) + tpath = "templates/" .. tpath .. ".txt" + print("rendering template: " .. tpath .. " (" .. title .. ")") + f:write_raw(template.compile(tpath)(nctx, true)) + f:finish() +end + local propt_to_type = { [eolian.function_type.PROPERTY] = "(get, set)", [eolian.function_type.PROP_GET] = "(get)", @@ -345,7 +363,7 @@ local build_reftable = function(f, title, ctype, t, iscl) eoutils.obj_nspaces_get(v), v:name_get() ):finish(), - eoutils.doc_brief_get(eos, v:documentation_get()) + docm.brief_str_get(eos, v:documentation_get()) } end table.sort(nt, function(v1, v2) return v1[1] < v2[1] end) @@ -478,14 +496,14 @@ local find_parent_briefdoc find_parent_briefdoc = function(fulln, cl) local pimpl, pcl = find_parent_impl(fulln, cl) if not pimpl then - return eoutils.doc_brief_get(eos, nil) + return docm.brief_str_get(eos, nil) end local pdoc = pimpl:documentation_get(eolian.function_type.METHOD) local pdocf = eoutils.impl_fallback_doc_get(pimpl) if not pdoc and not pdocf then return find_parent_briefdoc(fulln, pcl) end - return eoutils.doc_brief_get(eos, pdocf) + return docm.brief_str_get(eos, pdocf) end local build_functable = function(f, tcl, tbl) @@ -554,7 +572,7 @@ local write_description = function(f, impl, func, cl) if over and not doc and not docf then bdoc = find_parent_briefdoc(impl:name_get(), cl) else - bdoc = eoutils.doc_brief_get(eos, docf) + bdoc = docm.brief_str_get(eos, docf) end if bdoc ~= "No description supplied." then f:write_raw(bdoc) @@ -812,7 +830,7 @@ local write_evtable = function(f, tcl, tbl) write_event_scope(f, ev) -- description - local bdoc = eoutils.doc_brief_get(eos, ev:documentation_get()) + local bdoc = docm.brief_str_get(eos, ev:documentation_get()) if bdoc ~= "No description supplied." then f:write_br(true) f:write_raw("> ") @@ -858,7 +876,7 @@ local write_inherit_evtable = function(f, tcl, tbl) f:write_b(llbuf:finish()) f:write_raw(" | ") - local bdoc = eoutils.doc_brief_get(eos, ev:documentation_get()) + local bdoc = docm.brief_str_get(eos, ev:documentation_get()) if bdoc ~= "No description supplied." then f:write_raw(bdoc) end @@ -879,7 +897,7 @@ local build_class = function(cl) f:write_h(cl:name_get() .. " (" .. eoutils.class_type_str_get(cl) .. ")", 1) f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, cl:documentation_get(), nil, true)) + f:write_raw(docm.full_str_get(eos, cl:documentation_get(), nil, true)) f:write_nl(2) f:write_editable(cln, "description") @@ -933,139 +951,45 @@ local build_classes = function() end end -local write_tsigs = function(f, tp, ns) - f:write_h("Signature", 2) - f:write_code(eoutils.obj_serialize(tp)) - f:write_nl() - - f:write_h("C signature", 2) - f:write_code(eoutils.obj_serialize_c(tp, ns), "c") - f:write_nl() -end - -local build_alias = function(tp) - local ns = eoutils.obj_nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating alias: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, tp:documentation_get(), nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_struct = function(tp) - local ns = eoutils.obj_nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating struct: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, tp:documentation_get(), nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - f:write_h("Fields", 2) - - f:write_editable(ns, "fields") - f:write_nl() - - local arr = {} - for fl in tp:struct_fields_get() do - local buf = writer.Buffer() - buf:write_b(fl:name_get()) - buf:write_raw(" - ", eoutils.doc_full_get(eos, fl:documentation_get())) - arr[#arr + 1] = buf:finish() - end - f:write_list(arr) - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_enum = function(tp) - local ns = eoutils.obj_nspaces_get(tp) - local fulln = tp:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating enum: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, tp:documentation_get(), nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - f:write_h("Fields", 2) - - f:write_editable(ns, "fields") - f:write_nl() - - local arr = {} - for fl in tp:enum_fields_get() do - local buf = writer.Buffer() - buf:write_b(fl:name_get()) - buf:write_raw(" - ", eoutils.doc_full_get(eos, fl:documentation_get())) - arr[#arr + 1] = buf:finish() - end - f:write_list(arr) - f:write_nl() - - write_tsigs(f, tp, ns) - - f:finish() -end - -local build_variable = function(v, constant) - local ns = eoutils.obj_nspaces_get(v) - local fulln = v:name_get() - local f = writer.Writer(ns, fulln) - printgen("Generating variable: " .. fulln) - - f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, v:documentation_get(), nil, true)) - f:write_nl(2) - - f:write_editable(ns, "description") - f:write_nl() - - write_tsigs(f, v, ns) - - f:finish() -end - local build_typedecls = function() for tp in eos:aliases_get() do - build_alias(tp) + render_template("alias", eoutils.obj_nspaces_get(tp), tp:name_get(), { + type_obj = tp + }) end for tp in eos:structs_get() do - build_struct(tp) + render_template( + "struct_enum", eoutils.obj_nspaces_get(tp), tp:name_get(), { + type_obj = tp, obj_fields = tp:struct_fields_get() + } + ) end for tp in eos:enums_get() do - build_enum(tp) + render_template( + "struct_enum", eoutils.obj_nspaces_get(tp), tp:name_get(), { + type_obj = tp, obj_fields = tp:enum_fields_get() + } + ) end end local build_variables = function() for v in eos:constants_get() do - build_variable(v, true) + render_template( + "variable", eoutils.obj_nspaces_get(v), v:name_get(), { + var_obj = v, var_is_constant = true + } + ) end for v in eos:globals_get() do - build_variable(v, false) + render_template( + "variable", eoutils.obj_nspaces_get(v), v:name_get(), { + var_obj = v, var_is_constant = false + } + ) end end @@ -1078,7 +1002,7 @@ local build_parlist = function(f, pl, nodir) buf:write_raw(" ") buf:write_i("(", eoutils.param_get_dir_name(p), ")") end - buf:write_raw(" - ", eoutils.doc_full_get(eos, p:documentation_get())) + buf:write_raw(" - ", docm.full_str_get(eos, p:documentation_get())) params[#params + 1] = buf:finish() end f:write_list(params) @@ -1217,7 +1141,7 @@ build_method = function(impl, cl) end f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, doc, nil, true)) + f:write_raw(docm.full_str_get(eos, doc, nil, true)) f:write_nl() f:write_editable(mns, "description") @@ -1278,7 +1202,7 @@ build_property = function(impl, cl) if isget and isset then f:write_h("Description", 2) if doc or (not gdoc and not sdoc) then - f:write_raw(eoutils.doc_full_get(eos, doc, nil, true)) + f:write_raw(docm.full_str_get(eos, doc, nil, true)) end if (isget and gdoc) or (isset and sdoc) then f:write_nl(2) @@ -1302,7 +1226,7 @@ build_property = function(impl, cl) else f:write_h("Description", 2) end - f:write_raw(eoutils.doc_full_get(eos, gdoc, nil, true)) + f:write_raw(docm.full_str_get(eos, gdoc, nil, true)) if isset and sdoc then f:write_nl(2) end @@ -1319,7 +1243,7 @@ build_property = function(impl, cl) else f:write_h("Description", 2) end - f:write_raw(eoutils.doc_full_get(eos, sdoc, nil, true)) + f:write_raw(docm.full_str_get(eos, sdoc, nil, true)) if isget then f:write_nl() f:write_editable(pns, "getter_description") @@ -1391,7 +1315,7 @@ build_event = function(ev, cl) printgen("Generating event: " .. evnm) f:write_h("Description", 2) - f:write_raw(eoutils.doc_full_get(eos, ev:documentation_get(), nil, true)) + f:write_raw(docm.full_str_get(eos, ev:documentation_get(), nil, true)) f:write_nl() f:write_editable(evn, "description") @@ -1582,6 +1506,7 @@ getopt.parse { title = not opts["disable-title"] } writer.init(rootns, wfeatures) + docm.init(rootns, wfeatures.notes, wfeatures.title) if not st or st == "rm" then dutil.rm_root() dutil.mkdir_r(nil) diff --git a/templates/alias.txt b/templates/alias.txt new file mode 100644 index 0000000..80aae66 --- /dev/null +++ b/templates/alias.txt @@ -0,0 +1,19 @@ +{*title*} + +===== Description ===== + +{*doc.full_str_get(eos, type_obj:documentation_get(), nil, true)*} + +{*doc.editable_get(page_ns, "description")*} + +===== Signature ===== + + +{*eoutils.obj_serialize(type_obj)*} + + +===== C signature ===== + + +{*eoutils.obj_serialize_c(type_obj, page_ns)*} + diff --git a/templates/struct_enum.txt b/templates/struct_enum.txt new file mode 100644 index 0000000..508bc74 --- /dev/null +++ b/templates/struct_enum.txt @@ -0,0 +1,27 @@ +{*title*} + +===== Description ===== + +{*doc.full_str_get(eos, type_obj:documentation_get(), nil, true)*} + +{*doc.editable_get(page_ns, "description")*} + +===== Fields ===== + +{*doc.editable_get(page_ns, "fields")*} + +{% for fl in obj_fields do %} + * **{*fl:name_get()*}** - {*doc.full_str_get(eos, fl:documentation_get())*} +{% end %} + +===== Signature ===== + + +{*eoutils.obj_serialize(type_obj)*} + + +===== C signature ===== + + +{*eoutils.obj_serialize_c(type_obj, page_ns)*} + diff --git a/templates/variable.txt b/templates/variable.txt new file mode 100644 index 0000000..e20c9aa --- /dev/null +++ b/templates/variable.txt @@ -0,0 +1,19 @@ +{*title*} + +===== Description ===== + +{*doc.full_str_get(eos, var_obj:documentation_get(), nil, true)*} + +{*doc.editable_get(page_ns, "description")*} + +===== Signature ===== + + +{*eoutils.obj_serialize(var_obj)*} + + +===== C signature ===== + + +{*eoutils.obj_serialize_c(var_obj, page_ns)*} +