Module:labels: Difference between revisions
No edit summary |
use large_pages in Module:headword/data instead of having it here |
||
| Line 3: | Line 3: | ||
export.lang_specific_data_list_module = "Module:labels/data/lang" | export.lang_specific_data_list_module = "Module:labels/data/lang" | ||
export.lang_specific_data_modules_prefix = "Module:labels/data/lang/" | export.lang_specific_data_modules_prefix = "Module:labels/data/lang/" | ||
local load_module = "Module:load" | local load_module = "Module:load" | ||
local parse_utilities_module = "Module:parse utilities" | local parse_utilities_module = "Module:parse utilities" | ||
local string_utilities_module = "Module:string utilities" | local string_utilities_module = "Module:string utilities" | ||
local utilities_module = "Module:utilities" | local utilities_module = "Module:utilities" | ||
local insert = table.insert | |||
local require_when_needed = require("Module:require when needed") | |||
local unpack = unpack or table.unpack -- Lua 5.2 compatibility | |||
local dump = mw.dumpObject | |||
local m_lang_specific_data = mw.loadData(export.lang_specific_data_list_module) | |||
local m_table = require_when_needed("Module:table") | |||
--[==[ intro: | --[==[ intro: | ||
| Line 41: | Line 48: | ||
local force_cat = false | local force_cat = false | ||
local | local m_headword_data = mw.loadData("Module:headword/data") | ||
local SUBPAGENAME = m_headword_data.pagename | |||
-- Disable tracking on heavy pages to save time. | -- Disable tracking on heavy pages to save time. | ||
local pages_where_tracking_is_disabled = | local pages_where_tracking_is_disabled = m_headword_data.large_pages | ||
[ | -- Add tracking category for PAGE. The tracking category linked to is [[Wiktionary:Tracking/labels/PAGE]]. | ||
-- pages | -- We also add to [[Wiktionary:Tracking/labels/PAGE/LANGCODE]] and [[Wiktionary:Tracking/labels/PAGE/MODE]] if | ||
[" | -- LANGCODE and/or MODE given. | ||
local function track(page, langcode, mode) | |||
if pages_where_tracking_is_disabled[SUBPAGENAME] then | |||
return true | |||
end | |||
-- avoid including links in pages (may cause error) | |||
page = page:gsub("%[", "("):gsub("%]", ")"):gsub("|", "!") | |||
require("Module:debug/track")("labels/" .. page) | |||
if langcode then | |||
require("Module:debug/track")("labels/" .. page .. "/" .. langcode) | |||
end | |||
if mode then | |||
require("Module:debug/track")("labels/" .. page .. "/" .. mode) | |||
end | |||
-- We don't currently add a tracking label for both langcode and mode to reduce the total number of labels, to | |||
-- save some memory. | |||
return true | |||
end | |||
local function ucfirst(txt) | local function ucfirst(txt) | ||
| Line 79: | Line 98: | ||
local allowed_values = {} | local allowed_values = {} | ||
for key, _ in pairs(mode_to_outer_class) do | for key, _ in pairs(mode_to_outer_class) do | ||
insert(allowed_values, "'" .. key .. "'") | |||
end | end | ||
table.sort(allowed_values) | table.sort(allowed_values) | ||
| Line 90: | Line 109: | ||
local mode_prefix = mode_to_property_prefix[mode] | local mode_prefix = mode_to_property_prefix[mode] | ||
return mode_prefix and labdata[mode_prefix .. prop] or labdata[prop] | return mode_prefix and labdata[mode_prefix .. prop] or labdata[prop] | ||
end | |||
local function check_type(label, lang, prop, value, expected_types) | |||
if value == nil or expected_types == nil then | |||
return value | |||
end | |||
if type(expected_types) ~= "table" then | |||
expected_types = {expected_types} | |||
end | |||
local valtype = type(value) | |||
local matches = false | |||
for _, expected_type in ipairs(expected_types) do | |||
if type(expected_type) == "string" then | |||
if valtype == expected_type then | |||
matches = true | |||
break | |||
end | |||
elseif value == expected_type then | |||
matches = true | |||
break | |||
end | |||
end | |||
if not matches then | |||
local function join_untagged_or(elements) | |||
return m_table.serialCommaJoin(elements, {conj = "or", dontTag = true}) | |||
end | |||
local quoted_types = {} | |||
local quoted_values = {} | |||
for _, expected_type in ipairs(expected_types) do | |||
if type(expected_type) == "string" then | |||
insert(quoted_types, "'" .. expected_type .. "'") | |||
else | |||
insert(quoted_values, "'" .. dump(expected_type) .. "'") | |||
end | |||
end | |||
local possible_matches = {} | |||
if quoted_types[1] then | |||
insert(possible_matches, ("be of type%s %s"):format( | |||
quoted_types[2] and "s" or "", join_untagged_or(quoted_types))) | |||
end | |||
if quoted_values[1] then | |||
insert(possible_matches, ("have the value%s %s"):format( | |||
quoted_values[2] and "s" or "", join_untagged_or(quoted_values))) | |||
end | |||
error(("Internal error: For label '%s', langcode '%s', property '%s' should %s but is of type '%s' with value %s"):format( | |||
label, lang and lang:getCode() or "UNKNOWN", prop, join_untagged_or(possible_matches), valtype, dump(value))) | |||
end | |||
end | end | ||
| Line 110: | Line 177: | ||
function export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang) | function export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang) | ||
local wikipedia_langs = {} | local wikipedia_langs = {} | ||
insert(wikipedia_langs, "en") | |||
if lang then | if lang then | ||
local article_lang = lang | local article_lang = lang | ||
| Line 117: | Line 184: | ||
local wmcodes = article_lang:getWikimediaLanguageCodes() | local wmcodes = article_lang:getWikimediaLanguageCodes() | ||
for _, wmcode in ipairs(wmcodes) do | for _, wmcode in ipairs(wmcodes) do | ||
insert(wikipedia_langs, wmcode) | |||
end | end | ||
end | end | ||
| Line 125: | Line 192: | ||
local family, wp_lang = unpack(family_to_wp_lang) | local family, wp_lang = unpack(family_to_wp_lang) | ||
if lang:inFamily(family) then | if lang:inFamily(family) then | ||
insert(wikipedia_langs, wp_lang) | |||
end | end | ||
end | end | ||
| Line 156: | Line 223: | ||
end | end | ||
local function labprop(prop) | local function labprop(prop, expected_types) | ||
local retval = getprop(labdata, mode, prop) | |||
check_type(canon_label, lang, prop, retval, expected_types) | |||
return retval | |||
end | end | ||
local empty_list = {} | local empty_list = {} | ||
| Line 193: | Line 262: | ||
end | end | ||
insert(categories, cat) | |||
end | end | ||
| Line 229: | Line 298: | ||
]==] | ]==] | ||
function export.get_submodules(lang) | function export.get_submodules(lang) | ||
local submodules = {} | local submodules = { | ||
"Module:labels/data", | |||
"Module:labels/data/qualifiers", | |||
"Module:labels/data/regional", | |||
"Module:labels/data/topical", | |||
} | |||
if not lang then | |||
return submodules | |||
end | |||
-- get language-specific labels from data module | -- get language-specific labels from data module | ||
local langcode = | local langcode = lang:getFullCode() | ||
if | if m_lang_specific_data.langs_with_lang_specific_modules[langcode] then | ||
-- prefer per-language label in order to pick subvariety labels over regional ones | -- prefer per-language label in order to pick subvariety labels over regional ones | ||
insert(submodules, 1, export.lang_specific_data_modules_prefix .. langcode) | |||
end | end | ||
return submodules | return submodules | ||
end | end | ||
| Line 261: | Line 336: | ||
mode = validate_mode(mode) | mode = validate_mode(mode) | ||
local function labprop(prop) | local function labprop(prop, expected_types) | ||
local retval = getprop(labdata, mode, prop) | |||
check_type(label, lang, prop, retval, expected_types) | |||
return retval | |||
end | end | ||
deprecated = deprecated or labprop("deprecated") | deprecated = deprecated or labprop("deprecated") | ||
| Line 278: | Line 355: | ||
end | end | ||
formatted_label = labprop("special_display"):gsub("<(.-)>", add_language_name) | formatted_label = labprop("special_display", "string"):gsub("<(.-)>", add_language_name) | ||
else | else | ||
--[=[ | --[=[ | ||
We proceed as follows: | |||
1. The display form comes from either (a) the `override_display` variable if set (this happens when | |||
the user uses a label like '!British'); (b) the `display` property, if set; or (c) the label iself. | |||
2. If the display form contains a link, use it directly and ignore the other display-related settings. | |||
(NOTE: Settings `Wikipedia` and `Wikidata` may still be used on the category page itself, by the | |||
category tree code.) | |||
3. Otherwise, use one of the other display-related settings, in the following order: | |||
`glossary` > `Wiktionary` > `Wikipedia` > `Wikidata`. Specifically: | |||
a. If any of the values is equal to `true`, that is equivalent to specifying a string consisting of | |||
the canonical label. | |||
b. If `glossary` is set, it specifies the anchor in [[Appendix:Glossary]]. | |||
c. If `Wiktionary` is set, it specifies an arbitrary Wiktionary page or page + anchor (e.g. a | |||
separate Appendix entry). | |||
d. If `Wikipedia` is set, it specifies an arbitrary Wikipedia article, or a list of such items (in | |||
this case, we select the first one, but the category tree uses all of them). | |||
e. If `Wikidata` is set, it specifies an arbitrary Wikidata item to retrieve a Wikipedia article from, | |||
or a list of such items (in this case, we select the first one, but the category tree uses all of | |||
them). If the item is of the form `wmcode:id`, the Wikipedia article corresponding to `id` in the | |||
`wmcode`-language Wikipedia is fetched if available. Otherwise, the English-language Wikipedia | |||
article corresponding to `id` is retrieved if available, falling back to the Wikimedia language(s) | |||
corresponding to `lang` and then (in certain cases) to the macrolanguage that `lang` is part of. | |||
Note that if `mode` is specified, prefixed properties (e.g. | Note that if `mode` is specified, prefixed properties (e.g. `accent_display` for `mode` == "accent", | ||
`form_display` for `mode` == "form") are checked before the bare equivalent (e.g. `display`). | |||
]=] | ]=] | ||
local display = override_display or labprop("display") or label | local display = override_display or labprop("display", "string") or label | ||
-- There are several 'Foo spelling' labels specially designed for use in the |from= param in | -- There are several 'Foo spelling' labels specially designed for use in the |from= param in | ||
| Line 319: | Line 397: | ||
formatted_label = display | formatted_label = display | ||
else | else | ||
local glossary = labprop("glossary") | local glossary = labprop("glossary", {"string", true}) | ||
local Wiktionary = labprop("Wiktionary") | local Wiktionary = labprop("Wiktionary", {"string", true}) | ||
local Wikipedia = labprop("Wikipedia") | local Wikipedia = labprop("Wikipedia", {"string", true, "table"}) | ||
local Wikidata = labprop("Wikidata") | local Wikidata = labprop("Wikidata", {"string", true, "table"}) | ||
if glossary then | if glossary then | ||
local glossary_entry = | local glossary_entry = glossary == true and label or glossary | ||
formatted_label = "[[ | formatted_label = "[[Appendix:Glossary#" .. glossary_entry .. "|" .. display .. "]]" | ||
elseif Wiktionary then | elseif Wiktionary then | ||
formatted_label = "[[ | local Wiktionary_entry = Wiktionary == true and label or Wiktionary | ||
if Wiktionary == display then | |||
formatted_label = "[[" .. display .. "]]" | |||
else | |||
formatted_label = "[[" .. Wiktionary_entry .. "|" .. display .. "]]" | |||
end | |||
elseif Wikipedia then | elseif Wikipedia then | ||
if type(Wikipedia) == "table" then | |||
Wikipedia = Wikipedia[1] | |||
end | |||
local Wikipedia_entry = Wikipedia == true and label or Wikipedia | |||
formatted_label = "[[w:" .. Wikipedia_entry .. "|" .. display .. "]]" | formatted_label = "[[w:" .. Wikipedia_entry .. "|" .. display .. "]]" | ||
elseif Wikidata then | elseif Wikidata then | ||
| Line 389: | Line 475: | ||
`categories` to be formatted for documentation display. | `categories` to be formatted for documentation display. | ||
* `nocat`: If true, don't add the label to any categories. | * `nocat`: If true, don't add the label to any categories. | ||
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion | |||
pages). | |||
* `notrack`: Disable all tracking for this label. | * `notrack`: Disable all tracking for this label. | ||
* `sort`: Sort key for categorization. | |||
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according | * `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according | ||
to the display form of the label, so if two labels have the same display form, the second one won't be displayed | to the display form of the label, so if two labels have the same display form, the second one won't be displayed | ||
| Line 422: | Line 511: | ||
* `label`: The formatted form of the label. This is what is actually shown to the user. If the label is recognized | * `label`: The formatted form of the label. This is what is actually shown to the user. If the label is recognized | ||
(found in some module), this will typically be in the form of a link. | (found in some module), this will typically be in the form of a link. | ||
* `categories`: A list of the categories to add the label to; an empty list | * `categories`: A list of the categories to add the label to; an empty list if `nocat` was specified. | ||
* `formatted_categories`: A string containing the formatted categories; {nil} if `nocat` or `for_doc` was specified, | * `formatted_categories`: A string containing the formatted categories; {nil} if `nocat` or `for_doc` was specified, | ||
or if `categories` is empty. Currently will be an empty string if there are categories to format but the namespace is | or if `categories` is empty. Currently will be an empty string if there are categories to format but the namespace is | ||
| Line 496: | Line 585: | ||
label = resolved_label or label | label = resolved_label or label | ||
break | break | ||
elseif not data.notrack then | |||
-- Track use of a label that fails the lang restriction. | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label]] | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LANGCODE]] | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL]] | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL/LANGCODE]] | |||
track("wrong-lang-label", data_langcode) | |||
track("wrong-lang-label/" .. label, data_langcode) | |||
if resolved_label then | |||
track("wrong-lang-label/" .. resolved_label, data_langcode) | |||
end | |||
end | end | ||
end | end | ||
| Line 515: | Line 615: | ||
-- Note that this is an alias and store the canonical version. | -- Note that this is an alias and store the canonical version. | ||
ret.canonical = label | ret.canonical = label | ||
end | |||
if not data.notrack then -- labprop("track") then -- track all labels now | |||
-- Track label (after converting aliases to canonical form; but also track raw label (alias) if different | |||
-- from canonical label). | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL]] | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/LANGCODE]] | |||
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/MODE]] | |||
track("label/" .. label, data_langcode, mode) | |||
if label ~= non_canonical then | |||
track("label/" .. non_canonical, data_langcode, mode) | |||
end | |||
end | end | ||
| Line 526: | Line 638: | ||
depcat = "<code>" .. depcat .. "</code>" | depcat = "<code>" .. depcat .. "</code>" | ||
end | end | ||
insert(ret.categories, depcat) | |||
end | end | ||
end | end | ||
| Line 552: | Line 664: | ||
local cats = export.fetch_categories(label, labdata, data.lang, mode, data.for_doc) | local cats = export.fetch_categories(label, labdata, data.lang, mode, data.for_doc) | ||
for _, cat in ipairs(cats) do | for _, cat in ipairs(cats) do | ||
insert(ret.categories, cat) | |||
end | end | ||
if not ret.categories[1] or data.for_doc then | if not ret.categories[1] or data.for_doc then | ||
| Line 560: | Line 672: | ||
else | else | ||
ret.formatted_categories = require(utilities_module).format_categories(ret.categories, data.lang, | ret.formatted_categories = require(utilities_module).format_categories(ret.categories, data.lang, | ||
data.sort, nil, force_cat) | data.sort, nil, force_cat or data.force_cat) | ||
end | end | ||
end | end | ||
| Line 626: | Line 738: | ||
* `mode`: How the label was invoked; see {get_label_info()} for more information. | * `mode`: How the label was invoked; see {get_label_info()} for more information. | ||
* `nocat`: If true, don't add the label to any categories. | * `nocat`: If true, don't add the label to any categories. | ||
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion | |||
pages). | |||
* `notrack`: Disable all tracking for this label. | * `notrack`: Disable all tracking for this label. | ||
* `sort`: Sort key for categorization. | * `sort`: Sort key for categorization. | ||
| Line 631: | Line 745: | ||
to the display form of the label, so if two labels have the same display form, the second one won't be displayed | to the display form of the label, so if two labels have the same display form, the second one won't be displayed | ||
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen. | (but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen. | ||
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this | |||
function running. | |||
]==] | ]==] | ||
function export.process_raw_labels(data) | function export.process_raw_labels(data) | ||
local label_infos = {} | local label_infos = {} | ||
if not data.ok_to_destructively_modify then | |||
data = m_table.shallowCopy(data) | |||
data.ok_to_destructively_modify = true | |||
end | |||
local function get_info_and_insert(label) | local function get_info_and_insert(label) | ||
-- Reuse this structure to save memory. | -- Reuse this structure to save memory. | ||
data.label = label | data.label = label | ||
insert(label_infos, export.get_label_info(data)) | |||
end | end | ||
| Line 649: | Line 768: | ||
if i % 2 == 1 then | if i % 2 == 1 then | ||
local raw_text_type = i == 1 and "begin" or i == #segments and "end" or "middle" | local raw_text_type = i == 1 and "begin" or i == #segments and "end" or "middle" | ||
insert(label_infos, {raw_text = raw_text_type, label = segment, categories = {}}) | |||
else | else | ||
local segment_labels = export.split_labels_on_comma(segment) | local segment_labels = export.split_labels_on_comma(segment) | ||
| Line 674: | Line 793: | ||
* `mode`: How the label was invoked; see {get_label_info()} for more information. | * `mode`: How the label was invoked; see {get_label_info()} for more information. | ||
* `nocat`: If true, don't add the label to any categories. | * `nocat`: If true, don't add the label to any categories. | ||
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion | |||
pages). | |||
* `notrack`: Disable all tracking for this label. | * `notrack`: Disable all tracking for this label. | ||
* `sort`: Sort key for categorization. | * `sort`: Sort key for categorization. | ||
| Line 679: | Line 800: | ||
to the display form of the label, so if two labels have the same display form, the second one won't be displayed | to the display form of the label, so if two labels have the same display form, the second one won't be displayed | ||
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen. | (but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen. | ||
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this | |||
function running. | |||
]==] | ]==] | ||
function export.split_and_process_raw_labels(data) | function export.split_and_process_raw_labels(data) | ||
if not data.ok_to_destructively_modify then | |||
data = m_table.shallowCopy(data) | |||
data.ok_to_destructively_modify = true | |||
end | |||
data.labels = export.split_labels_on_comma(data.labels) | data.labels = export.split_labels_on_comma(data.labels) | ||
return export.process_raw_labels(data) | return export.process_raw_labels(data) | ||
| Line 697: | Line 822: | ||
* `labels`: List of the label objects to format, in the format returned by {get_label_info()}. | * `labels`: List of the label objects to format, in the format returned by {get_label_info()}. | ||
* `lang`: The language of the labels. | * `lang`: The language of the labels. | ||
* `open`: Open bracket or parenthesis to display before the concatenated labels. If specified, it is wrapped in the | * `open`: Open bracket or parenthesis to display before the concatenated labels. If specified, it is wrapped in the | ||
{"ib-brac"} CSS | {"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no open bracket is displayed. | ||
* `close`: Close bracket or parenthesis to display after the concatenated labels. If specified, it is wrapped in the | * `close`: Close bracket or parenthesis to display after the concatenated labels. If specified, it is wrapped in the | ||
{"ib-brac"} CSS | {"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no close bracket is displayed. | ||
* `no_ib_content`: By default, the concatenated formatted labels inside of the open/close brackets are wrapped in the | * `no_ib_content`: By default, the concatenated formatted labels inside of the open/close brackets are wrapped in the | ||
{"ib-content"} CSS | {"ib-content"} and {"label-content"} CSS classes. Specify this to suppress this wrapping. | ||
* `raw`: Suppress all CSS wrapping of content, including open/close parentheses, content and comma delimiters (which | |||
are normally wrapped in {"ib-comma"} and {"label-comma"} CSS classes). | |||
* `ok_to_destructively_modify`: If set, the `data` structure, and the `data.labels` table inside of it, will be | |||
destructively modified in the process of this function running. | |||
* `split_output`: If not given, the return value is a concatenation of the formatted concatenated labels and formatted | |||
categories. Otherwise, two values are returned: the formatted pronunciation and the categories. If `split_output` is | |||
the value {"raw"}, the categories are returned in list form, where the list elements are strings f the form suitable | |||
for passing to {format_categories()} in [[Module:utilities]]. If `split_output` is any other value besides {nil}, the | |||
categories are returned as a pre-formatted concatenated string. | |||
The return value (or the first return value, if `split_output` is given) is a string containing the contenated labels, | |||
Normally, labels are separated by comma-space sequences, but this may be suppressed for certain labels. If `nocat` | optionally surrounded by open/close brackets or parentheses. Normally, labels are separated by comma-space sequences, | ||
wasn't given to {get_label_info() or process_raw_labels()}, the label objects will contain formatted categories in | but this may be suppressed for certain labels. If `nocat` wasn't given to {get_label_info()} or {process_raw_labels()}, | ||
them, which will be inserted into the returned text. The concatenated text inside of the open/close brackets is normally | and `split_output` wasn't given, the label objects will contain formatted categories in them, which will be inserted | ||
wrapped in the {"ib-content"} CSS class, but this can be suppressed, as mentioned above | into the returned text. (Use `split_output` if you need the categories returned separately.) The concatenated text | ||
inside of the open/close brackets is normally wrapped in the {"ib-content"} CSS class, but this can be suppressed, as | |||
mentioned above. | |||
]==] | ]==] | ||
function export.format_processed_labels(data) | function export.format_processed_labels(data) | ||
if not data.labels then | if not data.labels then | ||
error("`data` must now be an object containing the params") | error("`data` must now be an object containing the params") | ||
end | |||
if not data.ok_to_destructively_modify then | |||
data = m_table.shallowCopy(data) | |||
data.labels = m_table.deepCopy(data.labels) | |||
data.ok_to_destructively_modify = true | |||
end | end | ||
local labels = data.labels | local labels = data.labels | ||
| Line 754: | Line 888: | ||
end | end | ||
local function wrap_css(txt, suffix) | |||
if data.raw then | |||
return txt | |||
end | |||
return ("<span class=\"ib-%s label-%s\">%s</span>"):format(suffix, suffix, txt) | |||
end | |||
local categories = nil | |||
local formatted_categories = split_output and split_output ~= "raw" and {} or nil | |||
for i, labelinfo in ipairs(labels) do | for i, labelinfo in ipairs(labels) do | ||
local label | local label | ||
| Line 764: | Line 907: | ||
label = "" | label = "" | ||
else | else | ||
label = (labelinfo.omit_comma and "" or | label = (labelinfo.omit_comma and "" or wrap_css(",", "comma")) .. | ||
(labelinfo.omit_space and "" or " ") .. | (labelinfo.omit_space and "" or " ") .. | ||
labelinfo.label | labelinfo.label | ||
end | end | ||
labels[i] = label .. (labelinfo.formatted_categories or "") | if split_output then | ||
labels[i] = label | |||
if split_output == "raw" then | |||
if labelinfo.categories and labelinfo.categories[1] then | |||
if categories then | |||
m_table.extend(categories, labelinfo.categories) | |||
else | |||
categories = labelinfo.categories | |||
end | |||
end | |||
elseif labelinfo.formatted_categories then | |||
insert(formatted_categories, labelinfo.formatted_categories) | |||
end | |||
else | |||
labels[i] = label .. (labelinfo.formatted_categories or "") | |||
end | |||
end | end | ||
local function wrap_open_close(val) | local function wrap_open_close(val) | ||
if val then | if val then | ||
return " | return wrap_css(val, "brac") | ||
else | else | ||
return "" | return "" | ||
| Line 781: | Line 939: | ||
local concatenated_labels = table.concat(labels, "") | local concatenated_labels = table.concat(labels, "") | ||
if not data.no_ib_content then | if not data.no_ib_content then | ||
concatenated_labels = " | concatenated_labels = wrap_css(concatenated_labels, "content") | ||
end | end | ||
local ret_labels = wrap_open_close(data.open) .. concatenated_labels .. wrap_open_close(data.close) | |||
if split_output == "raw" then | |||
return ret_labels, categories | |||
elseif split_output then | |||
return ret_labels, concat(formatted_categories) | |||
else | |||
return ret_labels | |||
end | |||
end | end | ||
| Line 796: | Line 961: | ||
* `mode`: How the label was invoked; see {get_label_info()} for more information. | * `mode`: How the label was invoked; see {get_label_info()} for more information. | ||
* `nocat`: If true, don't add the labels to any categories. | * `nocat`: If true, don't add the labels to any categories. | ||
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion | |||
pages). | |||
* `notrack`: Disable all tracking for these labels. | * `notrack`: Disable all tracking for these labels. | ||
* `sort`: Sort key for categorization. | * `sort`: Sort key for categorization. | ||
| Line 804: | Line 971: | ||
* `close`: Close bracket or parenthesis to display after the concatenated labels. If {nil}, defaults to a close | * `close`: Close bracket or parenthesis to display after the concatenated labels. If {nil}, defaults to a close | ||
parenthesis. Set to {false} to disable. | parenthesis. Set to {false} to disable. | ||
* `no_ib_content`: As in `format_processed_labels()`. | |||
* `raw`: As in `format_processed_labels()`. Also suppress wrapping the entire formatted result in a usage label CSS | |||
class (see below). | |||
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this | |||
function running. | |||
Compared with {format_processed_labels()}, this function has the following differences: | Compared with {format_processed_labels()}, this function has the following differences: | ||
| Line 810: | Line 982: | ||
# Tracking of already-seen labels is enabled unless explicitly turned off using `no_track_already_seen`. | # Tracking of already-seen labels is enabled unless explicitly turned off using `no_track_already_seen`. | ||
# The entire formatted result is wrapped in a {"usage-label-<var>type</var>"} CSS class (depending on the value of | # The entire formatted result is wrapped in a {"usage-label-<var>type</var>"} CSS class (depending on the value of | ||
`mode`) | `mode`), unless `raw` is given. | ||
]==] | ]==] | ||
function export.show_labels(data) | function export.show_labels(data) | ||
if not data.labels then | if not data.labels then | ||
error("`data` must now be an object containing the params") | error("`data` must now be an object containing the params") | ||
end | |||
if not data.ok_to_destructively_modify then | |||
data = m_table.shallowCopy(data) | |||
data.ok_to_destructively_modify = true | |||
end | end | ||
local labels = data.labels | local labels = data.labels | ||
| Line 837: | Line 1,011: | ||
end | end | ||
local formatted = export.format_processed_labels(data) | local formatted = export.format_processed_labels(data) | ||
return "<span class=\"" .. mode_to_outer_class[mode] .. "\">" .. formatted .. "</span>" | if data.raw then | ||
return formatted | |||
else | |||
return "<span class=\"" .. mode_to_outer_class[mode] .. "\">" .. formatted .. "</span>" | |||
end | |||
end | end | ||
--[==[Helper function for the data modules.]==] | --[==[Helper function for the data modules.]==] | ||
function export.alias(labels, key, aliases) | function export.alias(labels, key, aliases) | ||
m_table.alias(labels, key, aliases) | |||
end | end | ||
| Line 859: | Line 1,037: | ||
return link, display | return link, display | ||
end | end | ||
link = label:match("^%[%[([^%[%]|])+%]%]$") | |||
if link then | if link then | ||
return link, link | return link, link | ||
| Line 888: | Line 1,066: | ||
--[==[Used to finalize the data into the form that is actually returned.]==] | --[==[Used to finalize the data into the form that is actually returned.]==] | ||
function export.finalize_data(labels) | function export.finalize_data(labels) | ||
local shallow_copy = | local shallow_copy = m_table.shallowCopy | ||
local aliases = {} | local aliases = {} | ||
for label, data in pairs(labels) do | for label, data in pairs(labels) do | ||