diff options
Diffstat (limited to 'tools/build-doc.lua')
-rw-r--r-- | tools/build-doc.lua | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/tools/build-doc.lua b/tools/build-doc.lua new file mode 100644 index 00000000..fbf5fa6b --- /dev/null +++ b/tools/build-doc.lua @@ -0,0 +1,197 @@ +package.path = package.path .. ';script/?.lua;tools/?.lua' + +local fs = require 'bee.filesystem' +local config = require 'configuration' +local markdown = require 'provider.markdown' +local util = require 'utility' +local lloader = require 'locale-loader' +local json = require 'json-beautify' +local diagd = require 'proto.diagnostic' + +local function mergeDiagnosticGroupLocale(locale) + for groupName, names in pairs(diagd.diagnosticGroups) do + local key = ('config.diagnostics.%s'):format(groupName) + local list = {} + for name in util.sortPairs(names) do + list[#list+1] = ('* %s'):format(name) + end + local desc = table.concat(list, '\n') + locale[key] = desc + end +end + +local function getLocale() + local locale = {} + + for dirPath in fs.pairs(fs.path 'locale') do + local lang = dirPath:filename():string() + local text = util.loadFile((dirPath / 'setting.lua'):string()) + if text then + locale[lang] = lloader(text, lang) + -- add `config.diagnostics.XXX` + mergeDiagnosticGroupLocale(locale[lang]) + end + end + + return locale +end + +local localeMap = getLocale() + +local function getDesc(lang, desc) + if not desc then + return nil + end + if desc:sub(1, 1) ~= '%' or desc:sub(-1, -1) ~= '%' then + return desc + end + local locale = localeMap[lang] + if not locale then + return desc + end + local id = desc:sub(2, -2) + return locale[id] +end + +local function buildType(md, lang, conf) + md:add('md', '## type') + if type(conf.type) == 'table' then + md:add('ts', ('%s | %s'):format(conf.type[1], conf.type[2])) + elseif conf.type == 'array' then + md:add('ts', ('Array<%s>'):format(conf.items.type)) + elseif conf.type == 'object' then + if conf.properties then + local _, first = next(conf.properties) + assert(first) + md:add('ts', ('object<string, %s>'):format(first.type)) + elseif conf.patternProperties then + local _, first = next(conf.patternProperties) + assert(first) + md:add('ts', ('Object<string, %s>'):format(first.type)) + else + md:add('ts', '**Unknown object type!!**') + end + else + md:add('ts', ('%s'):format(conf.type)) + end +end + +local function buildDesc(md, lang, conf) + local desc = conf.markdownDescription or conf.description + desc = getDesc(lang, desc) + if desc then + md:add('md', desc) + else + md:add('md', '**Missing description!!**') + end + md:emptyLine() +end + +local function buildDefault(md, lang, conf) + local default = conf.default + if default == json.null then + default = nil + end + md:add('md', '## default') + if conf.type == 'object' then + if not default then + default = {} + for k, v in pairs(conf.properties) do + default[k] = v.default + end + end + local list = util.getTableKeys(default, true) + if #list == 0 then + md:add('jsonc', '{}') + return + end + md:add('jsonc', '{') + for i, k in ipairs(list) do + local desc = getDesc(lang, conf.properties[k].description) + if desc then + md:add('jsonc', ' /*') + md:add('jsonc', (' %s'):format(desc:gsub('\n', '\n '))) + md:add('jsonc', ' */') + end + if i == #list then + md:add('jsonc',(' %s: %s'):format(json.encode(k), json.encode(default[k]))) + else + md:add('jsonc',(' %s: %s,'):format(json.encode(k), json.encode(default[k]))) + end + end + md:add('jsonc', '}') + else + md:add('jsonc', ('%s'):format(json.encode(default))) + end +end + +local function buildEnum(md, lang, conf) + if conf.enum then + md:add('md', '## enum') + md:emptyLine() + for i, enum in ipairs(conf.enum) do + local desc = getDesc(lang, conf.markdownEnumDescriptions and conf.markdownEnumDescriptions[i]) + if desc then + md:add('md', ('* ``%s``: %s'):format(json.encode(enum), desc)) + else + md:add('md', ('* ``%s``'):format(json.encode(enum))) + end + end + md:emptyLine() + return + end + + if conf.type == 'object' and conf.properties then + local _, first = next(conf.properties) + if first and first.enum then + md:add('md', '## enum') + md:emptyLine() + for i, enum in ipairs(first.enum) do + local desc = getDesc(lang, conf.markdownEnumDescriptions and conf.markdownEnumDescriptions[i]) + if desc then + md:add('md', ('* ``%s``: %s'):format(json.encode(enum), desc)) + else + md:add('md', ('* ``%s``'):format(json.encode(enum))) + end + end + md:emptyLine() + return + end + end + + if conf.type == 'array' and conf.items.enum then + md:add('md', '## enum') + md:emptyLine() + for i, enum in ipairs(conf.items.enum) do + local desc = getDesc(lang, conf.markdownEnumDescriptions and conf.markdownEnumDescriptions[i]) + if desc then + md:add('md', ('* ``%s``: %s'):format(json.encode(enum), desc)) + else + md:add('md', ('* ``%s``'):format(json.encode(enum))) + end + end + md:emptyLine() + return + end +end + +local function buildMarkdown(lang) + local dir = fs.path 'doc' / lang + fs.create_directories(dir) + local configDoc = markdown() + + for name, conf in util.sortPairs(config) do + configDoc:add('md', '# ' .. name:gsub('^Lua%.', '')) + configDoc:emptyLine() + buildDesc(configDoc, lang, conf) + buildType(configDoc, lang, conf) + buildEnum(configDoc, lang, conf) + buildDefault(configDoc, lang, conf) + end + + util.saveFile((dir / 'config.md'):string(), configDoc:string()) +end + +for lang in pairs(localeMap) do + buildMarkdown(lang) +end |