Module:documentation: Difference between revisions

m 1 revision imported
No edit summary
Line 2: Line 2:


local array_module = "Module:array"
local array_module = "Module:array"
local debug_track_module = "Module:debug/track"
local frame_module = "Module:frame"
local frame_module = "Module:frame"
local fun_is_callable_module = "Module:fun/isCallable"
local fun_is_callable_module = "Module:fun/isCallable"
Line 45: Line 44:
categorize_module = require(module_categorization_module).categorize
categorize_module = require(module_categorization_module).categorize
return categorize_module(...)
return categorize_module(...)
end
local function debug_track(...)
debug_track = require(debug_track_module)
return debug_track(...)
end
end


Line 163: Line 157:


local skins = {
local skins = {
["common"     ] = "";
["common"] = "",
["vector"     ] = "Vector";
["vector"] = "Vector",
["monobook"   ] = "Monobook";
["monobook"] = "Monobook",
["cologneblue"] = "Cologne Blue";
["cologneblue"] = "Cologne Blue",
["modern"     ] = "Modern";
["modern"] = "Modern",
}
}
local function track(page)
debug_track("documentation/" .. page)
return true
end


local function compare_pages(page1, page2, text)
local function compare_pages(page1, page2, text)
return "[" .. tostring(
return "[" .. tostring(
full_url("Special:ComparePages", {page1 = page1, page2 = page2}))
full_url("Special:ComparePages", { page1 = page1, page2 = page2 }))
.. " " .. text .. "]"
.. " " .. text .. "]"
end
end


-- Avoid transcluding [[Module:languages/cache]] everywhere.
-- Avoid transcluding [[Module:languages/cache]] everywhere.
local lang_cache = setmetatable({}, { __index = function (self, k)
local lang_cache = setmetatable({}, {
return require("Module:languages/cache")[k]
__index = function(self, k)
end })
return require("Module:languages/cache")[k]
end
})


local function zh_link(word)
local function zh_link(word)
return full_link{
return full_link {
lang = lang_cache.zh,
lang = lang_cache.zh,
term = word
term = word
Line 217: Line 208:
local function make_Unicode_data_documentation(title, cats)
local function make_Unicode_data_documentation(title, cats)
local subpage, first_three_of_code_point
local subpage, first_three_of_code_point
= title.fullText:match("^Module:Unicode data/([^/]+)/(%x%x%x)$")
= title.fullText:match("^Module:Unicode data/([^/]+)/(%x%x%x)$")
if subpage == "names" or subpage == "images" or subpage == "emoji images" then
if subpage == "names" or subpage == "images" or subpage == "emoji images" then
local low, high =
local low, high =
Line 235: Line 226:
low, high)
low, high)
if subpage == "images" and safe_load_data("Module:Unicode data/emoji images/" .. first_three_of_code_point) then
if subpage == "images" and safe_load_data("Module:Unicode data/emoji images/" .. first_three_of_code_point) then
text = text .. " This list includes the text variants of emojis. For the list of emoji variants of those characters, see [[Module:Unicode data/emoji images/" .. first_three_of_code_point .. "]]."
text = text ..
" This list includes the text variants of emojis. For the list of emoji variants of those characters, see [[Module:Unicode data/emoji images/" ..
first_three_of_code_point .. "]]."
elseif subpage == "emoji images" then
elseif subpage == "emoji images" then
text = text .. " For text-style images, see [[Module:Unicode data/images/" .. first_three_of_code_point .. "]]."
text = text ..
" For text-style images, see [[Module:Unicode data/images/" .. first_three_of_code_point .. "]]."
end
end
return text
return text
Line 272: Line 266:
where:
where:
  * TITLE is a title object describing the module's title; see
  * TITLE is a title object describing the module's title; see
    [https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Title_objects].
[https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Title_objects].
  * CATS is an array object (see [[Module:array]]) of categories that the module will be added to.
  * CATS is an array object (see [[Module:array]]) of categories that the module will be added to.
  * CAPTURE1, CAPTURE2, ... contain any captures in the `regex` field.
  * CAPTURE1, CAPTURE2, ... contain any captures in the `regex` field.
Line 451: Line 445:
local lang, langname = insert_lang_data_module_cats(cats, lang_code, "Category tree data modules/lang")
local lang, langname = insert_lang_data_module_cats(cats, lang_code, "Category tree data modules/lang")
if lang then
if lang then
return "This module handles generating the descriptions and categorization for " .. langname .. " category pages "
return "This module handles generating the descriptions and categorization for " ..
langname .. " category pages "
.. "of the format \"" .. langname .. " LABEL\" where LABEL can be any text. Examples are "
.. "of the format \"" .. langname .. " LABEL\" where LABEL can be any text. Examples are "
.. "[[:Category:Bulgarian conjugation 2.1 verbs]] and [[:Category:Russian velar-stem neuter-form nouns]]. "
.. "[[:Category:Bulgarian conjugation 2.1 verbs]] and [[:Category:Russian velar-stem neuter-form nouns]]. "
Line 559: Line 554:
cats:insert(lang:getCanonicalName() .. " modules|" .. refname)
cats:insert(lang:getCanonicalName() .. " modules|" .. refname)
cats:insert(("Reference modules|%s"):format(lang:getCanonicalName()))
cats:insert(("Reference modules|%s"):format(lang:getCanonicalName()))
return "This module implements the reference template {{temp|R:" .. lang_code .. ":" .. refname .. "}}."
return "This module implements the reference template {{temp|R:" .. lang_code .. ":" .. refname .. "}}."
end
end
end,
end,
Line 581: Line 576:
return "This module contains data on specific varieties of " .. langname .. ", for use by " ..
return "This module contains data on specific varieties of " .. langname .. ", for use by " ..
"{{tl|dialect synonyms}}. The actual synonyms themselves are contained in submodules.\n\n" ..
"{{tl|dialect synonyms}}. The actual synonyms themselves are contained in submodules.\n\n" ..
"==== Language data module structure ====\n" ..
"* <code>export.title</code> — optional; table title template (e.g. \"Regional synonyms of %s\").\n" ..
"* <code>export.columns</code> — optional; list of column headers for location hierarchy (e.g. {\"Dialect group\", \"Dialect\", \"Location\"}).\n" ..
"* <code>export.notes</code> — optional; table of note keys to text.\n" ..
"* <code>export.sources</code> — optional; table of source keys to text.\n" ..
"* <code>export.note_aliases</code> — optional; alias map for notes.\n" ..
"* <code>export.varieties</code> — required; nested table of variety nodes. Each node must have <code>name</code>; array part holds children. Node keys can include <code>text_display</code>, <code>color</code>, <code>code</code>, <code>wikidata</code>, <code>lat</code>, <code>long</code>, and language-specific keys (e.g. <code>persian</code>, <code>armenian</code>, <code>chinese</code>).\n\n" ..
expand_template({ title = 'dial syn', args = { lang_code, ["demo mode"] = "y" } })
expand_template({ title = 'dial syn', args = { lang_code, ["demo mode"] = "y" } })
end
end
Line 586: Line 588:
},
},
{
{
regex = "^Module:dialect synonyms/([%l-]+)/(.+)$",
regex = "^Module:dialect synonyms/([%l-]+)/([^/]+)$",
process = function(title, cats, lang_code, term)
process = function(title, cats, lang_code, term)
local lang = lang_cache[lang_code]
local lang = lang_cache[lang_code]
Line 593: Line 595:
cats:insert("Dialect synonyms data modules|" .. langname)
cats:insert("Dialect synonyms data modules|" .. langname)
cats:insert(langname .. " dialect synonyms data modules|" .. term)
cats:insert(langname .. " dialect synonyms data modules|" .. term)
return ("This module contains dialectal %s synonyms for {{m|%s|%s}}.\n\n%s"):format(langname, lang_code, term, expand_template({ title = 'dial syn', args = { lang_code, term } }))
return ("%s\n\n%s"):format(
"==== Term/sense module structure ====\n" ..
"* <code>export.title</code> — optional; custom table title (e.g. \"Realization of 'strong R' between vowels\"). Overrides the language default.\n" ..
"* <code>export.meaning</code> — optional; meaning/gloss (alternative to <code>gloss</code>).\n" ..
"* <code>export.gloss</code> — optional; short meaning for the table.\n" ..
"* <code>export.note</code> — optional; single note key or string, or list of note keys.\n" ..
"* <code>export.notes</code> — optional; list of note keys.\n" ..
"* <code>export.source</code> / <code>export.sources</code> — optional; source keys.\n" ..
"* <code>export.last_column</code> — optional; label for the data column (default \"Words\"; e.g. \"Realization\").\n" ..
"* <code>export.syns</code> — required; table mapping variety/location names (keys from the language data module) to a list of term entries. Each entry can be a string or a table (e.g. <code>{ ipa = \"[ɽ]\" }</code> or <code>{ term = \"word\" }</code>).\n\n" ..
"Example (custom title and data column, IPA realizations):\n" ..
"<pre>\nlocal export = {}\n\nexport.title = \"Realization of 'strong R' between vowels\"\n" ..
"export.meaning = \"\"\nexport.note = \"realization of 'strong R' between vowels\"\n" ..
"export.last_column = \"Realization\"\n\nexport.syns = {\n\t[\"ALERS-158\"] = { { ipa = \"[ɽ]\" } },\n\t[\"ALERS-175\"] = { { ipa = \"[x]\" } },\n}\n\nreturn export\n</pre>\n\n",
expand_template({ title = 'dial syn', args = { lang_code, term } }))
end
end,
},
{
regex = "^Module:dialect synonyms/([%l-]+)/([^/]+)/([^/]+)$",
process = function(title, cats, lang_code, term, id)
local lang = lang_cache[lang_code]
if lang then
local langname = lang:getCanonicalName()
cats:insert("Dialect synonyms data modules|" .. langname)
cats:insert(langname .. " dialect synonyms data modules|" .. term)
return ("%s\n\n%s"):format(
"==== Term/sense module structure ====\n" ..
"* <code>export.title</code> — optional; custom table title (e.g. \"Realization of 'strong R' between vowels\"). Overrides the language default.\n" ..
"* <code>export.meaning</code> — optional; meaning/gloss (alternative to <code>gloss</code>).\n" ..
"* <code>export.gloss</code> — optional; short meaning for the table.\n" ..
"* <code>export.note</code> — optional; single note key or string, or list of note keys.\n" ..
"* <code>export.notes</code> — optional; list of note keys.\n" ..
"* <code>export.source</code> / <code>export.sources</code> — optional; source keys.\n" ..
"* <code>export.last_column</code> — optional; label for the data column (default \"Words\"; e.g. \"Realization\").\n" ..
"* <code>export.syns</code> — required; table mapping variety/location names (keys from the language data module) to a list of term entries. Each entry can be a string or a table (e.g. <code>{ ipa = \"[ɽ]\" }</code> or <code>{ term = \"word\" }</code>).\n\n" ..
"Example (custom title and data column, IPA realizations):\n" ..
"<pre>\nlocal export = {}\n\nexport.title = \"Realization of 'strong R' between vowels\"\n" ..
"export.meaning = \"\"\nexport.note = \"realization of 'strong R' between vowels\"\n" ..
"export.last_column = \"Realization\"\n\nexport.syns = {\n\t[\"ALERS-158\"] = { { ipa = \"[ɽ]\" } },\n\t[\"ALERS-175\"] = { { ipa = \"[x]\" } },\n}\n\nreturn export\n</pre>\n\n",
expand_template({ title = 'dial syn', args = { lang_code, term, id = id } }))
end
end
end,
end,
Line 607: Line 649:
page = lang_cache[lang_code]:getCanonicalName()
page = lang_cache[lang_code]:getCanonicalName()
if page then
if page then
cats:insert(page.." modules")
cats:insert(page .. " modules")
end
end
end
end
cats:insert("Reference modules")
cats:insert("Reference modules")
return "This module holds bibliographical data for "..page..". For the formatted bibliography see '''[[Appendix:Bibliography/"..page.."]]'''."
return "This module holds bibliographical data for " ..
page .. ". For the formatted bibliography see '''[[Appendix:Bibliography/" .. page .. "]]'''."
end,
end,
},
},
Line 617: Line 660:


function export.show(frame)
function export.show(frame)
local boolean_default_false = {type = "boolean", default = false}
local boolean_default_false = { type = "boolean", default = false }
local args = process_params(frame.args, {
local args = process_params(frame.args, {
["hr"] = true,
["hr"] = true,
Line 628: Line 671:
["nosandbox"] = boolean_default_false, -- supress sandbox
["nosandbox"] = boolean_default_false, -- supress sandbox
})
})
 
local output = Array('\n<div class="documentation" style="display:block; clear:both">\n')
local output = Array('\n<div class="documentation" style="display:block; clear:both">\n')
local cats = Array()
local cats = Array()
 
local nodoc = args.nodoc
local nodoc = args.nodoc
 
if (not args.hr) or (args.hr == "above") then
if (not args.hr) or (args.hr == "above") then
output:insert("----\n")
output:insert("----\n")
end
end
 
local title = args["for"] and new_title(args["for"]) or get_current_title()
local title = args["for"] and new_title(args["for"]) or get_current_title()
local doc_title = args.from ~= "-" and new_title(args.from or title.fullText .. '/documentation') or nil
local doc_title = args.from ~= "-" and new_title(args.from or title.fullText .. '/documentation') or nil
Line 646: Line 689:
local auto_generated_cat_source
local auto_generated_cat_source
local cats_auto_generated = false
local cats_auto_generated = false
 
if not args.allowondoc and is_documentation(title) then
if not args.allowondoc and is_documentation(title) then
-- TODO: merge with {{documentation subpage}}, and choose behaviour based on the page type.
-- TODO: merge with {{documentation subpage}}, and choose behaviour based on the page type.
Line 662: Line 705:
preload = "Template:documentation/preloadMediaWikiJavaScript"
preload = "Template:documentation/preloadMediaWikiJavaScript"
else
else
preload = "Template:documentation/preloadTemplate" -- XXX
preload = "Template:documentation/preloadTemplate" -- XXX
if title.nsText == "User" then
if title.nsText == "User" then
user_name = title.rootText
user_name = title.rootText
Line 669: Line 712:
is_script_or_stylesheet = true
is_script_or_stylesheet = true
elseif pagetype:match("%f[%w]stylesheet%f[%W]") then -- .css
elseif pagetype:match("%f[%w]stylesheet%f[%W]") then -- .css
preload = "Template:documentation/preloadTemplate" -- XXX
preload = "Template:documentation/preloadTemplate" -- XXX
if title.nsText == "User" then
if title.nsText == "User" then
user_name = title.rootText
user_name = title.rootText
Line 675: Line 718:
is_script_or_stylesheet = true
is_script_or_stylesheet = true
elseif contentModel == "Scribunto" then -- Exclude pages in Module: which aren't Scribunto.
elseif contentModel == "Scribunto" then -- Exclude pages in Module: which aren't Scribunto.
preload = "Template:documentation/preloadModule"
preload = "Template:documentation/preloadModule"
elseif pagetype:match("%f[%w]template%f[%W]") or pagetype:match("%f[%w]project%f[%W]") then
elseif pagetype:match("%f[%w]template%f[%W]") or pagetype:match("%f[%w]project%f[%W]") then
preload = "Template:documentation/preloadTemplate"
preload = "Template:documentation/preloadTemplate"
end
end


Line 692: Line 735:
if user_name then
if user_name then
fallback_docs = "documentation/fallback/user module"
fallback_docs = "documentation/fallback/user module"
automatic_cats = {"User sandbox modules"}
automatic_cats = { "User sandbox modules" }
else
else
for _, data in ipairs(module_regex) do
for _, data in ipairs(module_regex) do
local captures = {umatch(title.fullText, data.regex)}
local captures = { umatch(title.fullText, data.regex) }
if #captures > 0 then
if #captures > 0 then
local cat, process_function
local cat, process_function
Line 715: Line 758:
end
end
cat = data.cat
cat = data.cat
 
if cat then
if cat then
if type(cat) == "string" then
if type(cat) == "string" then
cat = {cat}
cat = { cat }
end
end
for _, c in ipairs(cat) do
for _, c in ipairs(cat) do
Line 738: Line 781:
end
end
end
end
 
if #cats == 0 then
if #cats == 0 then
local auto_cats = categorize_module(frame, "return raw", "noerror")
local auto_cats = categorize_module(frame, "return raw", "noerror")
Line 762: Line 805:
-- obvious typos that should be corrected.
-- obvious typos that should be corrected.
if doc_page_content:lower():match("</?includeonly%f[%s/>][^>]*>") then
if doc_page_content:lower():match("</?includeonly%f[%s/>][^>]*>") then
track("module-includeonly")
else
else
-- Check for uses of {{module cat}}. find_templates treats the
-- Check for uses of {{module cat}}. find_templates treats the
Line 777: Line 819:
get_module_doc_and_cats("categories only")
get_module_doc_and_cats("categories only")
auto_generated_cat_source = auto_generated_cat_source or doc_content_source
auto_generated_cat_source = auto_generated_cat_source or doc_content_source
cats_auto_generated_text = " Categories were auto-generated by [[" .. auto_generated_cat_source .. "]]. <sup>[[" ..
cats_auto_generated_text = " Categories were auto-generated by [[" ..
new_title(auto_generated_cat_source):fullUrl{action = "edit"} .. " edit]]</sup>"
auto_generated_cat_source .. "]]. <sup>[[" ..
new_title(auto_generated_cat_source):fullUrl { action = "edit" } .. " edit]]</sup>"
end
end
end
end
Line 785: Line 828:
output:insert(
output:insert(
"<dd><i style=\"font-size: larger;\">The following " ..
"<dd><i style=\"font-size: larger;\">The following " ..
"[[Help:Documenting templates and modules|documentation]] is located at [[" ..
"[[wikt:Help:Documenting templates and modules|documentation]] is located at [[" ..
doc_title.fullText .. "]]. " .. "<sup>[[" .. doc_title:fullUrl{action = "edit"} .. " edit]]</sup>" ..
doc_title.fullText .. "]]. " .. "<sup>[[" .. doc_title:fullUrl { action = "edit" } .. " edit]]</sup>" ..
cats_auto_generated_text .. "</i></dd>")
cats_auto_generated_text .. "</i></dd>")
else
else
Line 800: Line 843:
end
end
end
end
 
if doc_content then
if doc_content then
output:insert(
output:insert(
"<dd><i style=\"font-size: larger;\">The following " ..
"<dd><i style=\"font-size: larger;\">The following " ..
"[[Help:Documenting templates and modules|documentation]] is " ..
"[[wikt:Help:Documenting templates and modules|documentation]] is " ..
"generated by [[" .. doc_content_source .. "]]. <sup>[[" ..
"generated by [[" .. doc_content_source .. "]]. <sup>[[" ..
new_title(doc_content_source):fullUrl{action = "edit"} ..
new_title(doc_content_source):fullUrl { action = "edit" } ..
" edit]]</sup> </i></dd>")
" edit]]</sup> </i></dd>")
elseif not nodoc then
elseif not nodoc then
Line 812: Line 855:
output:insert(
output:insert(
"<dd><i style=\"font-size: larger;\">This " .. pagetype ..
"<dd><i style=\"font-size: larger;\">This " .. pagetype ..
" lacks a [[Help:Documenting templates and modules|documentation subpage]]. " ..
" lacks a [[wikt:Help:Documenting templates and modules|documentation subpage]]. " ..
(fallback_docs and "You may " or "Please ") ..
(fallback_docs and "You may " or "Please ") ..
"[" .. doc_title:fullUrl{action = "edit", preload = preload}
"[" .. doc_title:fullUrl { action = "edit", preload = preload }
.. " create it].</i></dd>\n")
.. " create it].</i></dd>\n")
else
else
output:insert(
output:insert(
"<dd><i style=\"font-size: larger; color: var(--wikt-palette-red-9,#FF0000);\">Unable to auto-generate " ..
"<dd><i style=\"font-size: larger; color: var(--wikt-palette-red-9,#FF0000);\">Unable to auto-generate " ..
"documentation for this " .. pagetype ..".</i></dd>\n")
"documentation for this " .. pagetype .. ".</i></dd>\n")
end
end
end
end
end
end
 
if startswith(title.fullText, "MediaWiki:Gadget-") then
if startswith(title.fullText, "MediaWiki:Gadget-") then
local is_gadget = false
local is_gadget = false
Line 840: Line 883:
output:insert(gadget)
output:insert(gadget)
output:insert("</code> gadget ([")
output:insert("</code> gadget ([")
output:insert(tostring(full_url("MediaWiki:Gadgets-definition", {action = "edit"})))
output:insert(tostring(full_url("MediaWiki:Gadgets-definition", { action = "edit" })))
output:insert(" edit definitions])'' <dl>")
output:insert(" edit definitions])'' <dl>")
 
output:insert("<dd> ''Description ([")
output:insert("<dd> ''Description ([")
output:insert(tostring(full_url("MediaWiki:Gadget-" .. gadget, {action = "edit"})))
output:insert(tostring(full_url("MediaWiki:Gadget-" .. gadget, { action = "edit" })))
output:insert(" edit])'': ")
output:insert(" edit])'': ")
 
output:insert(preprocess(new_message('Gadget-' .. gadget):plain()))
output:insert(preprocess(new_message('Gadget-' .. gadget):plain()))
output:insert(" </dd>")
output:insert(" </dd>")
Line 867: Line 910:
end
end
end
end
 
if not is_gadget then
if not is_gadget then
output:insert("<dd> ''This script is not a part of any [")
output:insert("<dd> ''This script is not a part of any [")
output:insert(tostring(full_url("Special:Gadgets", {uselang = "en"})))
output:insert(tostring(full_url("Special:Gadgets", { uselang = "en" })))
output:insert(' gadget] ([')
output:insert(' gadget] ([')
output:insert(tostring(full_url("MediaWiki:Gadgets-definition", {action = "edit"})))
output:insert(tostring(full_url("MediaWiki:Gadgets-definition", { action = "edit" })))
output:insert(' edit definitions]).</dd>')
output:insert(' edit definitions]).</dd>')
-- else
-- else
-- cats:insert("Wiktionary gadgets")
-- cats:insert("Wiktionary gadgets")
end
end
end
end
 
if old_doc_title then
if old_doc_title then
output:insert("<dd> ''Redirected from'' [")
output:insert("<dd> ''Redirected from'' [")
output:insert(old_doc_title:fullUrl{redirect = "no"})
output:insert(old_doc_title:fullUrl { redirect = "no" })
output:insert(" ")
output:insert(" ")
output:insert(old_doc_title.fullText)
output:insert(old_doc_title.fullText)
output:insert("] ([")
output:insert("] ([")
output:insert(old_doc_title:fullUrl{action = "edit"})
output:insert(old_doc_title:fullUrl { action = "edit" })
output:insert(" edit]).</dd>\n")
output:insert(" edit]).</dd>\n")
end
end
 
if not args.nolinks then
if not args.nolinks then
local links = Array()
local links = Array()


Line 898: Line 941:
links:insert("[[Special:PrefixIndex/" .. title.fullText .. "/|subpage list]]")
links:insert("[[Special:PrefixIndex/" .. title.fullText .. "/|subpage list]]")
end
end
 
links:insert(
links:insert(
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidetrans = true, hideredirs = true})) .. " links]")
"[" ..
tostring(full_url("Special:WhatLinksHere/" .. title.fullText, { hidetrans = true, hideredirs = true })) ..
" links]")
 
if contentModel ~= "Scribunto" then
if contentModel ~= "Scribunto" then
links:insert(
links:insert(
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidelinks = true, hidetrans = true})) .. " redirects]")
"[" ..
tostring(full_url("Special:WhatLinksHere/" .. title.fullText, { hidelinks = true, hidetrans = true })) ..
" redirects]")
end
end
 
if is_script_or_stylesheet then
if is_script_or_stylesheet then
if user_name then
if user_name then
Line 913: Line 960:
else
else
links:insert(
links:insert(
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidelinks = true, hideredirs = true})) .. " transclusions]")
"[" ..
tostring(full_url("Special:WhatLinksHere/" .. title.fullText, { hidelinks = true, hideredirs = true })) ..
" transclusions]")
end
end
 
if contentModel == "Scribunto" then
if contentModel == "Scribunto" then
local is_testcases = title.isSubpage and title.subpageText == "testcases"
local is_testcases = title.isSubpage and title.subpageText == "testcases"
Line 924: Line 973:
links:insert("[[" .. title.fullText .. "/testcases|testcases]]")
links:insert("[[" .. title.fullText .. "/testcases|testcases]]")
end
end
 
if user_name then
if user_name then
links:insert("[[User:" .. user_name .. "|user page]]")
links:insert("[[User:" .. user_name .. "|user page]]")
links:insert("[[User talk:" .. user_name .. "|user talk page]]")
links:insert("[[User talk:" .. user_name .. "|user talk page]]")
links:insert("[[Special:PrefixIndex/User:" .. user_name .. "/|userspace]]")
links:insert("[[Special:PrefixIndex/User:" .. user_name .. "/|userspace]]")
-- If sandbox module, add a link to the module that this is a sandbox of.
-- If sandbox module, add a link to the module that this is a sandbox of.
-- Exclude user sandbox modules like [[User:Dine2016/sandbox]].
-- Exclude user sandbox modules like [[User:Dine2016/sandbox]].
elseif title.text:find("/sandbox%d*%f[/%z]") then
elseif title.text:find("^sandbox%d*/") or title.text:find("/sandbox%d*%f[/%z]") then
cats:insert("Sandbox modules")
cats:insert("Sandbox modules")
 
-- Sandbox modules don’t really need documentation.
-- Sandbox modules don’t really need documentation.
needs_doc = false
needs_doc = false
 
-- Don't track user sandbox modules.
-- Don't track user sandbox modules.
local text_title = new_title(title.text)
local text_title = new_title(title.text)
if not (text_title and text_title.namespace == 2) then
if not (text_title and text_title.nsText == "User") then
track("sandbox to be moved")
local diff
local sandbox_of = title.text:match("^(.*)/sandbox%d*%f[/%z]")
local sandbox_of, diff = title.baseText
if sandbox_of then
else
sandbox_of = title.text:match("^sandbox%d*/(.*)$")
end
if not sandbox_of then
error(("Internal error: Something wrong, couldn't extract sandbox-of module from title '%s'")
:format(title.text))
end
sandbox_of = title.nsText .. ":" .. sandbox_of
if title_exists(sandbox_of) then
if title_exists(sandbox_of) then
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")"
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")"
else
track("no sandbox of")
end
end
 
links:insert("[[:" .. sandbox_of .. "|sandbox of]]" .. (diff or ""))
links:insert("[[:" .. sandbox_of .. "|sandbox of]]" .. (diff or ""))
end
end
-- If not a sandbox module, add link to sandbox module.
-- If not a sandbox module, add link to sandbox module.
-- Sometimes there are multiple sandboxes for a single module:
-- Sometimes there are multiple sandboxes for a single module:
-- [[Module:sa-pronunc/sandbox]],  [[Module:sa-pronunc/sandbox2]].
-- [[Module:sandbox/sa-pronunc]],  [[Module:sandbox2/sa-pronunc]].
-- Occasionally sandbox modules have their own subpages that are also
-- sandboxes: [[Module:grc-decl/sandbox/decl]].
else
else
local sandbox_title
local sandbox_title
if title.rootText == "grc-decl" then
local user_prefix, user_rest = title.text:match("^(User:.-/)(.*)$")
sandbox_title = string_insert(title.fullText, 16, "/sandbox")
if not user_prefix then
elseif is_testcases then
user_prefix = ""
sandbox_title = title.fullText:gsub("/testcases", "/sandbox/testcases")
user_rest = title.text
else
sandbox_title = title.fullText .. "/sandbox"
end
end
sandbox_title = title.nsText .. ":" .. user_prefix .. "sandbox/" .. user_rest
local sandbox_link = "[[:" .. sandbox_title .. "|sandbox]]"
local sandbox_link = "[[:" .. sandbox_title .. "|sandbox]]"
 
local diff
local diff
if title_exists(sandbox_title) then
if title_exists(sandbox_title) then
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")"
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")"
end
end
 
links:insert(sandbox_link .. (diff or ""))
links:insert(sandbox_link .. (diff or ""))
end
end
end
end
 
if title.nsText == "Template" then
if title.nsText == "Template" then
-- Error search: all(any namespace), hastemplate (show pages using the template), insource (show source code), incategory (any/specific error) -- [[mw:Help:CirrusSearch]], [[w:Help:Searching/Regex]]
-- Error search: all(any namespace), hastemplate (show pages using the template), insource (show source code), incategory (any/specific error) -- [[mw:Help:CirrusSearch]], [[w:Help:Searching/Regex]]
-- apparently same with/without: &profile=advanced&fulltext=1
-- apparently same with/without: &profile=advanced&fulltext=1
local errorq = 'searchengineselect=mediawiki&search=all: hastemplate:\"'..title.rootText..'\" insource:\"'..title.rootText..'\" incategory:'
local errorq = 'searchengineselect=mediawiki&search=all: hastemplate:\"' ..
local eincategory = "Pages_with_module_errors|ParserFunction_errors|DisplayTitle_errors|Pages_with_ISBN_errors|Pages_with_ISSN_errors|Pages_with_reference_errors|Pages_with_syntax_highlighting_errors|Pages_with_TemplateStyles_errors"
title.rootText .. '\" insource:\"' .. title.rootText .. '\" incategory:'
local eincategory =
"Pages_with_module_errors|ParserFunction_errors|DisplayTitle_errors|Pages_with_ISBN_errors|Pages_with_ISSN_errors|Pages_with_reference_errors|Pages_with_syntax_highlighting_errors|Pages_with_TemplateStyles_errors"
 
links:insert(
links:insert(
'[' .. tostring(full_url('Special:Search', errorq..eincategory )) .. ' errors]'
'[' .. tostring(full_url('Special:Search', errorq .. eincategory)) .. ' errors]'
.. ' (' ..
.. ' (' ..
'[' .. tostring(full_url('Special:Search', errorq..'ParserFunction_errors' )) .. ' parser]'
'[' .. tostring(full_url('Special:Search', errorq .. 'ParserFunction_errors')) .. ' parser]'
.. '/' ..
.. '/' ..
'[' .. tostring(full_url('Special:Search', errorq..'Pages_with_module_errors' )) .. ' module]'
'[' .. tostring(full_url('Special:Search', errorq .. 'Pages_with_module_errors')) .. ' module]'
.. ')'
.. ')'
)
)
 
if title.isSubpage and title.text:find("/sandbox%d*%f[/%z]") then -- This is a sandbox template.
if title.isSubpage and title.text:find("/sandbox%d*%f[/%z]") then -- This is a sandbox template.
-- At the moment there are no user sandbox templates with subpage
-- At the moment there are no user sandbox templates with subpage
-- “/sandbox”.
-- “/sandbox”.
cats:insert("Sandbox templates")
cats:insert("Sandbox templates")
 
-- Sandbox templates don’t really need documentation.
-- Sandbox templates don’t really need documentation.
needs_doc = false
needs_doc = false
 
-- Will behave badly if “/sandbox” occurs twice in title!
-- Will behave badly if “/sandbox” occurs twice in title!
local sandbox_of = title.fullText:gsub("/sandbox%d*%f[/%z]", "")
local sandbox_of = title.fullText:gsub("/sandbox%d*%f[/%z]", "")
 
local diff
local diff
if title_exists(sandbox_of) then
if title_exists(sandbox_of) then
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")"
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")"
else
track("no sandbox of")
end
end
 
links:insert("[[:" .. sandbox_of .. "|sandbox of]]" .. (diff or ""))
links:insert("[[:" .. sandbox_of .. "|sandbox of]]" .. (diff or ""))
-- This is a template that can have a sandbox.
-- This is a template that can have a sandbox.
elseif not args.nosandbox then -- unless we tell it not to
elseif not args.nosandbox then -- unless we tell it not to
local sandbox_title = title.fullText .. "/sandbox"
local sandbox_title = title.fullText .. "/sandbox"
 
local diff
local diff
if title_exists(sandbox_title) then
if title_exists(sandbox_title) then
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")"
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")"
end
end
 
links:insert("[[:" .. sandbox_title .. "|sandbox]]" .. (diff or ""))
links:insert("[[:" .. sandbox_title .. "|sandbox]]" .. (diff or ""))
end
end
end
end
 
if #links > 0 then
if #links > 0 then
output:insert("<dd> ''Useful links'': " .. links:concat(" • ") .. "</dd>")
output:insert("<dd> ''Useful links'': " .. links:concat(" • ") .. "</dd>")
end
end
end
end
 
output:insert("</dl>\n")
output:insert("</dl>\n")
 
-- Show error from [[Module:category tree/topic cat/data]] on its submodules'
-- Show error from [[Module:category tree/topic cat/data]] on its submodules'
-- documentation to, for instance, warn about duplicate labels.
-- documentation to, for instance, warn about duplicate labels.
Line 1,038: Line 1,090:
end
end
end
end
 
if doc_title and doc_title.exists then
if doc_title and doc_title.exists then
-- Override automatic documentation, if present.
-- Override automatic documentation, if present.
doc_content = expand_template{ title = doc_title.fullText }
doc_content = expand_template { title = doc_title.fullText }
elseif not doc_content and fallback_docs then
elseif not doc_content and fallback_docs then
doc_content = expand_template{
doc_content = expand_template {
title = fallback_docs,
title = fallback_docs,
args = {
args = {
Line 1,057: Line 1,109:
end
end


output:insert(('\n<%s style="clear: both;" />'):format(args.hr == "below" and "hr" or "span"))
output:insert(('\n<%s style="clear: both;" />'):format(args.hr == "below" and "hr" or "br"))
 
if cats_auto_generated and not cats[1] and (not doc_content or not doc_content:find("%[%[Category:")) then
if cats_auto_generated and not cats[1] and (not doc_content or not doc_content:find("%[%[Category:")) then
if contentModel == "Scribunto" then
if contentModel == "Scribunto" then
cats:insert("Uncategorized modules")
cats:insert("Uncategorized modules")
-- elseif title.nsText == "Template" then
-- elseif title.nsText == "Template" then
-- cats:insert("Uncategorized templates")
-- cats:insert("Uncategorized templates")
end
end
end
end
 
if needs_doc then
if needs_doc then
cats:insert("Templates and modules needing documentation")
cats:insert("Templates and modules needing documentation")
end
end
 
for _, cat in ipairs(cats) do
for _, cat in ipairs(cats) do
output:insert("[[Category:" .. cat .. "]]")
output:insert("[[Category:" .. cat .. "]]")
end
end
 
output:insert("</div>\n")
output:insert("</div>\n")


Line 1,093: Line 1,145:
local cat_parts = {}
local cat_parts = {}
if type(cats) == "string" then
if type(cats) == "string" then
cats = {cats}
cats = { cats }
end
end
for _, cat in ipairs(cats) do
for _, cat in ipairs(cats) do
Line 1,115: Line 1,167:
function export.translitModuleLangList(frame)
function export.translitModuleLangList(frame)
local pagename, subpage
local pagename, subpage
 
if frame.args[1] then
if frame.args[1] then
pagename = frame.args[1]
pagename = frame.args[1]
Line 1,122: Line 1,174:
subpage = title.subpageText
subpage = title.subpageText
pagename = title.text
pagename = title.text
 
if subpage ~= pagename then
if subpage ~= pagename then
pagename = title.rootText
pagename = title.rootText
end
end
end
end
 
local translitModule = pagename
local translitModule = pagename
 
local languageObjects = require("Module:languages/byTranslitModule")(translitModule)
local languageObjects = require("Module:languages/byTranslitModule")(translitModule)
local codeInPagename = pagename:match("^([%l-]+)%-.*translit$")
local codeInPagename = pagename:match("^([%l-]+)%-.*translit$")
 
local categories = Array()
local categories = Array()
local codeInPagenameInList = false
local codeInPagenameInList = false
Line 1,141: Line 1,193:
#languageObjects .. " language" .. agreement .. "]]")
#languageObjects .. " language" .. agreement .. "]]")
end
end
 
languageObjects = Array(languageObjects)
languageObjects = Array(languageObjects)
:filter(
:filter(
function (lang)
function(lang)
local result = lang:getCode() ~= codeInPagename
local result = lang:getCode() ~= codeInPagename
codeInPagenameInList = codeInPagenameInList or result
codeInPagenameInList = codeInPagenameInList or result
Line 1,150: Line 1,202:
end)
end)
end
end
 
if subpage ~= "documentation" then
if subpage ~= "documentation" then
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
Line 1,159: Line 1,211:
end
end
end
end
 
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
categories:insert("[[Category:Transliteration modules without a testcases subpage]]")
categories:insert("[[Category:Transliteration modules without a testcases subpage]]")
end
end
 
if not languageObjects[1] then
if not languageObjects[1] then
return categories:concat()
return categories:concat()
end
end
 
local langs = Array(languageObjects)
local langs = Array(languageObjects)
:sort(
:sort(
Line 1,176: Line 1,228:
:map(languageObjects[1].makeCategoryLink)
:map(languageObjects[1].makeCategoryLink)
:serialCommaJoin()
:serialCommaJoin()
 
return "It is " .. ( codeInPagenameInList and "also" or "" ) ..
return "It is " .. (codeInPagenameInList and "also" or "") ..
" used to transliterate " .. langs .. "." .. categories:concat()
" used to transliterate " .. langs .. "." .. categories:concat()
end
end


-- Used by {{entry name module documentation}}.
-- Used by {{strip diacritics module documentation}}.
function export.entryNameModuleLangList(frame)
function export.stripDiacriticsModuleLangList(frame)
local pagename, subpage
local pagename, subpage
 
if frame.args[1] then
if frame.args[1] then
pagename = frame.args[1]
pagename = frame.args[1]
Line 1,191: Line 1,243:
subpage = title.subpageText
subpage = title.subpageText
pagename = title.text
pagename = title.text
 
if subpage ~= pagename then
if subpage ~= pagename then
pagename = title.rootText
pagename = title.rootText
end
end
end
end
 
local entryNameModule = pagename
local stripDiacriticsModule = pagename
 
local languageObjects = require("Module:languages/byEntryNameModule")(entryNameModule)
local languageObjects = require("Module:languages/byStripDiacriticsModule")(stripDiacriticsModule)
local codeInPagename = pagename:match("^([%l-]+)%-.*entryname$")
local codeInPagename = pagename:match("^([%l-]+)%-.*stripdiacritics$")
 
local categories = Array()
local categories = Array()
local codeInPagenameInList = false
local codeInPagenameInList = false
Line 1,207: Line 1,259:
if languageObjects[1] and subpage ~= "documentation" then
if languageObjects[1] and subpage ~= "documentation" then
local agreement = languageObjects[2] and "s" or ""
local agreement = languageObjects[2] and "s" or ""
categories:insert("[[Category:Entry name-generating modules used by " ..
categories:insert("[[Category:Diacritic-stripping modules used by " ..
#languageObjects .. " language" .. agreement .. "]]")
#languageObjects .. " language" .. agreement .. "]]")
end
end
 
languageObjects = Array(languageObjects)
languageObjects = Array(languageObjects)
:filter(
:filter(
function (lang)
function(lang)
local result = lang:getCode() ~= codeInPagename
local result = lang:getCode() ~= codeInPagename
codeInPagenameInList = codeInPagenameInList or result
codeInPagenameInList = codeInPagenameInList or result
Line 1,219: Line 1,271:
end)
end)
end
end
 
if subpage ~= "documentation" then
if subpage ~= "documentation" then
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
Line 1,228: Line 1,280:
end
end
end
end
 
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
categories:insert("[[Category:Entry name-generating modules without a testcases subpage]]")
categories:insert("[[Category:Diacritic-stripping modules without a testcases subpage]]")
end
end
 
if not languageObjects[1] then
if not languageObjects[1] then
return categories:concat()
return categories:concat()
end
end
 
local langs = Array(languageObjects)
local langs = Array(languageObjects)
:sort(
:sort(
Line 1,245: Line 1,297:
:map(languageObjects[1].makeCategoryLink)
:map(languageObjects[1].makeCategoryLink)
:serialCommaJoin()
:serialCommaJoin()
 
return "It is " .. ( codeInPagenameInList and "also" or "" ) ..
return "It is " .. (codeInPagenameInList and "also" or "") ..
" used to generate entry names for " .. langs .. "." .. categories:concat()
" used to strip diacritics for " .. langs .. "." .. categories:concat()
end
end


Line 1,253: Line 1,305:
function export.sortkeyModuleLangList(frame)
function export.sortkeyModuleLangList(frame)
local pagename, subpage
local pagename, subpage
 
if frame.args[1] then
if frame.args[1] then
pagename = frame.args[1]
pagename = frame.args[1]
Line 1,260: Line 1,312:
subpage = title.subpageText
subpage = title.subpageText
pagename = title.text
pagename = title.text
 
if subpage ~= pagename then
if subpage ~= pagename then
pagename = title.rootText
pagename = title.rootText
end
end
end
end
 
local sortkeyModule = pagename
local sortkeyModule = pagename
 
local languageObjects = require("Module:languages/bySortkeyModule")(sortkeyModule)
local languageObjects = require("Module:languages/bySortkeyModule")(sortkeyModule)
local codeInPagename = pagename:match("^([%l-]+)%-.*sortkey$")
local codeInPagename = pagename:match("^([%l-]+)%-.*sortkey$")
 
local categories = Array()
local categories = Array()
local codeInPagenameInList = false
local codeInPagenameInList = false
Line 1,279: Line 1,331:
#languageObjects .. " language" .. agreement .. "]]")
#languageObjects .. " language" .. agreement .. "]]")
end
end
 
languageObjects = Array(languageObjects)
languageObjects = Array(languageObjects)
:filter(
:filter(
function (lang)
function(lang)
local result = lang:getCode() ~= codeInPagename
local result = lang:getCode() ~= codeInPagename
codeInPagenameInList = codeInPagenameInList or result
codeInPagenameInList = codeInPagenameInList or result
Line 1,288: Line 1,340:
end)
end)
end
end
 
if subpage ~= "documentation" then
if subpage ~= "documentation" then
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do
Line 1,297: Line 1,349:
end
end
end
end
 
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then
categories:insert("[[Category:Sortkey-generating modules without a testcases subpage]]")
categories:insert("[[Category:Sortkey-generating modules without a testcases subpage]]")
end
end
 
if not languageObjects[1] then
if not languageObjects[1] then
return categories:concat()
return categories:concat()
end
end
 
local langs = Array(languageObjects)
local langs = Array(languageObjects)
:sort(
:sort(
Line 1,314: Line 1,366:
:map(languageObjects[1].makeCategoryLink)
:map(languageObjects[1].makeCategoryLink)
:serialCommaJoin()
:serialCommaJoin()
 
return "It is " .. ( codeInPagenameInList and "also" or "" ) ..
return "It is " .. (codeInPagenameInList and "also" or "") ..
" used to sort " .. langs .. "." .. categories:concat()
" used to sort " .. langs .. "." .. categories:concat()
end
end


return export
return export