Difference between revisions of "Module:Lang/documentor tool"
Jump to navigation
Jump to search
blackwiki>Gonnym (linked name in error) |
blackwiki>Gonnym (Various updates and improvements; Added /testcases code; Added initial support for non_english_language_cs1_sources_category) |
||
| Line 2: | Line 2: | ||
local p = {}; | local p = {}; | ||
| − | --[[-------------------------< L A N G - X X _ S E T T I N G S > | + | --[[-------------------------< L A N G - X X _ S E T T I N G S >------------------------- |
{{#invoke:Lang/documentor tool|lang_xx_settings|template={{ROOTPAGENAME}}}} | {{#invoke:Lang/documentor tool|lang_xx_settings|template={{ROOTPAGENAME}}}} | ||
| Line 48: | Line 48: | ||
| − | --[[-------------------------< U S E S _ M O D U L E > | + | --[[-------------------------< U S E S _ M O D U L E >------------------------- |
{{#invoke:Lang/documentor tool|uses_module|template={{ROOTPAGENAME}}}} | {{#invoke:Lang/documentor tool|uses_module|template={{ROOTPAGENAME}}}} | ||
| Line 72: | Line 72: | ||
return content:find ('{{%s*#invoke:[Ll]ang%s*|') or ''; -- return index or empty string | return content:find ('{{%s*#invoke:[Ll]ang%s*|') or ''; -- return index or empty string | ||
end | end | ||
| + | |||
| + | --[[-------------------------< S H A R E D _ C O D E >------------------------- | ||
| + | |||
| + | - Tables: | ||
| + | -- language_categories | ||
| + | -- error_messages | ||
| + | |||
| + | - Functions: | ||
| + | -- get_error_message(message) | ||
| + | -- get_see_also_section(page_title, language_name, language_code) | ||
| + | -- get_top_section(frame) | ||
| + | -- get_bottom_section(frame, language_name, see_also_section, parent_category) | ||
| + | |||
| + | ]] | ||
local language_categories = { | local language_categories = { | ||
| Line 78: | Line 92: | ||
["LANGUAGE_TEXT"] = "Articles containing %s-language text", | ["LANGUAGE_TEXT"] = "Articles containing %s-language text", | ||
["LANGUAGES_COLLECTIVE_TEXT"] = "Articles with text from the %s languages collective", | ["LANGUAGES_COLLECTIVE_TEXT"] = "Articles with text from the %s languages collective", | ||
| − | ["LANGUAGES_COLLECTIVE_NEW_TEXT"] = "Articles with text from %s languages" | + | ["LANGUAGES_COLLECTIVE_NEW_TEXT"] = "Articles with text from %s languages", |
| + | ["ENGLISH"] = "Articles containing explicitly cited %s-language text", | ||
} | } | ||
| Line 84: | Line 99: | ||
["NOT_VALID_LANGUAGE_CODE"] = "[[%s]] is not a valid ISO 639 or IETF language name.", | ["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.", | ["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]]." | + | ["INCORRECT_CATEGORY_TITLE"] = "[[:%s]] is not the category being populated by the {{%s}} template. The correct category is located at: [[:%s]].", |
} | } | ||
| Line 143: | Line 158: | ||
end | end | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | + | --[[-------------------------< N O N _ E N G L I S H _ L A N G U A G E _ T E X T _ C A T E G O R Y >------------------------- | |
| − | + | {{#invoke:Lang/documentor tool|non_english_language_text_category}} | |
| + | This function implements {{Non-English-language text category}}. | ||
]] | ]] | ||
| − | local | + | local non_english_language_text_text_strings = { |
["LINE1"] = "This category contains articles with [[%s language|%s-language]]%s text. The primary purpose of these categories is to facilitate manual or automated checking of text in other languages.", | ["LINE1"] = "This category contains articles with [[%s language|%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.", | ["LINE2"] = "This category should only be added with the %s family of templates, never explicitly.", | ||
| Line 204: | Line 172: | ||
["LINE3_EXTRA"] = " Also available is %s which displays as %s.", | ["LINE3_EXTRA"] = " Also available is %s which displays as %s.", | ||
["IN_SCRIPT"] = " (in %s)", | ["IN_SCRIPT"] = " (in %s)", | ||
| − | ["EXAMPLE_DEFAULT_TEXT"] = "text in %s language here" | + | ["EXAMPLE_DEFAULT_TEXT"] = "text in %s language here", |
| + | ["PARENT_CATEGORY"] = "[[Category:Articles containing non-English-language text]]", | ||
} | } | ||
| − | local function | + | local function non_english_language_text_category(frame) |
local args = require('Module:Arguments').getArgs(frame) | local args = require('Module:Arguments').getArgs(frame) | ||
local page_title = mw.title.getCurrentTitle().text | local page_title = mw.title.getCurrentTitle().text | ||
| Line 217: | Line 186: | ||
local part2 = "" | local part2 = "" | ||
local suffix | local suffix | ||
| − | if | + | if page_title_modified:find("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 | -- 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 | -- Naming style: Category:Articles with text from the Afro-Asiatic languages collective | ||
part1, part2 = language_categories["LANGUAGES_COLLECTIVE_TEXT"]:match(split_title) | part1, part2 = language_categories["LANGUAGES_COLLECTIVE_TEXT"]:match(split_title) | ||
suffix = " languages" | suffix = " languages" | ||
| − | elseif page_title_modified:find ('Articles with text from ') then | + | 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) | -- 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) | part1, part2 = language_categories["LANGUAGES_COLLECTIVE_NEW_TEXT"]:match(split_title) | ||
suffix = " languages" | suffix = " languages" | ||
| + | elseif page_title_modified:find('explicitly cited') then | ||
| + | part1, part2 = language_categories["ENGLISH"]:match(split_title) | ||
else | else | ||
-- Naming style: Category:Articles containing French-language text | -- Naming style: Category:Articles containing French-language text | ||
| Line 261: | Line 232: | ||
local script_text | local script_text | ||
if script then | if script then | ||
| − | script_text = string.format( | + | script_text = string.format(non_english_language_text_text_strings["IN_SCRIPT"], script) |
else | else | ||
script_text = "" | script_text = "" | ||
end | end | ||
| − | local example_default_text = string.format( | + | local example_default_text = string.format(non_english_language_text_text_strings["EXAMPLE_DEFAULT_TEXT"], language_name) |
local example_text = args.example or example_default_text | local example_text = args.example or example_default_text | ||
| − | table.insert(layout, string.format( | + | table.insert(layout, string.format(non_english_language_text_text_strings["LINE1"], language_name, language_name, script_text)) |
local lang_template = frame:expandTemplate{title = 'Tl', args = {"Lang"}} | local lang_template = frame:expandTemplate{title = 'Tl', args = {"Lang"}} | ||
| − | table.insert(layout, string.format( | + | table.insert(layout, string.format(non_english_language_text_text_strings["LINE2"], lang_template)) |
local language_code_link = lang_module._name_from_tag({language_code, link="yes", label=language_code}) | local language_code_link = lang_module._name_from_tag({language_code, link="yes", label=language_code}) | ||
| Line 279: | Line 250: | ||
local lang_x_template_example = frame:expandTemplate{title = 'Tlx', args = {lang_x.text, example_text}} | 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}} | local lang_x_template = frame:expandTemplate{title = lang_x.text, args = {example_text}} | ||
| − | line3_extra = string.format( | + | line3_extra = string.format(non_english_language_text_text_strings["LINE3_EXTRA"], lang_x_template_example, lang_x_template) |
end | end | ||
| − | table.insert(layout, string.format( | + | table.insert(layout, string.format(non_english_language_text_text_strings["LINE3"], lang_template_example, language_code, line3_extra)) |
see_also_section = get_see_also_section(page_title, language_name, language_code) | see_also_section = get_see_also_section(page_title, language_name, language_code) | ||
end | end | ||
| Line 287: | Line 258: | ||
end | end | ||
| − | local bottom = get_bottom_section(frame, language_name, see_also_section, "[[Category:Articles | + | local bottom = get_bottom_section(frame, language_name, see_also_section, non_english_language_text_text_strings["PARENT_CATEGORY"]) |
| + | return table.concat(layout, "\n\n") .. bottom | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< N O N _ E N G L I S H _ L A N G U A G E _ S O U R C E S _ C A T E G O R Y >------------------------- | ||
| + | |||
| + | {{#invoke:Lang/documentor tool|non_english_language_sources_category}} | ||
| + | |||
| + | This function implements {{Non-English-language sources category}}. | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local non_english_language_sources_text_strings = { | ||
| + | ["LINE1"] = "This is a tracking category for articles that use %s to identify %s sources.", | ||
| + | ["LANGUAGE_COLLECTIVE"] = "[[%s]]-collective", | ||
| + | ["LANGUAGE_NON_COLLECTIVE"] = '[[%s language|%s]]-language', | ||
| + | ["PARENT_CATEGORY"] = "[[Category:Articles with non-English-language sources]]", | ||
| + | } | ||
| + | |||
| + | local function non_english_language_sources_category(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(non_english_language_sources_text_strings["LANGUAGE_COLLECTIVE"], language_name) | ||
| + | else | ||
| + | language_link = string.format(non_english_language_sources_text_strings["LANGUAGE_NON_COLLECTIVE"], language_name, language_name) | ||
| + | end | ||
| + | |||
| + | local text = string.format(non_english_language_sources_text_strings["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, non_english_language_sources_text_strings["PARENT_CATEGORY"]) | ||
return table.concat(layout, "\n\n") .. bottom | return table.concat(layout, "\n\n") .. bottom | ||
end | end | ||
| − | --[[ | + | --[[-------------------------< N O N _ E N G L I S H _ L A N G U A G E _ C S 1 _ S O U R C E S _ C A T E G O R Y >------------------------- |
| + | |||
| + | {{#invoke:Lang/documentor tool|non_english_language_cs1_sources_category}} | ||
| + | |||
| + | This function implements {{Non-English-language CS1 sources category}}. | ||
| + | ]] | ||
| + | |||
| + | local non_english_language_cs1_text_strings = { | ||
| + | ["LINE1"] = "This is a tracking category for [[WP:CS1|CS1 citations]] that use the parameter %s to identify a source in [[%s language|%s]]. Pages in this category should only be added by CS1 templates and [[Module:Citation/CS1]].", | ||
| + | ["PARENT_CATEGORY"] = "[[Category:CS1 foreign language sources]]", -- #TODO change to "Articles with non-english CS1 language sources" or "CS1 non-English language sources" | ||
| + | } | ||
| + | |||
| + | local function non_english_language_cs1_sources_category(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 parameter_doc = frame:expandTemplate{title = 'para', args = {"language", language_code}} | ||
| + | table.insert(layout, get_top_section(frame)) | ||
| + | table.insert(layout, string.format(non_english_language_cs1_text_strings["LINE1"], parameter_doc, language_name, language_name)) | ||
| + | local see_also_section = get_see_also_section(page_title, language_name, language_code) | ||
| + | local bottom = get_bottom_section(frame, language_name, see_also_section, non_english_language_cs1_text_strings["PARENT_CATEGORY"]) | ||
| + | return table.concat(layout, "\n\n") .. bottom | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< S H A R E D _ T E S T C A S E S _ C O D E >------------------------- | ||
| + | |||
| + | Functions: | ||
| + | - get_unordered_list(language_list, list_modification, range) | ||
| + | - get_unordered_language_list_general(language_list, list_modification, range) | ||
| + | - get_unordered_language_list_variations(language_list) | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local function get_unordered_language_list_general(language_list, list_modification, range) | ||
| + | local unordered_table = {} | ||
| + | for language_code in pairs(language_list) do | ||
| + | if list_modification == "range" then | ||
| + | if language_code:find(range) then | ||
| + | table.insert(unordered_table, language_code) | ||
| + | end | ||
| + | elseif list_modification == "length" then | ||
| + | if string.len(language_code) == 2 then | ||
| + | table.insert(unordered_table, language_code) | ||
| + | end | ||
| + | else | ||
| + | table.insert(unordered_table, language_code) | ||
| + | end | ||
| + | end | ||
| + | return unordered_table | ||
| + | end | ||
| + | |||
| + | -- If placed inside get_unordered_language_list_general() the testcasts error: "Lua error: not enough memory". | ||
| + | local function get_unordered_language_list_variations(language_list) | ||
| + | local unordered_table = {} | ||
| + | for language_code, values in pairs(language_list) do | ||
| + | for _, language_prefix in pairs(values.prefixes) do | ||
| + | table.insert(unordered_table, language_prefix .. "-" .. language_code) | ||
| + | end | ||
| + | end | ||
| + | return unordered_table | ||
| + | end | ||
| + | |||
| + | local function get_unordered_list(language_list, list_modification, range) | ||
| + | if list_modification == "variants" then | ||
| + | return get_unordered_language_list_variations(language_list) | ||
| + | else | ||
| + | return get_unordered_language_list_general(language_list, list_modification, range) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | local function get_data_from_language_code(language_list, language_code, unordered_table, reverse_table) | ||
| + | for _, language_name in pairs(language_list[language_code]) do | ||
| + | table.insert(unordered_table, language_name) | ||
| + | reverse_table[language_name] = language_code | ||
| + | end | ||
| + | end | ||
| + | |||
| + | local function get_unordered_language_list_general_with_reverse_list(language_list, list_modification, range) | ||
| + | local unordered_table = {} | ||
| + | local reverse_table = {} | ||
| + | for language_code in pairs(language_list) do | ||
| + | if list_modification == "range" then | ||
| + | if language_code:find(range) then | ||
| + | get_data_from_language_code(language_list, language_code, unordered_table, reverse_table) | ||
| + | end | ||
| + | elseif list_modification == "length" then | ||
| + | if string.len(language_code) == 2 then | ||
| + | get_data_from_language_code(language_list, language_code, unordered_table, reverse_table) | ||
| + | end | ||
| + | else | ||
| + | get_data_from_language_code(language_list, language_code, unordered_table, reverse_table) | ||
| + | end | ||
| + | end | ||
| + | return unordered_table, reverse_table | ||
| + | end | ||
| + | |||
| + | local function get_unordered_language_list_variations_with_reverse_list(language_list) | ||
| + | local unordered_table = {} | ||
| + | local reverse_table = {} | ||
| + | for language_code, values in pairs(language_list) do | ||
| + | for _, language_name in pairs(values.descriptions) do | ||
| + | table.insert(unordered_table, language_name) | ||
| + | if #values.prefixes > 0 then | ||
| + | for _, language_prefix in pairs(values.prefixes) do | ||
| + | reverse_table[language_name] = language_prefix .. "-" .. language_code | ||
| + | end | ||
| + | else | ||
| + | reverse_table[language_name] = language_code | ||
| + | end | ||
| + | end | ||
| + | end | ||
| + | return unordered_table, reverse_table | ||
| + | end | ||
| + | |||
| + | local function get_unordered_and_reverse_lists(language_list, list_modification, range) | ||
| + | if list_modification == "variants" then | ||
| + | return get_unordered_language_list_variations_with_reverse_list(language_list) | ||
| + | else | ||
| + | return get_unordered_language_list_general_with_reverse_list(language_list, list_modification, range) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< T E S T C A S E S _ C A T E G O R Y _ F R O M _ T A G >------------------------- | ||
| + | |||
| + | Entry point for the various category_from_tag testcases. | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local function testcases_category_from_tag(self, args) | ||
| + | local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range) | ||
| + | local ordered_table = {} | ||
| + | table.sort(unordered_table) | ||
| + | for _, key in ipairs(unordered_table) do | ||
| + | table.insert(ordered_table, {key}) | ||
| + | end | ||
| + | |||
| + | self:preprocess_equals_preprocess_many( | ||
| + | '{{#invoke:Lang/sandbox|category_from_tag|', '}}', '{{#invoke:Lang|category_from_tag|', '}}', | ||
| + | ordered_table, | ||
| + | {nowiki=false, templatestyles=true} | ||
| + | ) | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< T E S T C A S E S _ N A M E _ F R O M _ T A G >------------------------- | ||
| + | |||
| + | Entry point for the various name_from_tag testcases. | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local function testcases_name_from_tag(self, args) | ||
| + | local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range) | ||
| + | local ordered_table = {} | ||
| + | local override_table = require("Module:Lang/data").override | ||
| + | table.sort(unordered_table) | ||
| + | for _, key in ipairs(unordered_table) do | ||
| + | local override_lang_table = override_table[key] | ||
| + | if override_lang_table then | ||
| + | table.insert(ordered_table, {key, override_lang_table[1]}) | ||
| + | elseif args.list_modification == "variants" then | ||
| + | local language_prefix, language_code = key:match("([^,]+)-([^,]+)") | ||
| + | table.insert(ordered_table, {key, args.language_list[language_code].descriptions[1]}) | ||
| + | else | ||
| + | table.insert(ordered_table, {key, args.language_list[key][1]}) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | self:preprocess_equals_preprocess_many( | ||
| + | '{{#invoke:Lang/sandbox|name_from_tag|', '}}', '', '', | ||
| + | ordered_table, | ||
| + | {nowiki=false, templatestyles=true} | ||
| + | ) | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< T E S T C A S E S _ T A G _ F R O M _ N A M E >------------------------- | ||
| + | |||
| + | Entry point for the various tag_from_name testcases. | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local function testcases_tag_from_name(self, args) | ||
| + | local unordered_table, reverse_table = get_unordered_and_reverse_lists(args.language_list, args.list_modification, args.range) | ||
| + | local ordered_table = {} | ||
| + | table.sort(unordered_table) | ||
| + | for _, key in ipairs(unordered_table) do | ||
| + | table.insert(ordered_table, {key, reverse_table[key]}) | ||
| + | end | ||
| + | |||
| + | self:preprocess_equals_preprocess_many( | ||
| + | '{{#invoke:Lang/sandbox|tag_from_name|', '}}', '', '', | ||
| + | ordered_table, | ||
| + | {nowiki=false, templatestyles=true} | ||
| + | ) | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< T E S T C A S E S _ I S O _ C O D E _ T O _ N A M E >------------------------- | ||
| + | |||
| + | Entry point for the various iso_code_to_name testcases. | ||
| + | |||
| + | ]] | ||
| + | |||
| + | local function testcases_iso_code_to_name(self, args) | ||
| + | local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range) | ||
| + | local ordered_table = {} | ||
| + | table.sort(unordered_table) | ||
| + | for _, key in ipairs(unordered_table) do | ||
| + | table.insert(ordered_table, {key}) | ||
| + | end | ||
| + | |||
| + | self:preprocess_equals_preprocess_many( | ||
| + | '{{#invoke:ISO 639 name/sandbox|iso_639_code_to_name|link=yes|', '}}', '{{#invoke:ISO 639 name|iso_639_code_to_name|link=yes|', '}}', | ||
| + | ordered_table, | ||
| + | {nowiki=false, templatestyles=true} | ||
| + | ) | ||
| + | end | ||
| + | |||
| + | |||
| + | --[[-------------------------< E X P O R T E D F U N C T I O N S >------------------------- | ||
]] | ]] | ||
return { | return { | ||
| − | |||
lang_xx_settings = lang_xx_settings, | lang_xx_settings = lang_xx_settings, | ||
uses_module = uses_module, | uses_module = uses_module, | ||
| − | non_en_src_cat = | + | articles_containing_language_text_category = non_english_language_text_category, |
| + | non_en_src_cat = non_english_language_sources_category, | ||
| + | non_english_language_cs1_sources_category = non_english_language_cs1_sources_category, | ||
| + | testcases_category_from_tag = testcases_category_from_tag, | ||
| + | testcases_name_from_tag = testcases_name_from_tag, | ||
| + | testcases_tag_from_name = testcases_tag_from_name, | ||
| + | testcases_iso_code_to_name = testcases_iso_code_to_name, | ||
} | } | ||
Revision as of 10:33, 22 September 2020
| This module depends on the following other modules: |
Module:Lang/documentor tool implements the following templates:
The module is also used to produce the following testcases:
- #invoke:Lang|name_from_tag – ISO 639-1, ISO 639-3-1, ISO 639-3-2, and ISO 639-3-3.
- #invoke:Lang|category_from_tag – ISO 639-1, ISO 639-3-1, ISO 639-3-2, and ISO 639-3-3.
- #invoke:Lang|name_from_tag – ISO 639-1, ISO 639-3-1, ISO 639-3-2, and ISO 639-3-3.
- #invoke:Lang|tag_from_name – ISO 639-1, ISO 639-3-1, ISO 639-3-2, and ISO 639-3-3.
- #invoke:ISO 639 name|iso_639_code_to_name – ISO 639-1, ISO 639-2, ISO 639-3-1, ISO 639-3-2, ISO 639-3-3, ISO 639-5, and ISO 639 deprecated.
require('Module:No globals');
local p = {};
--[[-------------------------< L A N G - X X _ S E T T I N G S >-------------------------
{{#invoke:Lang/documentor tool|lang_xx_settings|template={{ROOTPAGENAME}}}}
Reads the content of the template and extracts the parameters from {{#invoke:Lang|...}} 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 >-------------------------
{{#invoke:Lang/documentor tool|uses_module|template={{ROOTPAGENAME}}}}
Reads the content of the template to determine if this {{lang-xx}} 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
--[[-------------------------< S H A R E D _ C O D E >-------------------------
- Tables:
-- language_categories
-- error_messages
- Functions:
-- get_error_message(message)
-- get_see_also_section(page_title, language_name, language_code)
-- get_top_section(frame)
-- get_bottom_section(frame, language_name, see_also_section, parent_category)
]]
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",
["ENGLISH"] = "Articles containing explicitly cited %s-language text",
}
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('<span style="font-size:100%%; font-style:normal;" class="error">Error: %s </span>[[Category:Lang and lang-xx template errors]]', 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\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, '<div style="font-size:x-small;">' .. purge_module._main({"Purge page cache"}) .. '</div>')
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 G L I S H _ L A N G U A G E _ T E X T _ C A T E G O R Y >-------------------------
{{#invoke:Lang/documentor tool|non_english_language_text_category}}
This function implements {{Non-English-language text category}}.
]]
local non_english_language_text_text_strings = {
["LINE1"] = "This category contains articles with [[%s language|%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 <code><span lang="%s"></code>.%s',
["LINE3_EXTRA"] = " Also available is %s which displays as %s.",
["IN_SCRIPT"] = " (in %s)",
["EXAMPLE_DEFAULT_TEXT"] = "text in %s language here",
["PARENT_CATEGORY"] = "[[Category:Articles containing non-English-language text]]",
}
local function non_english_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 = ""
local suffix
if page_title_modified:find("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)
suffix = " languages"
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)
suffix = " languages"
elseif page_title_modified:find('explicitly cited') then
part1, part2 = language_categories["ENGLISH"]: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 full_language_tag_name = language_name
if suffix then
full_language_tag_name = language_name .. suffix
end
local lang_module = require('Module:Lang')
local language_code = lang_module._tag_from_name({full_language_tag_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(non_english_language_text_text_strings["IN_SCRIPT"], script)
else
script_text = ""
end
local example_default_text = string.format(non_english_language_text_text_strings["EXAMPLE_DEFAULT_TEXT"], language_name)
local example_text = args.example or example_default_text
table.insert(layout, string.format(non_english_language_text_text_strings["LINE1"], language_name, language_name, script_text))
local lang_template = frame:expandTemplate{title = 'Tl', args = {"Lang"}}
table.insert(layout, string.format(non_english_language_text_text_strings["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(non_english_language_text_text_strings["LINE3_EXTRA"], lang_x_template_example, lang_x_template)
end
table.insert(layout, string.format(non_english_language_text_text_strings["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, non_english_language_text_text_strings["PARENT_CATEGORY"])
return table.concat(layout, "\n\n") .. bottom
end
--[[-------------------------< N O N _ E N G L I S H _ L A N G U A G E _ S O U R C E S _ C A T E G O R Y >-------------------------
{{#invoke:Lang/documentor tool|non_english_language_sources_category}}
This function implements {{Non-English-language sources category}}.
]]
local non_english_language_sources_text_strings = {
["LINE1"] = "This is a tracking category for articles that use %s to identify %s sources.",
["LANGUAGE_COLLECTIVE"] = "[[%s]]-collective",
["LANGUAGE_NON_COLLECTIVE"] = '[[%s language|%s]]-language',
["PARENT_CATEGORY"] = "[[Category:Articles with non-English-language sources]]",
}
local function non_english_language_sources_category(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(non_english_language_sources_text_strings["LANGUAGE_COLLECTIVE"], language_name)
else
language_link = string.format(non_english_language_sources_text_strings["LANGUAGE_NON_COLLECTIVE"], language_name, language_name)
end
local text = string.format(non_english_language_sources_text_strings["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, non_english_language_sources_text_strings["PARENT_CATEGORY"])
return table.concat(layout, "\n\n") .. bottom
end
--[[-------------------------< N O N _ E N G L I S H _ L A N G U A G E _ C S 1 _ S O U R C E S _ C A T E G O R Y >-------------------------
{{#invoke:Lang/documentor tool|non_english_language_cs1_sources_category}}
This function implements {{Non-English-language CS1 sources category}}.
]]
local non_english_language_cs1_text_strings = {
["LINE1"] = "This is a tracking category for [[WP:CS1|CS1 citations]] that use the parameter %s to identify a source in [[%s language|%s]]. Pages in this category should only be added by CS1 templates and [[Module:Citation/CS1]].",
["PARENT_CATEGORY"] = "[[Category:CS1 foreign language sources]]", -- #TODO change to "Articles with non-english CS1 language sources" or "CS1 non-English language sources"
}
local function non_english_language_cs1_sources_category(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 parameter_doc = frame:expandTemplate{title = 'para', args = {"language", language_code}}
table.insert(layout, get_top_section(frame))
table.insert(layout, string.format(non_english_language_cs1_text_strings["LINE1"], parameter_doc, language_name, language_name))
local see_also_section = get_see_also_section(page_title, language_name, language_code)
local bottom = get_bottom_section(frame, language_name, see_also_section, non_english_language_cs1_text_strings["PARENT_CATEGORY"])
return table.concat(layout, "\n\n") .. bottom
end
--[[-------------------------< S H A R E D _ T E S T C A S E S _ C O D E >-------------------------
Functions:
- get_unordered_list(language_list, list_modification, range)
- get_unordered_language_list_general(language_list, list_modification, range)
- get_unordered_language_list_variations(language_list)
]]
local function get_unordered_language_list_general(language_list, list_modification, range)
local unordered_table = {}
for language_code in pairs(language_list) do
if list_modification == "range" then
if language_code:find(range) then
table.insert(unordered_table, language_code)
end
elseif list_modification == "length" then
if string.len(language_code) == 2 then
table.insert(unordered_table, language_code)
end
else
table.insert(unordered_table, language_code)
end
end
return unordered_table
end
-- If placed inside get_unordered_language_list_general() the testcasts error: "Lua error: not enough memory".
local function get_unordered_language_list_variations(language_list)
local unordered_table = {}
for language_code, values in pairs(language_list) do
for _, language_prefix in pairs(values.prefixes) do
table.insert(unordered_table, language_prefix .. "-" .. language_code)
end
end
return unordered_table
end
local function get_unordered_list(language_list, list_modification, range)
if list_modification == "variants" then
return get_unordered_language_list_variations(language_list)
else
return get_unordered_language_list_general(language_list, list_modification, range)
end
end
local function get_data_from_language_code(language_list, language_code, unordered_table, reverse_table)
for _, language_name in pairs(language_list[language_code]) do
table.insert(unordered_table, language_name)
reverse_table[language_name] = language_code
end
end
local function get_unordered_language_list_general_with_reverse_list(language_list, list_modification, range)
local unordered_table = {}
local reverse_table = {}
for language_code in pairs(language_list) do
if list_modification == "range" then
if language_code:find(range) then
get_data_from_language_code(language_list, language_code, unordered_table, reverse_table)
end
elseif list_modification == "length" then
if string.len(language_code) == 2 then
get_data_from_language_code(language_list, language_code, unordered_table, reverse_table)
end
else
get_data_from_language_code(language_list, language_code, unordered_table, reverse_table)
end
end
return unordered_table, reverse_table
end
local function get_unordered_language_list_variations_with_reverse_list(language_list)
local unordered_table = {}
local reverse_table = {}
for language_code, values in pairs(language_list) do
for _, language_name in pairs(values.descriptions) do
table.insert(unordered_table, language_name)
if #values.prefixes > 0 then
for _, language_prefix in pairs(values.prefixes) do
reverse_table[language_name] = language_prefix .. "-" .. language_code
end
else
reverse_table[language_name] = language_code
end
end
end
return unordered_table, reverse_table
end
local function get_unordered_and_reverse_lists(language_list, list_modification, range)
if list_modification == "variants" then
return get_unordered_language_list_variations_with_reverse_list(language_list)
else
return get_unordered_language_list_general_with_reverse_list(language_list, list_modification, range)
end
end
--[[-------------------------< T E S T C A S E S _ C A T E G O R Y _ F R O M _ T A G >-------------------------
Entry point for the various category_from_tag testcases.
]]
local function testcases_category_from_tag(self, args)
local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range)
local ordered_table = {}
table.sort(unordered_table)
for _, key in ipairs(unordered_table) do
table.insert(ordered_table, {key})
end
self:preprocess_equals_preprocess_many(
'{{#invoke:Lang/sandbox|category_from_tag|', '}}', '{{#invoke:Lang|category_from_tag|', '}}',
ordered_table,
{nowiki=false, templatestyles=true}
)
end
--[[-------------------------< T E S T C A S E S _ N A M E _ F R O M _ T A G >-------------------------
Entry point for the various name_from_tag testcases.
]]
local function testcases_name_from_tag(self, args)
local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range)
local ordered_table = {}
local override_table = require("Module:Lang/data").override
table.sort(unordered_table)
for _, key in ipairs(unordered_table) do
local override_lang_table = override_table[key]
if override_lang_table then
table.insert(ordered_table, {key, override_lang_table[1]})
elseif args.list_modification == "variants" then
local language_prefix, language_code = key:match("([^,]+)-([^,]+)")
table.insert(ordered_table, {key, args.language_list[language_code].descriptions[1]})
else
table.insert(ordered_table, {key, args.language_list[key][1]})
end
end
self:preprocess_equals_preprocess_many(
'{{#invoke:Lang/sandbox|name_from_tag|', '}}', '', '',
ordered_table,
{nowiki=false, templatestyles=true}
)
end
--[[-------------------------< T E S T C A S E S _ T A G _ F R O M _ N A M E >-------------------------
Entry point for the various tag_from_name testcases.
]]
local function testcases_tag_from_name(self, args)
local unordered_table, reverse_table = get_unordered_and_reverse_lists(args.language_list, args.list_modification, args.range)
local ordered_table = {}
table.sort(unordered_table)
for _, key in ipairs(unordered_table) do
table.insert(ordered_table, {key, reverse_table[key]})
end
self:preprocess_equals_preprocess_many(
'{{#invoke:Lang/sandbox|tag_from_name|', '}}', '', '',
ordered_table,
{nowiki=false, templatestyles=true}
)
end
--[[-------------------------< T E S T C A S E S _ I S O _ C O D E _ T O _ N A M E >-------------------------
Entry point for the various iso_code_to_name testcases.
]]
local function testcases_iso_code_to_name(self, args)
local unordered_table = get_unordered_list(args.language_list, args.list_modification, args.range)
local ordered_table = {}
table.sort(unordered_table)
for _, key in ipairs(unordered_table) do
table.insert(ordered_table, {key})
end
self:preprocess_equals_preprocess_many(
'{{#invoke:ISO 639 name/sandbox|iso_639_code_to_name|link=yes|', '}}', '{{#invoke:ISO 639 name|iso_639_code_to_name|link=yes|', '}}',
ordered_table,
{nowiki=false, templatestyles=true}
)
end
--[[-------------------------< E X P O R T E D F U N C T I O N S >-------------------------
]]
return {
lang_xx_settings = lang_xx_settings,
uses_module = uses_module,
articles_containing_language_text_category = non_english_language_text_category,
non_en_src_cat = non_english_language_sources_category,
non_english_language_cs1_sources_category = non_english_language_cs1_sources_category,
testcases_category_from_tag = testcases_category_from_tag,
testcases_name_from_tag = testcases_name_from_tag,
testcases_tag_from_name = testcases_tag_from_name,
testcases_iso_code_to_name = testcases_iso_code_to_name,
}