Module:Current leader/sandbox
Appearance
| This is the module sandbox page for Module:Current leader (diff). |
| This module is rated as alpha. It is ready for limited use and third-party feedback. It may be used on a small number of pages, but should be monitored closely. Suggestions for new features or adjustments to input and output are welcome. |
Used by {{Current leader}}. Uses data from Module:Current leader/data.
Usage
[edit]{{#invoke:Current leader|main|country|title|link=[yes/no]|format=[invert/short]}}
require ('strict');
local get_args = require ('Module:Arguments').getArgs;
local data = mw.loadData ('Module:Current leader/data/sandbox');
--[[--------------------------< F O R M A T _ N A M E >--------------------------------------------------------
leader name is expected to match our article title for that leader including parenthetical or natural disambiguation.
this function strips disambiguation and return the properly linked leader's name or, when |link=no, the unlinked
leader name.
leader names listed in <no_link_name_t> will not be linked
]]
local function format_name (leader_data_t, args_t, link, frame)
local display_name;
local name;
if 'table' == type (leader_data_t) then -- <leader_data_t> can be a string or a table
if 'short' == args_t.format then -- short format defaults to last name
local short = leader_data_t.short or (leader_data_t.last and 'last' or nil); -- overridden by <short> in <leader_data_t>; Kristrún Frostadóttir → Kristrún
display_name = leader_data_t[short] or short; -- set the display name
name = leader_data_t[1]; -- set the link name
elseif 'invert' == args_t.format then -- Kristrún Frostadóttir → Frostadóttir, Kristrún
if leader_data_t.last and leader_data_t.first then
local separator = leader_data_t.last_first and ' ' or '53P'; -- for asian names use a space separateor; all other use '53P' to fool the disambiguator detector
display_name = string.format ('%s%s%s', leader_data_t.last, separator, leader_data_t.first); -- make an inverted display name
end
name = leader_data_t[1]; -- set the link name
else
name = leader_data_t[1]; -- no special format
end
else
name = leader_data_t; -- <leader_data_t> was a string (just a name)
end
for _, pattern in ipairs (data.dab_patterns_t) do
if not display_name and name:match (pattern) then -- if <display_name> not already set and leader name is disambiguated:
display_name = name:gsub (pattern, ''); -- remove disambiguator to create <display_name>
break; -- done so go make return value
end
end
if data.no_link_name_t[name:lower()] then -- when this 'name' matches
if frame and data.special_t[name:lower()] then
return frame:preprocess (data.special_t[name:lower()])
end
return name; -- do not link it, done
end
if display_name and display_name:match ('53P') then
display_name = display_name:gsub ('(.+)53P(.+)', '%1, %2'); -- <display_name> is inverted with comma separator
end
display_name = display_name and display_name:gsub (' +([IVX]+)$', ' %1'); -- for regnal names
name = name and name:gsub (' +([IVX]+)$', ' %1'); -- for regnal names
if link then -- linked name is the default case
if display_name then -- did we strip disambiguation?
return string.format ('[[%s|%s]]', name, display_name); -- create a link to dab'd article
else
return string.format ('[[%s]]', name); -- no disambiguation so make a simple link; for regnal names
end
else -- here when |link=no
return display_name or name;
end
end
--[[--------------------------< U N I N V E R T >--------------------------------------------------------------
uninvert inverted country names from the template's {{{1}}} parameter. There are a couple of common forms:
'korea, republic of' → 'republic of korea'
'comoros, union of the' → 'union of the comoros'; 'bahamas, the' → 'the bahamas'
where the inverted forms always contain a comma and always end in either 'of' or 'the'. country names like
'taiwan, china' are not inverted so are not changed by this function.
the purpose of this function is to ease the maintanance burden imposed by the requirement to include inverted
names in Module:Current leader/data
]]
local function uninvert (country_name)
for _, pattern in ipairs (data.uninvert_patterns) do -- loop through the <uninvert_patterns> sequence
local segment1, segment2 = country_name:match (pattern); -- try to match <country_name> with <pattern>
if segment1 then -- set when there is a match; nil else
return string.format ('%s %s', segment2, segment1); -- uninvert and return
end
end
return country_name; -- does not need uninversion so return <country_name> as is
end
--[[--------------------------< M A I N >----------------------------------------------------------------------
implements {{Current leader}}.
{{#invoke:Current leader}}
]]
local function main (frame)
local args_t = get_args (frame); -- fetch template parameters
local link = 'no' ~= args_t.link; -- default is true, always link; |link=no then set <link> false
local leader; -- <leader> can be either a sequence of names or a simple string
if args_t[1] and args_t[2] then -- must have both {{{1}}} and {{{2}}} (country and office)
local country = mw.ustring.lower(args_t[1]);
country = uninvert (country); -- uninvert inverted country names
local office = mw.ustring.lower(args_t[2]);
if data.synonyms_t[country] then
leader = data.synonyms_t[country][office];
if not leader then -- here when {{{2}}} is not a recognized office; emit error message and abandon
return string.format (data.error_messaging_t.fmt, data.error_messaging_t.office, office);
end
else -- here when {{{1}}} is not a recognized country synonym; emit error message and abandon
return string.format (data.error_messaging_t.fmt, data.error_messaging_t.country, country);
end
else -- here when missing one or both of {{{1}}} and {{{2}}}; emit error message and abandon
return string.format (data.error_messaging_t.fmt, data.error_messaging_t.missing, '');
end
local collection_t = {}; -- collection of formatted leader names goes here
if 'table' == type (leader) then
if 'table' == type (leader[1]) and 'table' == type (leader[2]) then -- multiple new-format leader names
for k, v_t in ipairs (leader) do
collection_t[k] = format_name (v_t, args_t, link); -- format and add to the collection
end
elseif 'string' == type (leader[1]) and 'string' == type (leader[2]) then -- multiple plain-format leader names
for k, v in ipairs (leader) do
collection_t[k] = format_name (v, args_t, link); -- format and add to the collection
end
else -- here when <leader[1]> is a string; single new-format leader name
collection_t[1] = format_name (leader, args_t, link, frame); -- format and add to the collection
end
else -- must be a string; single plain-format leader name
collection_t[1] = format_name ({leader}, args_t, link, frame); -- format and add to the collection
end
if 'invert' == args_t.format then
collection_t['comma'] = '; '; -- for inverted lists specify a <semicolon><space> separator between leaders
end
return frame:expandTemplate ({title = 'enum', args = collection_t}); -- make a prose-style list and done
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
main = main
}