Module:Language with name/for

--[=[

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 '/'

|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
between {{{2}}} and the rest of the rendering

|paren= – takes one of three values:

'none' – omit left and right parens around ' for '

'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

( for '')

multiple terms

( for '' / '' / '')

|paren=none

for ''

|break=yes


( for '')

|italic-term=yes

( for '' / '' / '')

|lang-name=

( for '')

]=]

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 = {'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, ' (help)'); -- 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 /. 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 ('.+', '%1'); -- apply italic markup; html to avoid converting to ' when quoted

end

if is_italic or term:match ('[^\']\'\'$') then

term = term:gsub ('.+', ''%1'');

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' 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 or 'no' == args_t.link then

return args_t['lang-name'];

end

local lang_t = {}; -- holds component parts of language name link when using |lang-name=

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 ({ -- get language name (linked or not) from {{lang|fn=name_from_tag}}

link = args_t.links or args_t.link or 'yes', -- link language name by default

[1] = args_t['lang-name'] and 'mis' or args_t[1], -- when |language-name= something, use tag 'mis'; tag from {{{1}}} else

});

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 {{{1}}} and |lang-name= 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}}

['rtl']=args_t.rtl, -- used by {{lang}}

[1] = args_t['lang-name'] and 'mis' or args_t[1], -- used by {{lang}}

[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 '
' or ' '); --
when |break=yes; else

table.insert (out_t, left_paren); -- omit left paren around ' for ' when |paren=none or |paren=right

end

table.insert (out_t, lang_make (args_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 ' for ' 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

}