Jump to content

Module:Language with name/for

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Trappist the monk (talk | contribs) at 23:22, 10 March 2023 (create;). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
--[=[

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 (existing)
	{{{1}}} – language tag
	{{{2}}} – non-English 'term' to be wrapped in {{lang}} using tag in {{{1}}}
	{{{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= – one value 'none'; omit parens around '<language-name> for <term>'

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: '};						-- 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
		term = term:gsub ('.+', '&#39;%1&#39;');								-- quote using &#39; in case term uses italic or bold wikimarkup
		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 (args_t)
	if not args_t[2] then
		return '';
	end

	return lang_mod._lang ({args_t['lang-name'] and 'mis' or args_t[1], args_t[2]});
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)
	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 ({args_t[1], ['link']=args_t.links or 'yes'});	-- 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 out_t = {};
	if args_t[2] then															-- optional;  {{{2}}} may be omitted
		table.insert (out_t, text_make (args_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, 'none' == args_t.paren and '' or '(');				-- omit parens around '<language name> for <term>' when |paren=none
	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, (('none' == args_t.paren) or (not args_t[2])) and '' or ')');	-- omit parens when |paren=none and when {{{2}}} omitted
	
	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
	}