48,355
edits
Tag: Undo |
m (1 revision imported) |
||
| (5 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
local export = {} | local export = {} | ||
-- | local array_module = "Module:array" | ||
function | local debug_track_module = "Module:debug/track" | ||
return | local frame_module = "Module:frame" | ||
local fun_is_callable_module = "Module:fun/isCallable" | |||
local languages_module = "Module:languages" | |||
local links_module = "Module:links" | |||
local load_module = "Module:load" | |||
local module_categorization_module = "Module:module categorization" | |||
local number_list_show_module = "Module:number list/show" | |||
local pages_module = "Module:pages" | |||
local parameters_module = "Module:parameters" | |||
local scripts_module = "Module:scripts" | |||
local string_endswith_module = "Module:string/endswith" | |||
local string_gline_module = "Module:string/gline" | |||
local string_insert_module = "Module:string/insert" | |||
local string_startswith_module = "Module:string/startswith" | |||
local string_utilities_module = "Module:string utilities" | |||
local template_parser_module = "Module:template parser" | |||
local title_exists_module = "Module:title/exists" | |||
local title_new_title_module = "Module:title/newTitle" | |||
local concat = table.concat | |||
local error = error | |||
local full_url = mw.uri.fullUrl | |||
local get_current_title = mw.title.getCurrentTitle | |||
local insert = table.insert | |||
local ipairs = ipairs | |||
local list_to_text = mw.text.listToText | |||
local new_message = mw.message.new | |||
local pcall = pcall | |||
local require = require | |||
local tonumber = tonumber | |||
local tostring = tostring | |||
local type = type | |||
local unpack = unpack or table.unpack -- Lua 5.2 compatibility | |||
local function Array(...) | |||
Array = require(array_module) | |||
return Array(...) | |||
end | |||
local function categorize_module(...) | |||
categorize_module = require(module_categorization_module).categorize | |||
return categorize_module(...) | |||
end | |||
local function debug_track(...) | |||
debug_track = require(debug_track_module) | |||
return debug_track(...) | |||
end | |||
local function endswith(...) | |||
endswith = require(string_endswith_module) | |||
return endswith(...) | |||
end | |||
local function expand_template(...) | |||
expand_template = require(frame_module).expandTemplate | |||
return expand_template(...) | |||
end | |||
local function find_templates(...) | |||
find_templates = require(template_parser_module).find_templates | |||
return find_templates(...) | |||
end | |||
local function full_link(...) | |||
full_link = require(links_module).full_link | |||
return full_link(...) | |||
end | |||
local function get_lang(...) | |||
get_lang = require(languages_module).getByCode | |||
return get_lang(...) | |||
end | |||
local function get_pagetype(...) | |||
get_pagetype = require(pages_module).get_pagetype | |||
return get_pagetype(...) | |||
end | |||
local function get_script(...) | |||
get_script = require(scripts_module).getByCode | |||
return get_script(...) | |||
end | |||
local function gline(...) | |||
gline = require(string_gline_module) | |||
return gline(...) | |||
end | |||
local function is_callable(...) | |||
is_callable = require(fun_is_callable_module) | |||
return is_callable(...) | |||
end | |||
local function is_documentation(...) | |||
is_documentation = require(pages_module).is_documentation | |||
return is_documentation(...) | |||
end | |||
local function is_sandbox(...) | |||
is_sandbox = require(pages_module).is_sandbox | |||
return is_sandbox(...) | |||
end | |||
local function new_title(...) | |||
new_title = require(title_new_title_module) | |||
return new_title(...) | |||
end | |||
local function number_list_show_table(...) | |||
number_list_show_table = require(number_list_show_module).table | |||
return number_list_show_table(...) | |||
end | |||
local function preprocess(...) | |||
preprocess = require(frame_module).preprocess | |||
return preprocess(...) | |||
end | |||
local function process_params(...) | |||
process_params = require(parameters_module).process | |||
return process_params(...) | |||
end | |||
local function safe_load_data(...) | |||
safe_load_data = require(load_module).safe_load_data | |||
return safe_load_data(...) | |||
end | |||
local function split(...) | |||
split = require(string_utilities_module).split | |||
return split(...) | |||
end | |||
local function startswith(...) | |||
startswith = require(string_startswith_module) | |||
return startswith(...) | |||
end | |||
local function string_insert(...) | |||
string_insert = require(string_insert_module) | |||
return string_insert(...) | |||
end | |||
local function title_exists(...) | |||
title_exists = require(title_exists_module) | |||
return title_exists(...) | |||
end | |||
local function ugsub(...) | |||
ugsub = require(string_utilities_module).gsub | |||
return ugsub(...) | |||
end | |||
local function umatch(...) | |||
umatch = require(string_utilities_module).match | |||
return umatch(...) | |||
end | end | ||
| Line 14: | Line 170: | ||
} | } | ||
local | 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})) | |||
.. " " .. 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({}, { __index = function (self, k) | ||
return require "Module:languages/cache"[k] | return require("Module:languages/cache")[k] | ||
end }) | end }) | ||
local function zh_link(word) | local function zh_link(word) | ||
return | return full_link{ | ||
lang = lang_cache.zh, | lang = lang_cache.zh, | ||
term = word | term = word | ||
} | |||
end | |||
local function make_languages_data_documentation(title, cats, division) | |||
local doc_template, module_cat | |||
if endswith(division, "/extra") then | |||
division = division:sub(1, -7) | |||
doc_template = "language extradata documentation" | |||
module_cat = "Language extra data modules" | |||
else | |||
doc_template = "language data documentation" | |||
module_cat = "Language data modules" | |||
end | |||
local sort_key | |||
if division == "exceptional" then | |||
sort_key = "x" | |||
else | |||
sort_key = division:gsub("/", "") | |||
end | |||
cats:insert(module_cat .. "|" .. sort_key) | |||
return { | |||
title = doc_template | |||
} | } | ||
end | end | ||
| Line 42: | Line 218: | ||
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" then | if subpage == "names" or subpage == "images" or subpage == "emoji images" then | ||
local low, high = | local low, high = | ||
tonumber(first_three_of_code_point .. "000", 16), | tonumber(first_three_of_code_point .. "000", 16), | ||
tonumber(first_three_of_code_point .. "FFF", 16) | tonumber(first_three_of_code_point .. "FFF", 16) | ||
local text, text_type | |||
"This data module contains the | if subpage == "names" then | ||
text_type = "titles of images" | |||
elseif subpage == "images" then | |||
text_type = "titles of images" | |||
elseif subpage == "emoji images" then | |||
text_type = "emoji-style images" | |||
end | |||
text = string.format( | |||
"This data module contains the " .. text_type .. " of " .. | |||
"[[Appendix:Unicode|Unicode]] code points within the range U+%04X to U+%04X.", | "[[Appendix:Unicode|Unicode]] code points within the range U+%04X to U+%04X.", | ||
low, high) | low, high) | ||
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 .. "]]." | |||
elseif subpage == "emoji images" then | |||
text = text .. " For text-style images, see [[Module:Unicode data/images/" .. first_three_of_code_point .. "]]." | |||
end | |||
return text | |||
end | end | ||
end | end | ||
-- This provides categories and documentation for various data modules, so that | local function insert_lang_data_module_cats(cats, langcode, overall_data_module_cat) | ||
local lang = lang_cache[langcode] | |||
if lang then | |||
local langname | |||
if lang._fullCode then | |||
langname = lang_cache[lang._fullCode]:getCanonicalName() | |||
else | |||
langname = lang:getCanonicalName() | |||
end | |||
cats:insert(overall_data_module_cat .. "|" .. langname) | |||
cats:insert(langname .. " modules") | |||
cats:insert(langname .. " data modules") | |||
return lang, langname | |||
end | |||
end | |||
--[=[ | |||
This provides categories and documentation for various data modules, so that [[Category:Uncategorized modules]] isn't | |||
unnecessarily cluttered. It is a list of tables, each of which have the following possible fields: | |||
`regex` (required): A Lua pattern to match the module's title. If it matches, the data in this entry will be used. | |||
Any captures in the pattern can by referenced in the `cat` field using %1 for the first capture, %2 for the | |||
second, etc. (often used for creating the sortkey for the category). In addition, the captures are passed to the | |||
`process` function as the third and subsequent parameters. | |||
`process` (optional): This may be a function or a string. If it is a function, it is called as follows: | |||
`process(TITLE, CATS, CAPTURE1, CAPTURE2, ...)` | |||
where: | |||
* TITLE is a title object describing the module's title; see | |||
[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. | |||
* CAPTURE1, CAPTURE2, ... contain any captures in the `regex` field. | |||
The return value of `process` should either be a string (which will be used as the module's documentation), or a | |||
table specifying the name of a template to expand to get the documentation, along with the arguments to that | |||
template. In the latter format, the template name (bare, without the "Template:" prefix) should be in the `title` | |||
field, and any arguments should be in `args; in this case, the template name will be listed above the generated | |||
documentation as the source of the documentation, along with an edit button to edit the template's contents. | |||
If, however, the return value of the `process` function is a string, any template invocations will be expanded | |||
using frame:preprocess(), and [[Module:documentation]] will be listed as the source of the documentation. | |||
If `process` itself is a string rather than a function, it should name a submodule under | |||
[[Module:documentation/functions/]] which returns a function, of the same type as described above. This submodule | |||
will be specified as the source of the documentation (unless it returns a table naming a template to expand to get | |||
the documentation, as described above). | |||
If `process` is omitted entirely, the module will have no documentation. | |||
`cat` (optional): A string naming the category into which the module should be placed, or a list of such strings. | |||
Captures specified in `regex` may be referenced in this string using %1 for the first capture, %2 for the second, | |||
etc. It is also possible to add categories in the `process` function by inserting them into the passed-in CATS | |||
array (the second parameter). | |||
]=] | |||
local module_regex = { | local module_regex = { | ||
{ | |||
regex = "^Module:languages/data/(3/%l/extra)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | |||
regex = "^Module:languages/data/(3/%l)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | |||
regex = "^Module:languages/data/(2/extra)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | |||
regex = "^Module:languages/data/(2)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | |||
regex = "^Module:languages/data/(exceptional/extra)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | |||
regex = "^Module:languages/data/(exceptional)$", | |||
process = make_languages_data_documentation, | |||
}, | |||
{ | { | ||
regex = "^Module:languages/.+$", | regex = "^Module:languages/.+$", | ||
| Line 90: | Line 332: | ||
regex = "^Module:data tables/data..?.?.?$", | regex = "^Module:data tables/data..?.?.?$", | ||
cat = "Reference module sharded data tables", | cat = "Reference module sharded data tables", | ||
}, | }, | ||
{ | { | ||
| Line 102: | Line 340: | ||
{ | { | ||
regex = "^Module:zh/data/dial%-syn/.+$", | regex = "^Module:zh/data/dial%-syn/.+$", | ||
cat = "Chinese | cat = "Chinese dialect synonyms data modules", | ||
process = "zh dial or syn", | process = "zh dial or syn", | ||
}, | }, | ||
| Line 147: | Line 385: | ||
{ | { | ||
regex = "^Module:number list/data/(.+)$", | regex = "^Module:number list/data/(.+)$", | ||
process = " | process = function(title, cats, lang_code) | ||
local lang = insert_lang_data_module_cats(cats, lang_code, "Number data modules") | |||
if lang then | |||
return ("This module contains data on various types of numbers in %s.\n%s") | |||
:format(lang:makeCategoryLink(), number_list_show_table() or "") | |||
end | |||
end, | |||
}, | }, | ||
{ | { | ||
| Line 170: | Line 414: | ||
local lang = lang_cache["inc-ash"] | local lang = lang_cache["inc-ash"] | ||
return ("This module contains data on the pronunciation of %s in dialects of %s.") | return ("This module contains data on the pronunciation of %s in dialects of %s.") | ||
:format( | :format(full_link({ term = word, lang = lang }, "term"), | ||
lang:makeCategoryLink()) | lang:makeCategoryLink()) | ||
end | end | ||
| Line 176: | Line 420: | ||
}, | }, | ||
{ | { | ||
regex = "^Module: | regex = "^.+%-translit$", | ||
process = function(title, cats) | process = "translit", | ||
local | }, | ||
{ | |||
regex = "^Module:form of/lang%-data/(.+)$", | |||
process = function(title, cats, lang_code) | |||
local lang, langname = insert_lang_data_module_cats(cats, lang_code, "Language-specific form-of modules") | |||
if lang then | |||
end | -- FIXME, display more info. | ||
return "This module contains language-specific form-of data (tags, shortcuts, base lemma params. etc.) for " .. | |||
langname .. "." | |||
end | |||
end | |||
}, | }, | ||
{ | { | ||
regex = "^.+ | regex = "^Module:labels/data/lang/(.+)$", | ||
process = " | process = function(title, cats, lang_code) | ||
local lang = insert_lang_data_module_cats(cats, lang_code, "Language-specific label data modules") | |||
if lang then | |||
return { | |||
title = "label language-specific data documentation", | |||
args = { [1] = lang_code }, | |||
} | |||
end | |||
end | |||
}, | }, | ||
{ | { | ||
regex = "^Module:category tree | regex = "^Module:category tree/lang/(.+)$", | ||
process = function(title, cats, lang_code) | process = function(title, cats, lang_code) | ||
local 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]]. " | ||
.. "This module is part of the | .. "This module is part of the category tree system, which is a general framework for generating the " | ||
.. "descriptions and categorization of category pages.\n\n" | .. "descriptions and categorization of category pages.\n\n" | ||
.. "For more information, see [[Module:category tree/ | .. "For more information, see [[Module:category tree/lang/documentation]].\n\n" | ||
.. "'''NOTE:''' If you add a new language-specific module, you must add the language code to the " | |||
.. "list at the top of [[Module:category tree/lang]] in order for the module to be recognized." | |||
end | end | ||
end | end | ||
}, | }, | ||
{ | { | ||
regex = "^Module:category tree/ | regex = "^Module:category tree/topic/(.+)$", | ||
process = function(title, cats, submodule) | |||
cats:insert("Category tree data modules/topic| ") | |||
return { | |||
title = "topic cat data submodule documentation" | |||
} | |||
end | |||
}, | |||
{ | |||
regex = "^Module:category tree/(.+)$", | |||
process = function(title, cats, submodule) | |||
cats:insert("Category tree data modules| ") | |||
return { | |||
title = "category tree data submodule documentation" | |||
} | |||
end | |||
}, | }, | ||
{ | { | ||
| Line 217: | Line 485: | ||
}, | }, | ||
{ | { | ||
regex = "^Module:Swadesh/data/(.+)$", | regex = "^Module:fi%-dialects/data/feature/Kettunen1940 ([0-9]+)$", | ||
cat = "Finnish dialectal data atlas modules|%1", | |||
process = function(title, cats, shard) | |||
return "This module contains shard " .. shard .. " of the online version of Lauri Kettunen's 1940 work " .. | |||
"''Suomen murteet III A. Murrekartasto'' (\"Finnish dialects III A: Dialect atlas\"). " .. | |||
"It was imported and converted from urn:nbn:fi:csc-kata20151130145346403821, published by the " .. | |||
"''Kotimaisten kielten keskus'' under the CC BY 4.0 license." | |||
end | |||
}, | |||
{ | |||
regex = "^Module:fi%-dialects/data/feature/(.+)", | |||
cat = "Finnish dialectal data modules|%1", | |||
}, | |||
{ | |||
regex = "^Module:fi%-dialects/data/word/(.+)", | |||
cat = "Finnish dialectal data modules|%1", | |||
}, | |||
{ | |||
regex = "^Module:Swadesh/data/([%l-]+)$", | |||
process = function(title, cats, lang_code) | |||
local lang, langname = insert_lang_data_module_cats(cats, lang_code, "Swadesh modules") | |||
if lang then | |||
return "This module contains the [[Swadesh list]] of basic vocabulary in " .. langname .. "." | |||
end | |||
end | |||
}, | |||
{ | |||
regex = "^Module:Swadesh/data/([%l-]+)/([^/]*)$", | |||
process = function(title, cats, lang_code, variety) | |||
local lang, langname = insert_lang_data_module_cats(cats, lang_code, "Swadesh modules") | |||
if lang then | |||
local prefix = "This module contains the [[Swadesh list]] of basic vocabulary in the " | |||
local etym_lang = get_lang(variety, nil, "allow etym") | |||
if etym_lang then | |||
return ("%s %s variety of %s."):format(prefix, etym_lang:getCanonicalName(), langname) | |||
end | |||
local script = get_script(variety) | |||
if script then | |||
return ("%s %s %s script."):format(prefix, langname, script:getCanonicalName()) | |||
end | |||
return ("%s %s variety of %s."):format(prefix, variety, langname) | |||
end | |||
end | |||
}, | }, | ||
{ | { | ||
| Line 224: | Line 533: | ||
process = function(title, cats) | process = function(title, cats) | ||
local data_suffix = title.fullText:match("^Module:typing%-aids/data/(.+)$") | local data_suffix = title.fullText:match("^Module:typing%-aids/data/(.+)$") | ||
local sortkey | |||
if data_suffix then | if data_suffix then | ||
if data_suffix:find "^[%l-]+$" then | if data_suffix:find "^[%l-]+$" then | ||
local lang = | local lang = get_lang(data_suffix) | ||
if lang then | if lang then | ||
sortkey = lang:getCanonicalName() | |||
cats:insert(sortkey .. " data modules") | |||
end | end | ||
elseif data_suffix:find "^%u%l%l%l$" then | elseif data_suffix:find "^%u%l%l%l$" then | ||
local script = | local script = get_script(data_suffix) | ||
if script then | if script then | ||
sortkey = script:getCanonicalName() | |||
cats:insert(script:getCategoryName()) | cats:insert(script:getCategoryName()) | ||
end | end | ||
end | end | ||
cats:insert("Character insertion data modules|" .. (sortkey or data_suffix)) | |||
end | end | ||
end, | end, | ||
}, | }, | ||
{ | { | ||
regex = "^Module:R:([ | regex = "^Module:R:([%l-]+):(.+)$", | ||
process = function(title, cats, lang_code, refname) | process = function(title, cats, lang_code, refname) | ||
local lang = lang_cache[lang_code] | local lang = lang_cache[lang_code] | ||
| Line 247: | Line 559: | ||
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 | return "This module implements the reference template {{temp|R:" .. lang_code .. ":" .. refname .. "}}." | ||
end | end | ||
end, | |||
}, | |||
{ | |||
regex = "^Module:Quotations/([%l-]+)/?(.*)", | |||
process = "Quotation", | |||
}, | |||
{ | |||
regex = "^Module:affix/lang%-data/([%l-]+)", | |||
process = "affix lang-data", | |||
}, | |||
{ | |||
regex = "^Module:dialect synonyms/([%l-]+)$", | |||
process = function(title, cats, lang_code) | |||
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| ") | |||
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" .. | |||
expand_template({ title = 'dial syn', args = { lang_code, ["demo mode"] = "y" } }) | |||
end | |||
end, | |||
}, | |||
{ | |||
regex = "^Module:dialect synonyms/([%l-]+)/(.+)$", | |||
process = function(title, cats, lang_code, term) | |||
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 ("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 } })) | |||
end | |||
end, | |||
}, | |||
{ | |||
regex = "^Module:bibliography/data/([%l-]+)$", | |||
process = function(title, cats, lang_code) | |||
if lang_code == "preload" then | |||
return 'Used as a base model for other languages when the button "create new language submodule" is clicked.' | |||
end | |||
local page = require(title.fullText).bib_page | |||
if not page then | |||
page = lang_cache[lang_code]:getCanonicalName() | |||
if page then | |||
cats:insert(page.." modules") | |||
end | |||
end | |||
cats:insert("Reference modules") | |||
return "This module holds bibliographical data for "..page..". For the formatted bibliography see '''[[Appendix:Bibliography/"..page.."]]'''." | |||
end, | end, | ||
}, | }, | ||
| Line 255: | Line 617: | ||
function export.show(frame) | function export.show(frame) | ||
local | local boolean_default_false = {type = "boolean", default = false} | ||
["hr"] = | local args = process_params(frame.args, { | ||
["for"] = | ["hr"] = true, | ||
["from"] = | ["for"] = true, | ||
[" | ["from"] = true, | ||
["nodoc"] = | ["allowondoc"] = boolean_default_false, -- Don't throw an error if used on a documentation subpage. | ||
} | ["notsubpage"] = boolean_default_false, | ||
["nodoc"] = boolean_default_false, | |||
["nolinks"] = boolean_default_false, -- suppress all "Useful links" | |||
["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') | ||
| Line 274: | Line 638: | ||
end | end | ||
local 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 = | |||
local contentModel = title.contentModel | local contentModel = title.contentModel | ||
local pagetype, is_script_or_stylesheet = get_pagetype(title) | |||
local preload, fallback_docs, doc_content, old_doc_title, user_name, skin_name, needs_doc | |||
local doc_content_source = "Module:documentation" | |||
local auto_generated_cat_source | |||
local cats_auto_generated = false | |||
if not args.allowondoc and is_documentation(title) then | |||
-- TODO: merge with {{documentation subpage}}, and choose behaviour based on the page type. | |||
error("This template should not be used on a documentation page. Please use [[Template:documentation subpage]].") | |||
elseif is_sandbox(title) then | |||
local sandbox_ns = title.nsText | |||
preload = ("Template:documentation/preload%s%sSandbox"):format( | |||
if title.nsText == | sandbox_ns == "Module" and sandbox_ns or "Template", | ||
title.rootText:match("^[Uu]ser:(.+)") and "User" or "" | |||
) | |||
elseif pagetype:match("%f[%w]gadget%f[%W]") then | |||
preload = "Template:documentation/preloadGadget" | |||
elseif pagetype:match("%f[%w]script%f[%W]") then -- .js | |||
if title.nsText == "MediaWiki" then | |||
preload = "Template:documentation/preloadMediaWikiJavaScript" | |||
else | |||
preload = "Template:documentation/preloadTemplate" -- XXX | |||
if title.nsText == "User" then | |||
user_name = title.rootText | |||
end | end | ||
end | end | ||
if title.nsText == | is_script_or_stylesheet = true | ||
elseif pagetype:match("%f[%w]stylesheet%f[%W]") then -- .css | |||
preload = "Template:documentation/preloadTemplate" -- XXX | |||
if title.nsText == "User" then | |||
user_name = title.rootText | user_name = title.rootText | ||
end | end | ||
is_script_or_stylesheet = true | |||
elseif contentModel == "Scribunto" then -- Exclude pages in Module: which aren't Scribunto. | |||
preload = "Template:documentation/preloadModule" | |||
elseif pagetype:match("%f[%w]template%f[%W]") or pagetype:match("%f[%w]project%f[%W]") then | |||
preload = "Template:documentation/preloadTemplate" | |||
elseif contentModel == "Scribunto" then | |||
elseif | |||
preload = | |||
end | end | ||
if doc_title.isRedirect then | if doc_title and doc_title.isRedirect then | ||
old_doc_title = doc_title | old_doc_title = doc_title | ||
doc_title = | doc_title = doc_title.redirectTarget | ||
end | end | ||
output:insert("<dl class=\"plainlinks\" style=\"font-size: smaller;\">") | output:insert("<dl class=\"plainlinks\" style=\"font-size: smaller;\">") | ||
local function get_module_doc_and_cats(categories_only) | |||
cats_auto_generated = true | |||
local automatic_cats = nil | |||
if user_name then | |||
fallback_docs = "documentation/fallback/user module" | |||
automatic_cats = {"User sandbox modules"} | |||
else | |||
for _, data in ipairs(module_regex) do | |||
local captures = {umatch(title.fullText, data.regex)} | |||
if #captures > 0 then | |||
local cat, process_function | |||
if is_callable(data.process) then | |||
process_function = data.process | |||
elseif type(data.process) == "string" then | |||
doc_content_source = "Module:documentation/functions/" .. data.process | |||
process_function = require(doc_content_source) | |||
end | |||
if process_function then | |||
doc_content = process_function(title, cats, unpack(captures)) | |||
end | |||
if type(doc_content) == "table" then | |||
doc_content_source = doc_content.title and "Template:" .. doc_content.title or doc_content_source | |||
doc_content = expand_template(doc_content) | |||
elseif doc_content ~= nil then | |||
doc_content = preprocess(doc_content) | |||
end | |||
cat = data.cat | |||
if cat then | |||
if type(cat) == "string" then | |||
cat = {cat} | |||
end | end | ||
for _, c in ipairs(cat) do | |||
insert(cats, (ugsub(title.fullText, data.regex, c))) | |||
end | end | ||
end | end | ||
break | |||
end | end | ||
end | end | ||
end | |||
if title.subpageText == "templates" then | |||
cats:insert("Template interface modules") | |||
end | |||
if automatic_cats then | |||
local | for _, c in ipairs(automatic_cats) do | ||
cats:insert(c) | |||
end | |||
end | |||
if #cats == 0 then | |||
local auto_cats = categorize_module(frame, "return raw", "noerror") | |||
if #auto_cats > 0 then | |||
auto_generated_cat_source = "Module:module categorization" | |||
end | |||
for _, category in ipairs(auto_cats) do | |||
cats:insert(category) | |||
end | end | ||
end | |||
-- meaning module is not in user’s sandbox or one of many datamodule boring series | |||
needs_doc = not categories_only and not (automatic_cats or doc_content or fallback_docs) | |||
end | |||
if | -- Override automatic documentation, if present. | ||
for | if doc_title and doc_title.exists then | ||
local cats_auto_generated_text = "" | |||
if contentModel == "Scribunto" then | |||
local doc_page_content = doc_title.content | |||
-- Track then do nothing if there are uses of includeonly. The | |||
-- pattern is slightly too permissive, but any false-positives are | |||
-- obvious typos that should be corrected. | |||
if doc_page_content:lower():match("</?includeonly%f[%s/>][^>]*>") then | |||
track("module-includeonly") | |||
else | |||
-- Check for uses of {{module cat}}. find_templates treats the | |||
-- input as transcluded by default (i.e. it parses the wikitext | |||
-- which will be transcluded through to the module page). | |||
local module_cat | |||
for template in find_templates(doc_page_content) do | |||
if template:get_name() == "module cat" then | |||
module_cat = true | |||
break | |||
end | |||
end | |||
if not module_cat then | |||
get_module_doc_and_cats("categories only") | |||
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>[[" .. | |||
new_title(auto_generated_cat_source):fullUrl{action = "edit"} .. " edit]]</sup>" | |||
end | end | ||
end | end | ||
end | |||
output:insert( | |||
"<dd><i style=\"font-size: larger;\">The following " .. | |||
"[[Help:Documenting templates and modules|documentation]] is located at [[" .. | |||
doc_title.fullText .. "]]. " .. "<sup>[[" .. doc_title:fullUrl{action = "edit"} .. " edit]]</sup>" .. | |||
cats_auto_generated_text .. "</i></dd>") | |||
else | |||
if contentModel == "Scribunto" then | |||
get_module_doc_and_cats(false) | |||
elseif title.nsText == "Template" then | elseif title.nsText == "Template" then | ||
--cats:insert("Uncategorized templates") | --cats:insert("Uncategorized templates") | ||
needs_doc = not (fallback_docs or nodoc) | needs_doc = not (fallback_docs or nodoc) | ||
elseif | elseif user_name and is_script_or_stylesheet then | ||
skin_name = skins[title.text:sub(#title.rootText + 1):match("^/(%l+)%.[jc]ss?$")] | |||
if skin_name then | |||
fallback_docs = "documentation/fallback/user " .. contentModel | |||
end | end | ||
end | end | ||
| Line 410: | Line 804: | ||
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 " .. | ||
"generated by [[" .. | "generated by [[" .. doc_content_source .. "]]. <sup>[[" .. | ||
new_title(doc_content_source):fullUrl{action = "edit"} .. | |||
" edit]]</sup> </i></dd>") | " edit]]</sup> </i></dd>") | ||
elseif not nodoc then | elseif not nodoc then | ||
output:insert( | if doc_title then | ||
output:insert( | |||
"<dd><i style=\"font-size: larger;\">This " .. pagetype .. | |||
" lacks a [[Help:Documenting templates and modules|documentation subpage]]. " .. | |||
(fallback_docs and "You may " or "Please ") .. | |||
"[" .. doc_title:fullUrl{action = "edit", preload = preload} | |||
.. " create it].</i></dd>\n") | |||
else | |||
output:insert( | |||
"<dd><i style=\"font-size: larger; color: var(--wikt-palette-red-9,#FF0000);\">Unable to auto-generate " .. | |||
"documentation for this " .. pagetype ..".</i></dd>\n") | |||
end | |||
end | end | ||
end | end | ||
if title.fullText | if startswith(title.fullText, "MediaWiki:Gadget-") then | ||
local is_gadget = false | local is_gadget = false | ||
for line in gline(new_title("MediaWiki:Gadgets-definition").content) do | |||
local gadget, items = line:match("^%*%s*(%a[%w_-]*)%[.-%]|(.+)$") | |||
local gadget | |||
if not gadget then | if not gadget then | ||
gadget, items = line:match("^%*%s*([ | gadget, items = line:match("^%*%s*(%a[%w_-]*)|(.+)$") | ||
end | end | ||
if gadget then | if gadget then | ||
items = Array( | items = Array(split(items, "|")) | ||
for i, item in ipairs(items) do | for i, item in ipairs(items) do | ||
if title.fullText == ("MediaWiki:Gadget-" .. item) then | if title.fullText == ("MediaWiki:Gadget-" .. item) then | ||
| Line 443: | Line 840: | ||
output:insert(gadget) | output:insert(gadget) | ||
output:insert("</code> gadget ([") | output:insert("</code> gadget ([") | ||
output:insert(tostring( | 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( | 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(" </dd>") | output:insert(" </dd>") | ||
| Line 461: | Line 856: | ||
end | end | ||
output:insert("<dd> ''Other parts'': ") | output:insert("<dd> ''Other parts'': ") | ||
output:insert( | output:insert(list_to_text(items)) | ||
output:insert("</dd>") | output:insert("</dd>") | ||
end | end | ||
| Line 475: | Line 870: | ||
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( | output:insert(tostring(full_url("Special:Gadgets", {uselang = "en"}))) | ||
output:insert(' gadget] ([') | output:insert(' gadget] ([') | ||
output:insert(tostring( | output:insert(tostring(full_url("MediaWiki:Gadgets-definition", {action = "edit"}))) | ||
output:insert(' edit definitions]).</dd>') | output:insert(' edit definitions]).</dd>') | ||
-- else | -- else | ||
| Line 486: | Line 881: | ||
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 = | 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 = | 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 | |||
local links = Array() | |||
if | |||
links | |||
if title.isSubpage and not args.notsubpage then | |||
links:insert("[[:" .. title.nsText .. ":" .. title.rootText .. "|root page]]") | |||
links:insert("[[Special:PrefixIndex/" .. title.nsText .. ":" .. title.rootText .. "/|root page’s subpages]]") | |||
else | |||
links:insert("[[Special:PrefixIndex/" .. title.fullText .. "/|subpage list]]") | |||
end | |||
links:insert( | links:insert( | ||
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidetrans = true, hideredirs = true})) .. " links]") | |||
if contentModel ~= "Scribunto" then | |||
links:insert( | |||
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidelinks = true, hidetrans = true})) .. " redirects]") | |||
links:insert("[ | |||
end | end | ||
if is_script_or_stylesheet then | |||
if user_name then | |||
links:insert("[[Special:MyPage" .. title.text:sub(#title.rootText + 1) .. "|your own]]") | |||
end | |||
else | else | ||
links:insert("[ | links:insert( | ||
"[" .. tostring(full_url("Special:WhatLinksHere/" .. title.fullText, {hidelinks = true, hideredirs = true})) .. " transclusions]") | |||
end | end | ||
if user_name then | if contentModel == "Scribunto" then | ||
local is_testcases = title.isSubpage and title.subpageText == "testcases" | |||
local without_subpage = title.nsText .. ":" .. title.baseText | |||
if is_testcases then | |||
links:insert("[[:" .. without_subpage .. "|tested module]]") | |||
else | |||
links:insert("[[" .. title.fullText .. "/testcases|testcases]]") | |||
end | |||
if user_name then | |||
links:insert("[[User:" .. user_name .. "|user page]]") | |||
links:insert("[[User talk:" .. user_name .. "|user talk page]]") | |||
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 | |||
cats:insert("Sandbox modules") | cats:insert("Sandbox modules") | ||
| Line 545: | Line 937: | ||
needs_doc = false | needs_doc = false | ||
-- | -- Don't track user sandbox modules. | ||
local | local text_title = new_title(title.text) | ||
if not (text_title and text_title.namespace == 2) then | |||
track("sandbox to be moved") | |||
local sandbox_of, diff = title.baseText | |||
if title_exists(sandbox_of) then | |||
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")" | |||
else | |||
track("no sandbox of") | |||
end | |||
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: | ||
| Line 562: | Line 958: | ||
else | else | ||
local sandbox_title | local sandbox_title | ||
if title. | if title.rootText == "grc-decl" then | ||
sandbox_title = title.fullText | sandbox_title = string_insert(title.fullText, 16, "/sandbox") | ||
elseif is_testcases then | elseif is_testcases then | ||
sandbox_title = title.fullText:gsub("/testcases", "/sandbox/testcases") | sandbox_title = title.fullText:gsub("/testcases", "/sandbox/testcases") | ||
| Line 572: | Line 968: | ||
local diff | local diff | ||
if | if title_exists(sandbox_title) then | ||
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")" | diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")" | ||
end | end | ||
| Line 579: | Line 975: | ||
end | end | ||
end | end | ||
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]] | |||
-- apparently same with/without: &profile=advanced&fulltext=1 | |||
local errorq = 'searchengineselect=mediawiki&search=all: hastemplate:\"'..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( | |||
'[' .. tostring(full_url('Special:Search', errorq..eincategory )) .. ' errors]' | |||
.. ' (' .. | |||
'[' .. tostring(full_url('Special:Search', errorq..'ParserFunction_errors' )) .. ' parser]' | |||
.. '/' .. | |||
'[' .. tostring(full_url('Special:Search', errorq..'Pages_with_module_errors' )) .. ' module]' | |||
.. ')' | |||
) | |||
-- Will behave badly if “/sandbox” occurs twice in title! | 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 | |||
-- “/sandbox”. | |||
cats:insert("Sandbox templates") | |||
-- Sandbox templates don’t really need documentation. | |||
needs_doc = false | |||
-- Will behave badly if “/sandbox” occurs twice in title! | |||
local sandbox_of = title.fullText:gsub("/sandbox%d*%f[/%z]", "") | |||
local diff | |||
if title_exists(sandbox_of) then | |||
diff = " (" .. compare_pages(title.fullText, sandbox_of, "diff") .. ")" | |||
else | |||
track("no sandbox of") | |||
end | |||
links:insert("[[:" .. sandbox_of .. "|sandbox of]]" .. (diff or "")) | |||
-- This is a template that can have a sandbox. | |||
elseif not args.nosandbox then -- unless we tell it not to | |||
local sandbox_title = title.fullText .. "/sandbox" | |||
local diff | |||
if title_exists(sandbox_title) then | |||
diff = " (" .. compare_pages(title.fullText, sandbox_title, "diff") .. ")" | |||
end | |||
links:insert("[[:" .. sandbox_title .. "|sandbox]]" .. (diff or "")) | |||
end | end | ||
end | end | ||
if #links > 0 then | |||
output:insert("<dd> ''Useful links'': " .. links:concat(" • ") .. "</dd>") | |||
end | |||
end | end | ||
| Line 633: | Line 1,032: | ||
-- 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. | ||
if title.fullText | if startswith(title.fullText, "Module:category tree/topic/") then | ||
local ok, err = pcall(require, "Module:category tree/topic | local ok, err = pcall(require, "Module:category tree/topic/data") | ||
if not ok then | if not ok then | ||
output:insert('<span class="error">' .. err .. '</span>\n\n') | output:insert('<span class="error">' .. err .. '</span>\n\n') | ||
| Line 640: | Line 1,039: | ||
end | end | ||
if doc_title.exists then | if doc_title and doc_title.exists then | ||
-- Override automatic documentation, if present. | -- Override automatic documentation, if present. | ||
doc_content = | 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 = | doc_content = expand_template{ | ||
title = fallback_docs | title = fallback_docs, | ||
args = { | args = { | ||
['user'] = user_name | ['user'] = user_name, | ||
['page'] = title.fullText | ['page'] = title.fullText, | ||
['skin name'] = skin_name | ['skin name'] = skin_name, | ||
} | }, | ||
} | } | ||
end | end | ||
| Line 658: | Line 1,057: | ||
end | end | ||
output:insert(('\n<%s style="clear: both;" />'):format(args.hr == "below" and "hr" or " | output:insert(('\n<%s style="clear: both;" />'):format(args.hr == "below" and "hr" or "span")) | ||
if not cats[1] and not doc_content 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") | ||
| Line 679: | Line 1,078: | ||
return output:concat() | return output:concat() | ||
end | |||
function export.module_auto_doc_table() | |||
local parts = {} | |||
local function ins(text) | |||
insert(parts, text) | |||
end | |||
ins('{|class="wikitable"') | |||
ins("! Regex !! Category !! Handling modules") | |||
for _, spec in ipairs(module_regex) do | |||
local cat_text | |||
local cats = spec.cat | |||
if cats then | |||
local cat_parts = {} | |||
if type(cats) == "string" then | |||
cats = {cats} | |||
end | |||
for _, cat in ipairs(cats) do | |||
insert(cat_parts, ("<code>%s</code>"):format((cat:gsub("|", "|")))) | |||
end | |||
cat_text = concat(cat_parts, ", ") | |||
else | |||
cat_text = "''(unspecified)''" | |||
end | |||
ins("|-") | |||
ins(("| <code>%s</code> || %s || %s"):format(spec.regex, cat_text, | |||
is_callable(spec.process) and "''(handled internally)''" or | |||
type(spec.process) == "string" and ("[[Module:documentation/functions/%s]]"):format(spec.process) or | |||
"''(no documentation generator)''")) | |||
end | |||
ins("|}") | |||
return concat(parts, "\n") | |||
end | end | ||
| Line 688: | Line 1,119: | ||
pagename = frame.args[1] | pagename = frame.args[1] | ||
else | else | ||
local title = | local title = get_current_title() | ||
subpage = title.subpageText | subpage = title.subpageText | ||
pagename = title.text | pagename = title.text | ||
| Line 722: | Line 1,153: | ||
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 | ||
local script = | local script = get_script(script_code) | ||
if script then | if script then | ||
categories:insert("[[Category:" .. script:getCategoryName() .. "]]") | categories:insert("[[Category:" .. script:getCategoryName() .. "]]") | ||
| Line 729: | Line 1,160: | ||
end | end | ||
if subpage ~= "documentation" and not | 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 | ||
| Line 744: | Line 1,175: | ||
-- This will not error because languageObjects is not empty. | -- This will not error because languageObjects is not empty. | ||
:map(languageObjects[1].makeCategoryLink) | :map(languageObjects[1].makeCategoryLink) | ||
: | :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 | |||
-- Used by {{entry name module documentation}}. | |||
function export.entryNameModuleLangList(frame) | |||
local pagename, subpage | |||
if frame.args[1] then | |||
pagename = frame.args[1] | |||
else | |||
local title = get_current_title() | |||
subpage = title.subpageText | |||
pagename = title.text | |||
if subpage ~= pagename then | |||
pagename = title.rootText | |||
end | |||
end | |||
local entryNameModule = pagename | |||
local languageObjects = require("Module:languages/byEntryNameModule")(entryNameModule) | |||
local codeInPagename = pagename:match("^([%l-]+)%-.*entryname$") | |||
local categories = Array() | |||
local codeInPagenameInList = false | |||
if codeInPagename then | |||
if languageObjects[1] and subpage ~= "documentation" then | |||
local agreement = languageObjects[2] and "s" or "" | |||
categories:insert("[[Category:Entry name-generating modules used by " .. | |||
#languageObjects .. " language" .. agreement .. "]]") | |||
end | |||
languageObjects = Array(languageObjects) | |||
:filter( | |||
function (lang) | |||
local result = lang:getCode() ~= codeInPagename | |||
codeInPagenameInList = codeInPagenameInList or result | |||
return result | |||
end) | |||
end | |||
if subpage ~= "documentation" then | |||
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do | |||
local script = get_script(script_code) | |||
if script then | |||
categories:insert("[[Category:" .. script:getCategoryName() .. "]]") | |||
end | |||
end | |||
end | |||
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then | |||
categories:insert("[[Category:Entry name-generating modules without a testcases subpage]]") | |||
end | |||
if not languageObjects[1] then | |||
return categories:concat() | |||
end | |||
local langs = Array(languageObjects) | |||
:sort( | |||
function(lang1, lang2) | |||
return lang1:getCode() < lang2:getCode() | |||
end) | |||
-- This will not error because languageObjects is not empty. | |||
:map(languageObjects[1].makeCategoryLink) | |||
:serialCommaJoin() | |||
return "It is " .. ( codeInPagenameInList and "also" or "" ) .. | |||
" used to generate entry names for " .. langs .. "." .. categories:concat() | |||
end | |||
-- Used by {{sortkey module documentation}}. | |||
function export.sortkeyModuleLangList(frame) | |||
local pagename, subpage | |||
if frame.args[1] then | |||
pagename = frame.args[1] | |||
else | |||
local title = get_current_title() | |||
subpage = title.subpageText | |||
pagename = title.text | |||
if subpage ~= pagename then | |||
pagename = title.rootText | |||
end | |||
end | |||
local sortkeyModule = pagename | |||
local languageObjects = require("Module:languages/bySortkeyModule")(sortkeyModule) | |||
local codeInPagename = pagename:match("^([%l-]+)%-.*sortkey$") | |||
local categories = Array() | |||
local codeInPagenameInList = false | |||
if codeInPagename then | |||
if languageObjects[1] and subpage ~= "documentation" then | |||
local agreement = languageObjects[2] and "s" or "" | |||
categories:insert("[[Category:Sortkey-generating modules used by " .. | |||
#languageObjects .. " language" .. agreement .. "]]") | |||
end | |||
languageObjects = Array(languageObjects) | |||
:filter( | |||
function (lang) | |||
local result = lang:getCode() ~= codeInPagename | |||
codeInPagenameInList = codeInPagenameInList or result | |||
return result | |||
end) | |||
end | |||
if subpage ~= "documentation" then | |||
for script_code in pagename:gmatch("%f[^-%z]%u%l%l%l%f[-]") do | |||
local script = get_script(script_code) | |||
if script then | |||
categories:insert("[[Category:" .. script:getCategoryName() .. "]]") | |||
end | |||
end | |||
end | |||
if subpage ~= "documentation" and not title_exists("Module:" .. pagename .. "/testcases") then | |||
categories:insert("[[Category:Sortkey-generating modules without a testcases subpage]]") | |||
end | |||
if not languageObjects[1] then | |||
return categories:concat() | |||
end | |||
local langs = Array(languageObjects) | |||
:sort( | |||
function(lang1, lang2) | |||
return lang1:getCode() < lang2:getCode() | |||
end) | |||
-- This will not error because languageObjects is not empty. | |||
:map(languageObjects[1].makeCategoryLink) | |||
:serialCommaJoin() | |||
return "It is " .. ( codeInPagenameInList and "also" or "" ) .. | |||
" used to sort " .. langs .. "." .. categories:concat() | |||
end | end | ||
return export | return export | ||