--[=[
This module is a rewrite of the existing wikitext template {{Language with name/for}}. The primary purpose of
the rewrite is to bring the non-English text into the template so that it can be marked up by {{lang}}.
To accomodate the variety of uses of the template, news parameters are introduced to allow variable styling.
supported parameters (original)
{{{1}}} – language tag
{{{2}}} – non-English 'term' to be wrapped in {{lang}} using tag in {{{1}}}; modified to accept keyword 'none' to prevent categorization
{{{3}}} – English translation of {{{2}}} in single quotes; alias: |term1=
|links= – 'yes' or 'no'; default is 'yes'; links language name derived from {{{2}}}
supported parameters (new)
|term1= – alias of {{{3}}}
|term2= .. |termn= – additional 'or'-like translations; each rendered in single quotes; quoted terms separated by '<space>/<space>'
|italic-term= 'yes' or 'no'; default is 'no'; useful to multi-term translations when all should be italicized
|lang-name= – for those cases where ISO 639 does not have a language tag; {{{1}}} ignored; template wraps {{{2}}} with {{lang}} using 'mis' (uncoded language)
|break= – 'yes' or 'no'; default is 'no'; inserts <br /> between {{{2}}} and the rest of the rendering
|paren= – takes one of three values:
'none' – omit left and right parens around '<language-name> for <term>'
'left' – includes left paren, omits right paren
'right' – includes right paren, omits left paren
because this template now calls {{lang}} properly, it also supports the {{lang}} parameters:
|rtl=
|italic= (and aliases |italics= and |i=)
|size=
|cat=
|nocat=
basic rendering
<non-English text> (<language-name> for '<term>')
multiple terms
<non-English text> (<language-name> for '<term>' / '<term>' / '<term>')
|paren=none
<non-English text> <language-name> for '<term>'
|break=yes
<non-English text><br />(<language-name> for '<term>')
|italic-term=yes
<non-English text> (<language-name> for '<i><term></i>' / '<i><term></i>' / '<i><term></i>')
|lang-name=<lang-name>
<non-English text> ([[<lang-name> language|<lang-name>]] for '<term>')
]=]
require ('strict');
local get_args = require ('Module:Arguments').getArgs;
local lang_mod = require ('Module:Lang');
--[[--------------------------< E R R O R _ M E S S A G E >----------------------------------------------------
render an error message with help-text link and category.
]]
local function error_message (message)
local err_msg_t = {'<span style="color:#d33">Error: {{language with name/for}}: '}; -- open span and initial bit of the error message
table.insert (err_msg_t, message); -- the rest of the message
table.insert (err_msg_t, ' ([[Template:Language with name/for|help]])</span>'); -- the help link
local namespace = mw.title.getCurrentTitle().namespace; -- namespace number
if 0 == namespace or 10 == namespace then
table.insert (err_msg_t, '[[Category:Language with name/for errors]]'); -- categorize in main and template namespaces
end
return table.concat (err_msg_t); -- make a big string and done
end
--[[--------------------------< T E R M S _ G E T >------------------------------------------------------------
get value(s) assigned to {{{3}}} or to any number of |termn= parameters. Return a string where each term is in
single quotes. If more than one |termn= parameter, separate each term with <space>/<space>. Apply italic markup
when |itlaic-term=yes
]]
local function terms_get (args_t)
local function render_term (term, is_italic) -- local function to do the rendering
if is_italic then
term = term:gsub ('.+', '<i>%1</i>'); -- apply italic markup; html to avoid converting '' to ''' when quoted
end
if is_italic or term:match ('[^\']\'\'$') then
term = term:gsub ('.+', ''%1<span style="margin-left:.09em">'</span>');
else
term = term:gsub ('.+', ''%1''); -- quote using ' in case term uses italic or bold wikimarkup
end
return term; -- done this was to avoid second string.gsub() return value
end
local is_italic = 'yes' == args_t['italic-term']; -- make boolean
if args_t[3] then -- if {{{3}}} has a value
return render_term (args_t[3], is_italic);
end
local terms = {}; -- a table to hold one or more non-English terms
for k, v in pairs (args_t) do
if 'string' == type (k) and k:match ('term%d') then -- string parameter names only
table.insert (terms, k:match ('term(%d+)') .. '=' .. v); -- convert k/v pairs to a sequence that can be sorted by |termn= enumerator (enum=term)
end
end
table.sort (terms, function (a, b) -- sort the sequence using local sort function
local enum_a = a:match ('^%d+'); -- make numbers for the comparison
local enum_b = b:match ('^%d+');
return tonumber(enum_a) < tonumber(enum_b) -- and compare
end
);
for i, v in ipairs (terms) do -- rewrite the sequence to be sorted sequence of terms
terms[i] = render_term (v:gsub ('%d+=(.+)', '%1'), is_italic); -- extract term; italicize as required, and quote
end
return table.concat (terms, ' / '); -- form a string and done
end
--[[--------------------------< T E X T _ M A K E >------------------------------------------------------------
if {{{2}}} has a value (the non-English text) use {{lang}} to apply proper html markup. When |lang-name= has a
value, override any value that might be in {{{1}}} with 'mis' (uncoded languages)
TODO: error condition when both of {{{2}}} and |lang-name= have values?
]]
local function text_make (lang_params_t)
if not lang_params_t[2] then
return '';
end
return lang_mod._lang (lang_params_t);
end
--[[--------------------------< L A N G _ M A K E >------------------------------------------------------------
render the language name portion of the output. |lang-name= overrides {{{1}}}. Language name links to language
article through '<language name> language' redirect except when |links=no
]]
local function lang_make (args_t, lang_params_t)
if args_t['lang-name'] then
if 'no' == args_t.links then
return args_t['lang-name'];
end
local lang_t = {}; -- holds component parts of language name link when using |lang-name=<language>
table.insert (lang_t, '[['); -- open wikilink
table.insert (lang_t, args_t['lang-name']); -- add the name from |lang-name=
table.insert (lang_t, ' language|'); -- add ' languge' for redirect and pipe for link label
table.insert (lang_t, args_t['lang-name']); -- add language name as label for wikilink
table.insert (lang_t, ']]'); -- close wikilink
return table.concat (lang_t); -- and make a big string and done
end
return lang_mod._name_from_tag (lang_params_t); -- get language name (linked or not) from {{lang|fn=name_from_tag}}
end
--[[--------------------------< _ L A N G N F >----------------------------------------------------------------
entry point from another module
]]
local function _langnf (args_t)
if not (args_t[1] or args_t['lang-name']) then
return error_message ('missing language tag or language name');
end
if (args_t[1] and args_t['lang-name']) then
return error_message ('only one of <kbd>{{{1}}}</kbd> and <kbd>|lang-name=</kbd> allowed');
end
if not (args_t[3] or args_t.term1) then
return error_message ('missing English translation');
end
local lang_params_t = { -- build a table of parameters to be used by {{lang}}
link = args_t.links or 'yes', ['rtl']=args_t.rtl, -- used by {{lang|fn=tag_from_name}}
[1] = args_t['lang-name'] and 'mis' or args_t[1], -- used by {{lang}} and by {{lang|fn=tag_from_name}}
[2] = args_t[2], -- the rest of these are {{lang}} parameters used only by {{lang}}
rtl = args_t.rtl, -- right-to-left; not normally needed
i = args_t.i, -- |italic= alias
italic = args_t.italic,
italics = args_t.italics, -- |italic= alias
size = args_t.size,
cat = args_t.cat,
nocat = args_t.nocat,
template = 'Language with name/for',
}
local out_t = {}; -- components of the rendering go here
local left_paren = ('none' == args_t.paren or 'right' == args_t.paren) and '' or '(';
local right_paren = (not args_t[2] or 'none' == args_t[2] or 'left' == args_t.paren or 'none' == args_t.paren) and '' or ')';
if args_t[2] and ('none' ~= args_t[2]) then -- optional; {{{2}}} may be omitted; keyword 'none' prevents categorization; used in {{infobox papal document}}
table.insert (out_t, text_make (lang_params_t)); -- the non-English text marked up by {{lang}}
table.insert (out_t, 'yes' == args_t['break'] and '<br />' or ' '); -- <br /> when |break=yes; <space> else
table.insert (out_t, left_paren); -- omit left paren around '<language name> for <term>' when |paren=none or |paren=right
end
table.insert (out_t, lang_make (args_t, lang_params_t)); -- language name; linked unless |links=no
table.insert (out_t, ' for '); -- the 'for' static text
table.insert (out_t, terms_get (args_t)); -- and the term(s) italicized as appropriate and quoted
table.insert (out_t, right_paren); -- omit right paren around '<language name> for <term>' when |paren=none or |paren=left or {{{2}}} omitted
if not args_t[2] then -- if this template doesn't use {{{2}}} for the non-English text
table.insert (out_t, '[[Category:Pages with Langnf omitting second positional parameter]]'); -- add this category
end
return table.concat (out_t); -- make a big string and done
end
--[[--------------------------< L A N G N F >------------------------------------------------------------------
implements {{language with name/for}}
{{#invoke:Language with name/for|langnf}}
]]
local function langnf (frame)
local args_t = get_args (frame);
return _langnf (args_t)
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
langnf = langnf, -- entry point from a template
_langnf = _langnf, -- entry point from another module
}