Module:Find sources/autodoc/sandbox: Difference between revisions
Appearance
Content deleted Content added
No edit summary |
|||
Line 7: | Line 7: | ||
local AUTODOC_SUFFIX = '/autodoc' |
local AUTODOC_SUFFIX = '/autodoc' |
||
-- Load necessary modules. |
-- Load necessary modules. |
||
local mFindSources = require('Module:Find sources |
local mFindSources = require('Module:Find sources') |
||
local cfg = mw.loadData('Module:Find sources/autodoc/config') |
local cfg = mw.loadData('Module:Find sources/autodoc/config') |
||
Line 56: | Line 56: | ||
end |
end |
||
local function isValidTemplateCfg(templateCfg) |
|||
if type(templateCfg) ~= 'table' then |
|||
return false |
|||
end |
|||
for _, s in ipairs{'blurb'} do |
|||
if type(templateCfg[s]) ~= 'string' then |
|||
return false |
|||
end |
|||
end |
|||
for _, s in ipairs{'separator', 'class', 'style'} do |
|||
if templateCfg[s] ~= nil and type(templateCfg[s]) ~= 'string' then |
|||
return false |
|||
end |
|||
end |
|||
if templateCfg.isUsedInMainspace and templateCfg.isUsedInMainspace ~= true then |
|||
return false |
|||
end |
|||
if type(templateCfg.links) ~= 'table' then |
|||
return false |
|||
end |
|||
local function isValidLinkTable(t) |
|||
if type(t) ~= 'table' then |
|||
return false |
|||
end |
|||
if type(t.code) ~= 'string' then |
|||
return false |
|||
end |
|||
if t.display and type(t.display) ~= 'string' then |
|||
return false |
|||
end |
|||
return true |
|||
end |
|||
if templateCfg.introLink and not isValidLinkTable(templateCfg.introLink) then |
|||
return false |
|||
end |
|||
for _, t in ipairs(templateCfg.links) do |
|||
if not isValidLinkTable(t) then |
|||
return false |
|||
end |
|||
end |
|||
return true |
|||
end |
|||
local function isValidTemplate(template) |
|||
if type(template) ~= 'string' or template == '' then |
|||
return false |
|||
end |
|||
local templateCfg = maybeLoadData(TEMPLATE_ROOT .. template) |
|||
return isValidTemplateCfg(templateCfg) |
|||
end |
|||
local function isValidLinkAutdocCfg(t) |
local function isValidLinkAutdocCfg(t) |
||
Line 194: | Line 247: | ||
end |
end |
||
function p.templateTable( |
function p.templateTable() |
||
local templates = sortKeys(require(TEMPLATE_LIST)) |
local templates = sortKeys(require(TEMPLATE_LIST)) |
||
local headers = { |
local headers = { |
||
Line 204: | Line 257: | ||
local rows = {} |
local rows = {} |
||
for i, template in ipairs(templates) do |
for i, template in ipairs(templates) do |
||
if isValidTemplate(template) then |
|||
local autodocConfigPage = TEMPLATE_ROOT .. template .. AUTODOC_SUFFIX |
|||
local configPage = TEMPLATE_ROOT .. template |
|||
local templateData = maybeLoadData(autodocConfigPage) |
|||
local autodocConfigPage = configPage .. AUTODOC_SUFFIX |
|||
if not isValidTemplateAutdocCfg(templateData) then |
|||
templateData = |
local templateData = maybeLoadData(autodocConfigPage) |
||
if not isValidTemplateAutdocCfg(templateData) then |
|||
templateData = {} |
|||
end |
|||
-- Make the example text |
|||
local success, example = pcall( |
|||
mFindSources._main, |
|||
template, |
|||
{cfg['example-search-term']} |
|||
) |
|||
if not success then |
|||
example = makeWikitextError(example) |
|||
end |
|||
-- Build the row. |
|||
local row = { |
|||
bold(makeWikilink(mw.site.namespaces[10].name .. ':' .. template, template)), |
|||
templateData.description or grey("''No description available''"), |
|||
example, |
|||
table.concat({ |
|||
makeWikilink(configPage, cfg['template-table-main-config-link-display']), |
|||
makeWikilink(autodocConfigPage, cfg['template-table-autodoc-config-link-display']) |
|||
}, cfg['table-config-separator']) |
|||
} |
|||
rows[i] = row |
|||
else |
|||
local msg = substituteParams( |
|||
cfg['invalid-template-config-error'], |
|||
TEMPLATE_ROOT .. template |
|||
) |
|||
msg = makeWikitextError(msg) |
|||
msg = colspan(msg, 4) |
|||
rows[i] = {msg} |
|||
end |
end |
||
local example = frame:expandTemplate{title=template} |
|||
-- Build the row. |
|||
local row = { |
|||
bold(makeWikilink(mw.site.namespaces[10].name .. ':' .. template, template)), |
|||
templateData.description or grey("''No description available''"), |
|||
example, |
|||
table.concat({ |
|||
makeWikilink(autodocConfigPage, cfg['template-table-autodoc-config-link-display']) |
|||
}, cfg['table-config-separator']) |
|||
} |
|||
rows[i] = row |
|||
end |
end |
||
return makeWikitable(headers, rows) |
return makeWikitable(headers, rows) |
||
end |
end |
||
function |
local function documentation(template) |
||
-- This function makes documentation for the template |
-- This function makes documentation for the template specified in |
||
-- the template parameter. The template should be without the "Template:" |
|||
-- prefix. |
|||
-- Load necessary modules |
-- Load necessary modules |
||
local mDocumentation = require('Module:Documentation') |
local mDocumentation = require('Module:Documentation') |
||
local mList = require('Module:List') |
local mList = require('Module:List') |
||
local |
local frame = mw.getCurrentFrame() |
||
-- Load the config files |
|||
-- Remove "Template:" |
|||
local templateCfg = maybeLoadData(TEMPLATE_ROOT .. template) |
|||
template = template:sub(10) |
|||
if not isValidTemplateCfg(templateCfg) then |
|||
if template:sub(-8) == '/sandbox' then |
|||
error(substituteParams( |
|||
-- This makes {{Find sources/sandbox|Albert Einstein}} work. |
|||
cfg['invalid-template-name-error'], |
|||
template = template:sub(1, -9) |
|||
template, |
|||
TEMPLATE_ROOT .. template |
|||
)) |
|||
end |
end |
||
local autodocCfg = maybeLoadData(TEMPLATE_ROOT .. template .. AUTODOC_SUFFIX) |
local autodocCfg = maybeLoadData(TEMPLATE_ROOT .. template .. AUTODOC_SUFFIX) |
||
if not isValidTemplateAutdocCfg(autodocCfg) then |
if not isValidTemplateAutdocCfg(autodocCfg) then |
||
Line 253: | Line 332: | ||
end |
end |
||
local args = frame.args |
|||
-- Link descriptions |
-- Link descriptions |
||
local codes = {} |
local codes = {} |
||
if templateCfg.introLink then |
|||
if args.introlink and #args.introlink > 0 then |
|||
codes[#codes + 1] = |
codes[#codes + 1] = templateCfg.introLink.code |
||
end |
end |
||
for _, t in ipairs(templateCfg.links) do |
|||
local linkno = 1 |
|||
codes[#codes + 1] = t.code |
|||
while true do |
|||
local linkArg = args["link"..tostring(linkno)] |
|||
if linkArg == nil then |
|||
break |
|||
end |
|||
codes[#codes + 1] = linkArg |
|||
linkno = linkno + 1 |
|||
end |
end |
||
for i, code in ipairs(codes) do |
for i, code in ipairs(codes) do |
||
Line 282: | Line 354: | ||
shortcuts = shortcuts, |
shortcuts = shortcuts, |
||
docIntro = autodocCfg.docIntro, |
docIntro = autodocCfg.docIntro, |
||
isUsedInMainspace = |
isUsedInMainspace = templateCfg.isUsedInMainspace and 'yes' or nil, |
||
linkDescriptions = linkDescriptions |
linkDescriptions = linkDescriptions |
||
}} |
}} |
||
end |
end |
||
return |
return mDocumentation.main{content = content, ['link box'] = cfg['end-box-blurb']} |
||
end |
end |
||
setmetatable(p, { __index = function(t, template) |
|||
return function() |
|||
return documentation(template) |
|||
end |
|||
end}) |
|||
return p |
return p |
Revision as of 09:22, 31 July 2020
![]() | This is the module sandbox page for Module:Find sources/autodoc (diff). |
This module provides automatic documentation for templates based on Module:Find sources. See Module:Find sources#Automatic documentation for an overview.
-- Define constants
local ROOT_PAGE = 'Module:Find sources'
local TEMPLATE_LIST = ROOT_PAGE .. '/templates' -- template config module list
local TEMPLATE_ROOT = TEMPLATE_LIST .. '/' -- template config module prefix
local LINK_LIST = ROOT_PAGE .. '/links' -- link config module list
local LINK_ROOT = LINK_LIST .. '/' -- link config module prefix
local AUTODOC_SUFFIX = '/autodoc'
-- Load necessary modules.
local mFindSources = require('Module:Find sources')
local cfg = mw.loadData('Module:Find sources/autodoc/config')
local p = {}
local function maybeLoadData(page)
local success, data = pcall(mw.loadData, page)
return success and data
end
local function substituteParams(msg, ...)
return mw.message.newRawMessage(msg, ...):plain()
end
local function sortKeys(t)
local ret = {}
for k in pairs(t) do
ret[#ret + 1] = k
end
table.sort(ret)
return ret
end
local function isValidLinkCfg(linkCfg)
if type(linkCfg) ~= 'table' then
return false
end
for _, s in ipairs{'url', 'display'} do
if type(linkCfg[s]) ~= 'string' then
return false
end
end
for _, s in ipairs{'separator'} do
if linkCfg[s] ~= nil and type(linkCfg[s]) ~= 'string' then
return false
end
end
return true
end
local function isValidLink(code)
if type(code) ~= 'string' or code == '' then
return false
end
local linkCfg = maybeLoadData(LINK_ROOT .. code)
return isValidLinkCfg(linkCfg)
end
local function isValidTemplateCfg(templateCfg)
if type(templateCfg) ~= 'table' then
return false
end
for _, s in ipairs{'blurb'} do
if type(templateCfg[s]) ~= 'string' then
return false
end
end
for _, s in ipairs{'separator', 'class', 'style'} do
if templateCfg[s] ~= nil and type(templateCfg[s]) ~= 'string' then
return false
end
end
if templateCfg.isUsedInMainspace and templateCfg.isUsedInMainspace ~= true then
return false
end
if type(templateCfg.links) ~= 'table' then
return false
end
local function isValidLinkTable(t)
if type(t) ~= 'table' then
return false
end
if type(t.code) ~= 'string' then
return false
end
if t.display and type(t.display) ~= 'string' then
return false
end
return true
end
if templateCfg.introLink and not isValidLinkTable(templateCfg.introLink) then
return false
end
for _, t in ipairs(templateCfg.links) do
if not isValidLinkTable(t) then
return false
end
end
return true
end
local function isValidTemplate(template)
if type(template) ~= 'string' or template == '' then
return false
end
local templateCfg = maybeLoadData(TEMPLATE_ROOT .. template)
return isValidTemplateCfg(templateCfg)
end
local function isValidLinkAutdocCfg(t)
if type(t) ~= 'table' then
return false
end
for _, s in ipairs{'description', 'notes'} do
if t[s] and type(t[s]) ~= 'string' then
return false
end
end
return true
end
local function isValidTemplateAutdocCfg(t)
if type(t) ~= 'table' then
return false
end
for _, s in ipairs{'description', 'docIntro'} do
if t[s] and type(t[s]) ~= 'string' then
return false
end
end
if t.shortcuts and type(t.shortcuts) ~= 'table' then
return false
elseif t.shortcuts then
for _, s in ipairs(t.shortcuts) do
if type(s) ~= 'string' then
return false
end
end
end
return true
end
local function makeWikitable(headers, rows)
local ret = {}
-- Table start
ret[#ret + 1] = '{| class="wikitable"'
-- Headers
ret[#ret + 1] = '|-'
for i, header in ipairs(headers) do
ret[#ret + 1] = '! ' .. header
end
-- Rows
for i, row in ipairs(rows) do
ret[#ret + 1] = '|-'
for j, cell in ipairs(row) do
ret[#ret + 1] = '| ' .. cell
end
end
-- Table end
ret[#ret + 1] = '|}'
return table.concat(ret, '\n')
end
local function grey(s)
return string.format('<span style="color: gray;">%s</span>', s)
end
local function bold(s)
return string.format("'''%s'''", s)
end
local function colspan(s, n)
return string.format('colspan="%d" | %s', n, s)
end
local function makeWikitextError(msg)
return string.format('<strong class="error">%s</strong>', msg)
end
local function makeWikilink(page, display)
if display then
return string.format('[[%s|%s]]', page, display)
else
return string.format('[[%s]]', page)
end
end
function p.linkTable()
local codes = sortKeys(require(LINK_LIST))
local headers = {
cfg['link-table-code-header'],
cfg['link-table-description-header'],
cfg['link-table-example-header'],
cfg['link-table-config-header'],
cfg['link-table-notes-header']
}
local rows = {}
for i, code in ipairs(codes) do
if isValidLink(code) then
local configPage = LINK_ROOT .. code
local autodocConfigPage = configPage .. AUTODOC_SUFFIX
local linkData = maybeLoadData(autodocConfigPage)
if not isValidLinkAutdocCfg(linkData) then
linkData = {}
end
-- Make the example link.
local success, link = pcall(
mFindSources._renderLink,
code,
{cfg['example-search-term']}
)
if not success then
link = makeWikitextError(link)
end
-- Build the row.
local row = {
bold(code),
linkData.description or grey("''No description available''"),
link,
table.concat({
makeWikilink(configPage, cfg['link-table-main-config-link-display']),
makeWikilink(autodocConfigPage, cfg['link-table-autodoc-config-link-display'])
}, cfg['table-config-separator']),
linkData.notes or ''
}
rows[i] = row
else
local msg = substituteParams(
cfg['invalid-link-config-error'],
LINK_ROOT .. code
)
msg = makeWikitextError(msg)
msg = colspan(msg, 5)
rows[i] = {msg}
end
end
return makeWikitable(headers, rows)
end
function p.templateTable()
local templates = sortKeys(require(TEMPLATE_LIST))
local headers = {
cfg['template-table-template-header'],
cfg['template-table-description-header'],
cfg['template-table-example-header'],
cfg['template-table-config-header'],
}
local rows = {}
for i, template in ipairs(templates) do
if isValidTemplate(template) then
local configPage = TEMPLATE_ROOT .. template
local autodocConfigPage = configPage .. AUTODOC_SUFFIX
local templateData = maybeLoadData(autodocConfigPage)
if not isValidTemplateAutdocCfg(templateData) then
templateData = {}
end
-- Make the example text
local success, example = pcall(
mFindSources._main,
template,
{cfg['example-search-term']}
)
if not success then
example = makeWikitextError(example)
end
-- Build the row.
local row = {
bold(makeWikilink(mw.site.namespaces[10].name .. ':' .. template, template)),
templateData.description or grey("''No description available''"),
example,
table.concat({
makeWikilink(configPage, cfg['template-table-main-config-link-display']),
makeWikilink(autodocConfigPage, cfg['template-table-autodoc-config-link-display'])
}, cfg['table-config-separator'])
}
rows[i] = row
else
local msg = substituteParams(
cfg['invalid-template-config-error'],
TEMPLATE_ROOT .. template
)
msg = makeWikitextError(msg)
msg = colspan(msg, 4)
rows[i] = {msg}
end
end
return makeWikitable(headers, rows)
end
local function documentation(template)
-- This function makes documentation for the template specified in
-- the template parameter. The template should be without the "Template:"
-- prefix.
-- Load necessary modules
local mDocumentation = require('Module:Documentation')
local mList = require('Module:List')
local frame = mw.getCurrentFrame()
-- Load the config files
local templateCfg = maybeLoadData(TEMPLATE_ROOT .. template)
if not isValidTemplateCfg(templateCfg) then
error(substituteParams(
cfg['invalid-template-name-error'],
template,
TEMPLATE_ROOT .. template
))
end
local autodocCfg = maybeLoadData(TEMPLATE_ROOT .. template .. AUTODOC_SUFFIX)
if not isValidTemplateAutdocCfg(autodocCfg) then
autodocCfg = {}
end
-- Get the documentation content
local content
do
-- Shortcuts
local shortcuts
if autodocCfg.shortcuts then
shortcuts = frame:expandTemplate{title = 'Template shortcut', args = autodocCfg.shortcuts}
end
-- Link descriptions
local codes = {}
if templateCfg.introLink then
codes[#codes + 1] = templateCfg.introLink.code
end
for _, t in ipairs(templateCfg.links) do
codes[#codes + 1] = t.code
end
for i, code in ipairs(codes) do
local linkAutodocCfg = maybeLoadData(LINK_ROOT .. code .. AUTODOC_SUFFIX)
if not isValidLinkAutdocCfg(linkAutodocCfg) then
linkAutodocCfg = {}
end
codes[i] = linkAutodocCfg.description or code
end
local linkDescriptions = mList.bulleted(codes)
-- Build the content.
content = frame:expandTemplate{title = 'Find sources documentation', args = {
template = template,
shortcuts = shortcuts,
docIntro = autodocCfg.docIntro,
isUsedInMainspace = templateCfg.isUsedInMainspace and 'yes' or nil,
linkDescriptions = linkDescriptions
}}
end
return mDocumentation.main{content = content, ['link box'] = cfg['end-box-blurb']}
end
setmetatable(p, { __index = function(t, template)
return function()
return documentation(template)
end
end})
return p