Jump to content

Module:ISO 639 name

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 11:57, 28 September 2018. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

require('Module:No globals');

local getArgs = require ('Module:Arguments').getArgs;


--[[--------------------------< E R R O R _ M E S S A G E S >--------------------------------------------------

TODO: change to default hiding of error messages?  show with with personal css override:
	.show_639_err_msgs {display: inline !important;}

]]

local error_messages = {
--	['err_msg'] = '<span style="font-size:100%; display:none" class="error show_639_err_msgs">error: $1</span>[[Category:ISO 639 name template errors]]',
	['err_msg'] = '<span style="font-size:100%;" class="error show_639_err_msgs">error: $1</span>[[Category:ISO 639 name template errors]]',
	['err_text'] = {
		['required'] = 'ISO 639 code is required',
		['name'] = 'language name required',
		['not_code'] = '$1 is not an ISO 639 code',
		['not_code1'] = '$1 is not an ISO 639-1 code',
		['not_code2'] = '$1 is not an ISO 639-2 code',
		['not_code3'] = '$1 is not an ISO 639-3 code',
		['not_code5'] = '$1 is not an ISO 639-5 code',
		['not_found'] = '$1 not found in ISO 639-$2 list',
		['nocode'] = 'no code in ISO 639-$1 for $2',
		['ietf'] = '$1 is an IETF tag',
		}
	}


--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.

]]

local function is_set( var )
	return not (var == nil or var == '');
end


--[=[-------------------------< M A K E _ W I K I L I N K >----------------------------------------------------

Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only
link is provided, returns a wikilink in the form [[L]]; if neither are provided or link is omitted, returns an
empty string.

]=]

local function make_wikilink (link, display)
	if is_set (link) then
		if is_set (display) then
			return table.concat ({'[[', link, '|', display, ']]'});
		else
			return table.concat ({'[[', link, ']]'});
		end
	else
		return '';
	end
end


--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------

Populates numbered arguments in a message string using an argument table.

]]

local function substitute (msg, args)
	return args and mw.message.newRawMessage (msg, args):plain() or msg;
end


--[[--------------------------< E R R O R _ M S G >------------------------------------------------------------

create an error message

]]

local function error_msg (msg, arg)
	return substitute (error_messages.err_msg, substitute (error_messages.err_text[msg], arg))
end


--[[--------------------------< L A N G _ N A M E _ G E T >----------------------------------------------------

returns first listed language name for code from data{} table; strips parenthetical disambiguation; wikilinks to
the language article if link is true; returns nil else

]]

local function lang_name_get (code, data, link)
	local name;
	
	if data[code] then
		name = data[code][1]:gsub ('%s*%b()', '');								-- get the name and strip parenthetical disambiguators if any
		if link then															-- make a link to the language article?
			if name:find ('languages') then
				name = make_wikilink (name);									-- simple wikilink for collective languages
			else
				name = make_wikilink (name .. ' language', name);				-- [[name language|name]]
			end
		end
		return name;
	end
end


--[[--------------------------< I S O _ 6 3 9 _ N A M E >------------------------------------------------------

template entry point; returns first language name that matches code from template frame or an error message

]]

local function iso_639_name (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('required');
	end
	
	local code = args[1];														-- used in error messaging
	local lc_code;																-- holds lowercase version of code for indexing into the data tables
	local ietf_err;																-- holds an error message when args[1] (language code) is an IETF tag
	local name;																	-- the retrieved language name
	local data = {};															-- holds one of the various 639 code to name tables
	
	code, ietf_err = code:gsub('(.-)%-.*', '%1');								-- strip ietf subtags; count is non-zero when subtags are stripped
	lc_code = code:lower();

	ietf_err = (0 ~= ietf_err) and error_msg ('ietf', args[1]) or '';			-- when tags are stripped create an error message; empty string for concatenation else

	if 2 > #code or 3 < #code then												-- 639 codes are 2 or three characters only
		return  table.concat ({code, ' ', error_msg ('not_code', code)});		-- return whatever is in code + an error message
	end

	data = mw.loadData ('Module:Sandbox/trappist the monk/ISO 639 name/ISO 639 override');	-- first look in the override table
	name = lang_name_get (lc_code, data, 'yes' == args.link);
	if name then
		return table.concat ({name, ' ', ietf_err});
	end

	if 2 == #lc_code then
		data = mw.loadData ('Module:Language/data/iana languages');				-- used only for ISO 639-1 language codes / names
		name = lang_name_get (lc_code, data, 'yes' == args.link);
		if name then
			return table.concat ({name, ' ', ietf_err});
		end
	else
		for _, source in ipairs ({
			'Module:Sandbox/trappist the monk/ISO 639 name/ISO 639-2',
			'Module:Language/data/ISO 639-3',
			'Module:Sandbox/trappist the monk/ISO 639 name/ISO 639-5'
			}) do
				data = mw.loadData (source);
				name = lang_name_get (lc_code, data, 'yes' == args.link);
				if name then
					return table.concat ({name, ' ', ietf_err});
				end
		end
	end
	
	return error_msg ('not_found', {code, '1, -2, -3, -5'});					-- here when code is not found in the data tables
end


--[[--------------------------< I S O _ 6 3 9 _ C O D E _ 1 >--------------------------------------------------

template entry point; returns first language name that matches ISO 639-1 code from template frame or an error message

]]

local function iso_639_code_1 (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('required');
	end
	
	local code = args[1];														-- used in error messaging
	local lc_code = code:lower();												-- holds lowercase version of code for indexing into the data tables

	local part1_data = mw.loadData ('Module:Language/data/iana languages');		-- used only for ISO 639-1 language codes / names

	if 2 ~= #lc_code then														-- 639-1 codes are 2 characters only
		return  error_msg ('not_code1', code);
	end

	return part1_data[lc_code] and part1_data[lc_code][1] or error_msg ('not_found', {code, 1});
end


--[[--------------------------< I S O _ 6 3 9 _ C O D E _ 2 >--------------------------------------------------

template entry point; returns first language name that matches ISO 639-1 code from template frame or an error message

]]

local function iso_639_code_2 (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('required');
	end
	
	local code = args[1];														-- used in error messaging
	local lc_code = code:lower();												-- holds lowercase version of code for indexing into the data tables

	local part2_data = mw.loadData ('Module:Sandbox/trappist the monk/ISO 639 name/ISO 639-2');		-- ISO 639-2 language codes / names; to be moved to Module:Language/data/ISO 639-2

	if 3 ~= #lc_code then														-- 639-2 codes are 3 characters only
		return  error_msg ('not_code2', code);
	end

	return part2_data[lc_code] and part2_data[lc_code][1] or error_msg ('not_found', {code, 2});
end


--[[--------------------------< I S O _ 6 3 9 _ C O D E _ 3 >--------------------------------------------------

template entry point; returns first language name that matches ISO 639-3 code from template frame or an error message

]]

local function iso_639_code_3 (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('required');
	end
	
	local code = args[1];														-- used in error messaging
	local lc_code = code:lower();												-- holds lowercase version of code for indexing into the data tables

	local part3_data = mw.loadData ('Module:Language/data/ISO 639-3');			-- ISO 639-3 language codes / names

	if 3 ~= #lc_code then														-- 639-3 codes are 3 characters only
		return  error_msg ('not_code3', code);
	end

	return part3_data[lc_code] and part3_data[lc_code][1] or error_msg ('not_found', {code, 3});
end


--[[--------------------------< I S O _ 6 3 9 _ C O D E _ 5 >--------------------------------------------------

template entry point; returns first language name that matches ISO 639-5 code from template frame or an error message

]]

local function iso_639_code_5 (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('required');
	end
	
	local code = args[1];														-- used in error messaging
	local lc_code = code:lower();												-- holds lowercase version of code for indexing into the data tables

	local part5_data = mw.loadData ('Module:Sandbox/trappist the monk/ISO 639 name/ISO 639-5');		-- ISO 639-5 language codes / names; to be moved to Module:Language/data/ISO 639-5

	if 3 ~= #lc_code then														-- 639-5 codes are 3 characters only
		return  error_msg ('not_code5', code);
	end

	return part5_data[lc_code] and part5_data[lc_code][1] or error_msg ('not_found', {code, 5});
end


--[[--------------------------< I S O _ 6 3 9 _ N A M E _ T O _ C O D E >--------------------------------------------------

template entry point; returns ISO 639-1, -2, -3, or -5 code associated with language name according to part (1, 2, 3, 5) argument;
when part is not provided scans 1, 2, 3 , 5 and returns first code

]]

local function iso_639_name_to_code (frame)
	local args = getArgs(frame);
	
	if not args[1] then
		return error_msg ('name');
	end
	
	local name = args[1];														-- used in error messaging
	local lc_name = name:lower();												-- holds lowercase version of code for indexing into the data table
	local part = tonumber(args[2]);

	local name_data = mw.loadData ('Module:Sandbox/trappist the monk/ISO 639 name to code');	-- ISO 639 language names to code table; to be moved to Module:Language/data/ISO 639 name to code

	if name_data[lc_name] then
		if part then
			if '' ~= name_data[lc_name][part] then
				return name_data[lc_name][part];
			else
				return error_msg ('nocode', {part, name});						-- no code in ISO 639-part for language
			end
		else
			for _, v in ipairs ({1, 2, 3, 5-1}) do								-- no part provided, scan through list of get the first available code
				if '' ~= name_data[lc_name][v] then
					return name_data[lc_name][v];
				end
			end
		end
	else
		return error_msg ('not_found', {name, '1, -2, -3, -5'});
	end
end


--[[--------------------------< E X P O R T E D   F U N C T I O N S >------------------------------------------
]]

return {
	iso_639_name = iso_639_name,
	iso_639_code_1 = iso_639_code_1,
	iso_639_code_2 = iso_639_code_2,
	iso_639_code_3 = iso_639_code_3,
	iso_639_code_5 = iso_639_code_5,
	iso_639_name_to_code = iso_639_name_to_code,
	};