Module:Lang/documentor tool

require('Module:No globals'); local p = {};

--[[-< L A N G - X X _ S E T T I N G S >---

Reads the content of the template and extracts the parameters from for display on the template's documentation page.

]]

local function lang_xx_settings (frame) local page = mw.title.makeTitle ('Template', frame.args['template'] or frame.args[1]);	-- get a page object for this page in 'Template:' namespace if not page then return '';																-- TODO: error message? end local content = page:getContent;											-- get unparsed content if not page then return '';																-- TODO: error message? end

local out = {}; local params; local style;

if content:match ('{{%s*#invoke:%s*[Ll]ang%s*|[^|]+|[^}]+}}') or content:match ('{{%s*#invoke:%s*[Ll]ang/sandbox%s*|[^|]+|[^}]+}}') then			-- if this template uses Module:Lang params = content:match ('{{%s*#invoke:%s*[Ll]ang%s*|[^|]+(|[^}]+)}}') or content:match ('{{%s*#invoke:%s*[Ll]ang/sandbox%s*|[^|]+(|[^}]+)}}')	-- extract the #invoke:'s parameters if not params then return '';															-- there should be at least one or the template/module won't work TODO: error message? end table.insert (out, '{| class="wikitable" style="text-align:right; float:right"\n|+settings')	-- start a wikitable for k, v in params:gmatch ('%s*|%s*([^%s=]+)%s*=%s*([^%s|]+)') do		-- get the parameter names (k) and values (v) if 'label' == k then												-- special case for labels because spaces and pipes v = params:match ('label%s*=%s*(%[%^%+%]%])') or params:match ('label%s*=%s*([^|\n]+)') or 'missing label'; end table.insert (out, table.concat ({k, '\n|', v}));					-- make rudimentary wikitable entries end

style = content:match ('lang_xx_([^|]+)'); return table.concat ({table.concat (out,'\n|-\n! scope="row" | '), '\n|-\n|colspan="2"|style: ', style, '\n|-\n|}'});	-- add inter-row markup and close the wikitable and done else return '';																-- does not use Module:Lang so abandon quietly end end

--[[-< U S E S _ M O D U L E >-

Reads the content of the template to determine if this template uses Module:Lang. Returns the index of the substring '{{#invoke|lang|' in the template page content if true; empty string if false.

Used in template documentation {{#if:}} parser functions.

]]

local function uses_module (frame) local page = mw.title.makeTitle ('Template', frame.args['template'] or frame.args[1]);	-- get a page object for this page in 'Template:' namespace if not page then return '';																-- TODO: error message? end local content = page:getContent;											-- get unparsed content if not page then return '';																-- TODO: error message? end return content:find ('{{%s*#invoke:[Ll]ang%s*|') or '';						-- return index or empty string end

local language_categories = { ["SOURCES"] = "Articles with %s-language sources (%s)", ["CS1"] = "CS1 %s-language sources (%s)", ["LANGUAGE_TEXT"] = "Articles containing %s-language text", ["LANGUAGES_COLLECTIVE_TEXT"] = "Articles with text from the %s languages collective", ["LANGUAGES_COLLECTIVE_NEW_TEXT"] = "Articles with text from %s languages" }

local error_messages = { ["NOT_VALID_LANGUAGE_CODE"] = "%s is not a valid ISO 639 or IETF language name.", ["NO_CATEGORY_TITLE_FOUND"] = "No language category found for %s.", ["INCORRECT_CATEGORY_TITLE"] = "%s is not the category being populated by the {{%s}} template. The correct category is located at: %s." }

local function get_error_message(message) return string.format(' Error: %s ', message) end

-- Generates a consistent style See also section for {{Category articles containing non-English-language text}} and {{Non-English-language source category}}. -- If {{CS1 language sources}} is converted, it should also use it. -- TODO: Currently getting the redirect cateogry Category:Articles with text from Berber languages. Need to prevent soft redirects. local function get_see_also_section(page_title, language_name, language_code) local see_also_section = {}

for _, value in pairs(language_categories) do   	local category = mw.title.new(string.format(value, language_name, language_code), 14) if category and page_title ~= category.text and category.exists then table.insert(see_also_section, "* " .. category.prefixedText .. "") end end table.sort(see_also_section) table.insert(see_also_section, 1, '\n==See also==') if table.getn(see_also_section) == 1 then return "" else return table.concat(see_also_section, "\n") end end

-- Generates a consistent top maintenance template section. local function get_top_section(frame) local top_section = {} table.insert(top_section, frame:expandTemplate{title = 'Hidden category'}) if mw.site.stats.pagesInCategory(mw.title.getCurrentTitle.text, "all") == 0 then table.insert(top_section, frame:expandTemplate{title = 'Possibly empty category'}) else table.insert(top_section, frame:expandTemplate{title = 'Possibly empty category', args = {hidden=true}}) end

local purge_module = require('Module:Purge') table.insert(top_section, ' ' .. purge_module._main({"Purge page cache"}) .. ' ') return table.concat(top_section, "\n\n") end

-- Generates a consistent non-text section. local function get_bottom_section(frame, language_name, see_also_section, parent_category) local bottom_section = {} table.insert(bottom_section, frame:expandTemplate{title = 'CatAutoTOC'}) table.insert(bottom_section, see_also_section) table.insert(bottom_section, frame:preprocess{text = "{{DEFAULTSORT:" .. language_name .. "}}"}) if mw.title.getCurrentTitle.nsText == "Category" then table.insert(bottom_section, parent_category) end

return table.concat(bottom_section, "\n\n\n") end

--[[--< N O N _ E N _ S R C _ C A T >--

{{#invoke:Lang/documentor tool|non_en_src_cat|}}

This function implements {{Non-English-language source category}}.

]]

local language_source_category_text = { ["LINE1"] = "This is a tracking category for articles that use %s to identify %s sources.", ["LANGUAGE_COLLECTIVE"] = "%s-collective", ["LANGUAGE_NON_COLLECTIVE"] = '%s-language' }

local function non_en_src_cat(frame) local page_title_object = mw.title.getCurrentTitle local page_title = page_title_object.text local language_code = page_title:match('%(([%a%-]+)%)') local language_name = require('Module:Lang')._name_from_tag({language_code}) local layout = {} local see_also_section = "" local current_category_title = page_title_object.prefixedText local correct_language_category_title = require('Module:In lang')._in_lang({language_code, ["list-cats"]="yes"}) if correct_language_category_title == "" then table.insert(layout, get_error_message(string.format(error_messages["NO_CATEGORY_TITLE_FOUND"], language_code))) elseif correct_language_category_title ~= current_category_title then table.insert(layout, get_error_message(string.format(error_messages["INCORRECT_CATEGORY_TITLE"], current_category_title, "In lang", correct_language_category_title))) else local language_link -- Is a language collective? if language_name:find('languages') then language_link = string.format(language_source_category_text["LANGUAGE_COLLECTIVE"], language_name) else language_link = string.format(language_source_category_text["LANGUAGE_NON_COLLECTIVE"], language_name, language_name) end local text = string.format(language_source_category_text["LINE1"], frame:expandTemplate{title = 'Tlx', args = {"In lang", language_code}}, language_link) table.insert(layout, get_top_section(frame)) table.insert(layout, text) see_also_section = get_see_also_section(page_title, language_name, language_code) end

local bottom = get_bottom_section(frame, language_name, see_also_section, "") return table.concat(layout, "\n\n") .. bottom end

--[[--< A R T I C L E S _ C O N T A I N I N G . . . >--

{{#invoke:Lang/documentor tool|articles_containing_category_text|}}

This function implements {{Category articles containing non-English-language text}}.

]]

local articles_containing_category_text = { ["LINE1"] = "This category contains articles with %s-language%s text. The primary purpose of these categories is to facilitate manual or automated checking of text in other languages.", ["LINE2"] = "This category should only be added with the %s family of templates, never explicitly.", ["LINE3"] = 'For example %s, which wraps the text with .%s', ["LINE3_EXTRA"] = " Also available is %s which displays as %s.", ["IN_SCRIPT"] = " (in %s)", ["EXAMPLE_DEFAULT_TEXT"] = "text in %s language here" }

local function articles_containing_language_text_category(frame) local args = require('Module:Arguments').getArgs(frame) local page_title = mw.title.getCurrentTitle.text

-- Naming style: Articles with text from the Berber languages collective local page_title_modified = page_title local split_title = "([^,]+)%%s([^,]+)" local part1 = "" local part2 = "" if string.find(page_title_modified, "languages collective") then		-- this form may or may not be replaced with the form in the elseif -- Wikipedia:Categories_for_discussion/Log/2020_August_18#Category:Articles_with_text_from_the_Afro-Asiatic_languages_collective -- Naming style: Category:Articles with text from the Afro-Asiatic languages collective part1, part2 = language_categories["LANGUAGES_COLLECTIVE_TEXT"]:match(split_title) elseif page_title_modified:find ('Articles with text from ') then -- Naming style: Category:Articles with text from Afro-Asiatic languages (as currently implemented in Module:lang) part1, part2 = language_categories["LANGUAGES_COLLECTIVE_NEW_TEXT"]:match(split_title) else -- Naming style: Category:Articles containing French-language text part1, part2 = language_categories["LANGUAGE_TEXT"]:match(split_title) end

page_title_modified = page_title_modified:gsub(part1, "") page_title_modified = page_title_modified:gsub(part2, "") local language_name = page_title_modified

local lang_module = require('Module:Lang') local language_code = lang_module._tag_from_name({language_name}) local layout = {} local see_also_section = "" -- Check if error message if language_code:find('error') then table.insert(layout, get_error_message(string.format(error_messages["NOT_VALID_LANGUAGE_CODE"], language_name))) else local correct_language_category_title = lang_module._category_from_tag({language_code}) if correct_language_category_title:find('error') then table.insert(layout, get_error_message(string.format(error_messages["NO_CATEGORY_TITLE_FOUND"], language_code))) else local current_category_title = mw.title.getCurrentTitle.prefixedText if current_category_title ~= correct_language_category_title then table.insert(layout, get_error_message(string.format(error_messages["INCORRECT_CATEGORY_TITLE"], current_category_title, "Lang", correct_language_category_title))) else table.insert(layout, get_top_section(frame)) local script = args.script local script_text if script then script_text = string.format(articles_containing_category_text["IN_SCRIPT"], script) else script_text = "" end local example_default_text = string.format(articles_containing_category_text["EXAMPLE_DEFAULT_TEXT"], language_name) local example_text = args.example or example_default_text

table.insert(layout, string.format(articles_containing_category_text["LINE1"], language_name, language_name, script_text)) local lang_template = frame:expandTemplate{title = 'Tl', args = {"Lang"}} table.insert(layout, string.format(articles_containing_category_text["LINE2"], lang_template))

local language_code_link = lang_module._name_from_tag({language_code, link="yes", label=language_code}) local lang_template_example = frame:expandTemplate{title = 'Tlx', args = {"Lang", language_code_link, example_text}} local lang_x = mw.title.makeTitle(10, "Lang-" .. language_code) local line3_extra = "" if lang_x.exists then local lang_x_template_example = frame:expandTemplate{title = 'Tlx', args = {lang_x.text, example_text}} local lang_x_template = frame:expandTemplate{title = lang_x.text, args = {example_text}} line3_extra = string.format(articles_containing_category_text["LINE3_EXTRA"], lang_x_template_example, lang_x_template) end table.insert(layout, string.format(articles_containing_category_text["LINE3"], lang_template_example, language_code, line3_extra)) see_also_section = get_see_also_section(page_title, language_name, language_code) end end end local bottom = get_bottom_section(frame, language_name, see_also_section, "") return table.concat(layout, "\n\n") .. bottom end

----< E X P O R T E D  F U N C T I O N S >--

return { articles_containing_language_text_category = articles_containing_language_text_category, lang_xx_settings = lang_xx_settings, uses_module = uses_module, non_en_src_cat = non_en_src_cat, }