La documentation pour ce module peut être créée à Module:Langue test/doc

local Langue = { }  -- Chargement de la base de données des langues avec gestion d'erreur. local dataLangue local moduleData = 'Module:Langue/Data' local langErrorMess = '<span class=error>langue non reconnue : %s</span>' local success, resultat = pcall (mw.loadData, moduleData ) success = success and type( resultat.en ) == 'table' if success then 	dataLangue = resultat else 	-- Base de données a minima en cas de bug sur le Module:Langue/Data 	dataLangue = { en = { code = 'en', nom = anglais }, 		fr = { code = 'fr', nom = 'français' }, 		de = { code = 'de', nom = 'allemand' }, 		es = { code = 'es', nom = 'espagnol' }, 		it = { code = 'it', nom = 'italien'  }, 		la = { code = 'la', nom = 'latin'    }, 		['rtl script'] = { Arab = true } 	} 	dataLangue.anglais = dataLangue.en 	dataLangue['français'] = dataLangue.fr 	dataLangue.allemand = dataLangue.de 	dataLangue.espagnol = dataLangue.es 	dataLangue.italien = dataLangue.it end  -- premierParametre renvoie le premier paramètre de Frame, que celui-ci ait été passé au module par invoke, directement au modèle, -- ou à l'intérieur d'un module sous forme de string dans un tableau ou directement de string. -- Si aucun de ces arguments ne contient de chaine, la fonction renvoie nil. -- Si le deuxième paramètre est true, la chaine est renvoyée trimée et en minuscules. local function premierParametre( frame, lowerCase ) 	local arg 	if type( frame ) == 'table' then 		arg = ( frame.getParent and ( frame.args[1] or frame:getParent().args[1] ) ) or frame[1] 	elseif type( frame ) == 'string' then 		arg = frame 	end 	if type( arg ) ~= 'string' then 		arg = nil 	end 	if arg and lowerCase then 		arg = mw.ustring.lower( mw.text.trim ( arg ) ) 	end 	return arg end  -- determinationCode retourne une table contenant le code de langue principal et la liste des subcode -- si le code de langue principal n'est pas reconnu, retourne nil. function Langue.determinationCode( langue ) 	if type( langue ) == 'string' and langue ~= '' then 		local tabCode = mw.text.split( langue, '-' ) 		local tabLangue = dataLangue[ mw.ustring.lower( tabCode[1] ) ] 		if tabLangue and tabLangue.code then 			tabCode[1] = tabLangue.code 			if tabLangue.invalide then 				tabCode.invalide=true 			end 			return tabCode 		end 	end end  -- Voir Modèle:Code langue -- Paramètre : --     1  : nom de langue. function Langue.codeLangue( frame ) 	local arg = premierParametre( frame, true ) 	local tabCode = Langue.determinationCode( arg ) 	return ( tabCode and table.concat( tabCode, '-' ) ) or arg or '' end  -- Voir Modèle:Code langue 2 -- Paramètre : --     1  : nom de langue. function Langue.codeLangue2( frame ) 	local arg = premierParametre( frame, true ) 	local tabCode = Langue.determinationCode( arg ) 	return ( tabCode and table.concat( tabCode, '-' ) ) or '' end   -- Voir Modèle:Direction langue -- Paramètre : --     1  : nom de langue ou code IETF. function Langue.directionLangue( frame ) 	local arg = premierParametre( frame, true ) 	if type( arg ) ~= 'string' or arg == '' then 		return 'ltr' 	end 	-- séparation du code de langue en code principal et les différents subcode. 	local tabCode = Langue.determinationCode( arg ) 	if tabCode then 		-- on essaye de savoir si la direction est de droite à gauche 		local codeScript = tabCode[2] 		if codeScript and string.len( codeScript ) == 4 and dataLangue[ 'rtl script' ] then 			-- il y a un subcode d'écritrure, c'est lui qui est pris en compte 			codeScript = string.upper( string.sub( codeScript, 1, 1 ) ) .. string.sub( codeScript, 2 ) 			if dataLangue[ 'rtl script' ][ codeScript ] then 				return 'rtl' 			end 		else 			-- il n'y a pas de sub-code d'écriture, on prend en compte le code de langue principal. 			local tabLangue = dataLangue[ tabCode[1] ] 			if tabLangue and tabLangue.rtl then 				return 'rtl' 			end 		end 	end 	 	-- la langue n'est pas écrite de droite à gauche, donc ltr. 	return 'ltr' end   -- Voir Modèle:Nom langue -- Paramètre : --     1  : code IETF de langue. function Langue.nomLangue( frame ) 	local arg = premierParametre( frame, true ) 	if type( arg ) ~= 'string' or arg == '' then 		return '<span class=error>langue non précisée</span>' 	end 	local tabLangue = dataLangue[ arg ] 	if tabLangue == nil then 		tabLangue = dataLangue[ mw.ustring.match( arg, '^(%a-)%-' ) ] 	end 	if tabLangue then 		local nom 		if type( tabLangue.page ) == 'string' then 			nom = tabLangue.page .. '|' .. tabLangue.nom 		else 			nom = tabLangue.nom 		end 		return '[[' .. nom .. ']]' 	else 		if success then 			return string.format( langErrorMess, arg ) 		else 			return '<span title="erreur dans ' .. moduleData .. '">' .. arg .. '</span>' 		end 	end end   -- Voir Modèle:Langue -- Paramètres : --    1 : code IETF de langue ; --    texte ou 2 : texte dans cette langue ; --    trans : translittération du texte ; --    dir : direction de la langue (obsolète : peut être en paramètre 1, avec code en 2 et texte en 3). function Langue.langue( frame ) 	local args = ( frame.getParent and frame:getParent().args ) or frame or { }         -- préparation pour appel par modèle ou direct. 	local code = mw.ustring.lower( mw.text.trim( args[1] or '' ) ) 	local texte = args.texte or '' 	if texte == '' then 		texte = args[2] or '' 	end 	local dir = args.dir 	local trans = args.trans 	 	-- Décalage des paramètres si code contient la direction du texte (obsolète mais toujours possible). 	if code == 'ltr' or code == 'rtl' then 		dir = code 		code = mw.ustring.lower( mw.text.trim( args[2] ) or '' ) 		texte = args[3] or '' 	end 	local codeArg = code 	 	-- Si la langue est reconnue, la valeur de la table est prise en compte (permet de corriger les noms de langue en toutes lettres). 	local tabCode = Langue.determinationCode( code ) 	local tabLangue 	if tabCode then 		code = table.concat( tabCode, '-' ) 		tabLangue = dataLangue[ tabCode[1] ] 		 		local codeScript = tabCode[2] 		-- Si codeScript est bien un style d'écriture (len = 4) on applique sa direction 		if codeScript and  string.len( codeScript ) == 4 and dataLangue[ 'rtl script' ] then 			-- formatage type Latn correspondant au fromat dans dataLangue[ 'rtl script' ] 			codeScript = string.upper( string.sub(  codeScript, 1, 1 ) ) .. string.sub(  codeScript, 2 ) 			tabLangue = { code = tabLangue.code, 				rtl = dataLangue[ 'rtl script' ][ codeScript ], 				invalide = tabLangue.invalide 			} 		end 	end 		 	-- Prépatation du rendu de direction du texte. 	dir = dir and dir:lower() 	if dir ~= 'ltr' and dir ~= 'rtl' then 		dir = ( tabLangue and tabLangue.rtl and 'rtl' ) 	end  	-- Translittération. 	local htmlTrans = mw.html.create() 	if trans and trans ~= '' then 		trans = trans:gsub( "^''([^'].*[^'])''$", "%1" ) 		htmlTrans:wikitext( " (''" ) 				:tag( 'span' ) 					:addClass( 'transcription lang-' .. code ) 					:attr( 'lang', code .. '-Latn' ) 					:attr( 'dir', 'ltr' ) 					:wikitext( trans ) 					:done() 				:wikitext( "'')" ) 	end  	-- Compilation du texte à retourner. 	local html = mw.html.create( '' ) 	if code == '' then 		html:wikitext( texte ) 	else 		html:tag( 'span' ) 				:addClass( 'lang-' .. code ) 				:attr{ lang = code, dir = dir } 				:wikitext( texte ) 				:done() 			:node( htmlTrans ) 	end  	-- Ajout de la catégorie Page avec code de langue invalide si le code langue non reconnu ou invalide. 	if success and ( type( tabLangue ) ~= 'table' or tabCode.invalide ) then 		local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [12] = true, [14] = true, [100] = true } 		if namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] then 			if codeArg == '' then 				codeArg = ' ' 	-- sinon la catégorie n'est pas wikifiée 			end 			html:wikitext( '[[Catégorie:Page avec code de langue invalide]] ' ) 				:wikitext( string.format( langErrorMess, codeArg ) ) 		end 	end  	return tostring( html ) end  function Langue.lang( frame ) 	return Langue.langue( frame ) end   -- Voir Modèle:Indication de langue -- Paramètres : --    1 : nom de langue ; --    2 : code IETF ; --    texte : texte dans cette langue ; --    dir : direction de la langue. function Langue.indicationDeLangue( frame ) 	local args = ( frame.getParent and frame:getParent().args ) or frame or { } 	local nomLangue = args[1] or '' 	local code = args.langue or mw.text.trim( args[2] or '' ) 	local texte = args.texte 	local dir = args.dir 	local wikiText = '' 	-- Cas où le premier et/ou le deuxième paramètre est vide. 	if code .. nomLangue == '' then 		return texte 	elseif nomLangue == '' then 		nomLangue = dataLangue[ mw.ustring.lower( code ) ] 		nomLangue = (nomLangue and nomLangue.nom or '???') 	elseif code == '' then 		code = dataLangue[ nomLangue ] 		code = ( code and code.code or '' ) 		if code == '' then 			return texte 		end 	end 	-- Gestion du texte. 	if texte and texte ~= '' then 		texte = '&nbsp;' .. Langue.lang{ code, dir = dir, texte = texte } 	else 		texte = '' 	end 	-- Compilation de l'indicateur de langue et du texte. 	local html = mw.html.create() 	html:tag( 'span' ) 			:addClass( 'indicateur-langue' ) 			:wikitext( '(' ) 			:tag( 'abbr' ) 				:addClass( 'abbr' ) 				:attr( 'title', 'Langue : ' .. nomLangue ) 				:wikitext( code ) 				:done() 			:wikitext( ')' ) 			:done() 		:wikitext( texte ) 	 	return tostring( html ) end  -- Voir Modèle:Multiling -- Paramètres : codes IETF ou noms de langue, en nombre indéfini (string ou nil uniquement). function Langue.indicationMultilingue( frame ) 	local args = (frame.getParent and frame:getParent().args) or frame 	local listeNom = { } 	local listeCode = { } 	local tabLangue 	-- Valeur par défaut du premier paramètre = 'mul'. 	local code = mw.text.trim( args[1] or '' ) 	if code == '' then 		code = 'mul' 	end 	 	if not args[2] and not dataLangue[ mw.ustring.lower( code ) ] then 		local split = mw.text.split( code, '[+,;:/ .]+' ) 		if #split > 1 then  			return Langue.indicationMultilingue( split ) 		end 	end 	-- Ajout des noms et codes de langue de chaque paramètre dans listeNom et ListeCode. 	local i = 1 	repeat 		code = mw.ustring.lower( code ) 		local tabLangue = dataLangue[ code ] 		if not tabLangue then 			code = mw.text.split( code, '-' )[1] 			tabLangue = dataLangue[ code ] 		end 		if type( tabLangue ) == 'table' then 			table.insert( listeNom, tabLangue.nom ) 			table.insert( listeCode, tabLangue.code ) 		elseif success then 			table.insert( listeNom, '???' ) 			local erreur = ' ' .. string.format( langErrorMess, code ) 			table.insert( listeCode, erreur ) 		else 			table.insert( listeNom, '??? (erreur dans ' .. moduleData .. ')' ) 			table.insert( listeCode, code ) 		end 		i = i + 1 		code = mw.text.trim( args[i] or '' ) 	until code == '' 	 	-- Préparation et renvoi du texte. 	local n = #listeCode 	local pluriel = '' 	if #listeCode == 0 then 		return '' 	elseif n > 1 then 		pluriel = 's' 	end 	 	local html = mw.html.create( 'span' ) 	html:addClass( 'indicateur-langue' ) 		:wikitext( '(' ) 		:tag( 'abbr' ) 			:addClass( 'abbr' ) 			:attr( 'title', 'Langue' .. pluriel .. ' : ' .. mw.text.listToText( listeNom ) ) 			:wikitext( table.concat( listeCode, '+' ) ) 			:done() 		:wikitext( ')' ) 		:done() 		 	return tostring( html ) end   -- Voir Modèle:Langue avec nom -- Paramètres : --    1 : code IETF de langue ; --    texte ou 2 : texte dans cette langue ; --    trans : translittération du texte ; --    dir : direction de la langue. function Langue.langueAvecNom( frame ) 	local args = ( frame.getParent and frame:getParent().args ) or frame or { } 	local code = mw.ustring.lower( mw.text.trim( args [1] or '') ) 	local texte = args.texte or args[2] or '' 	local trans = args.trans 	local dir = args.dir 	local wikiText = ''  	-- Détection de la direction du texte. 	if code == 'ltr' or code == 'rtl' then 		dir = code 		code = mw.ustring.lower( mw.text.trim( args[2] ) ) 		texte = args[3] or '' 	end  	-- Définition du nom de la langue en français. 	local nom = Langue.nomLangue{ code }  	if texte ~= '' then 		texte = '&nbsp;' .. Langue.lang{ code, dir = dir, texte = texte, trans = trans } 	end  	wikiText = nom .. ' :' .. texte  	return wikiText end  --- -- latinOnly détermine si la chaine fournie contien uniquement des caractère latin (étendu, unicode < 880) function Langue.nonLatin( frame ) 	local texte = premierParametre( frame ) 	for codepoint in mw.ustring.gcodepoint( texte ) do 		if codepoint > 879 and not (                  --  > 036F 			codepoint > 7423 and codepoint < 7936 or  -- suppléments phonétique, diacritiques et latin  (1D00 à 1EFF) 			codepoint > 8191 and codepoint < 11392 or -- espace, indices, monaies et symboles divers (2000 à 2C7F) 			codepoint > 42783 and codepoint < 43008   -- latin étendu D  (A720 à A7FF) 		) then 			return true 		end 	end 	return false end  -- erreurModuleData affiche un message d'erreur si le Module:Langue/Data n'a pas été chargé correctement, -- pour la page de discussion de la base de données et ceux qui veulent surveiller cette page. function Langue.erreurModuleData() 	if success == false then 		local message = [[<strong class="error">Le chargement du module Langue/Data génère une erreur : </strong> <br />%s <br />  <span class="error">Cette erreur doit être corrigée au plus vite car des milliers de pages ne s'affichent pas correctement.</span> ]] 		return string.format( message, resultat ) 	end end  -- tableauLangues génère un tableau triable de la liste des langues disponible dans Module:langue/Data. function Langue.tableauLangues() 	if type( dataLangue ) ~= 'table' then 		return 	end  	local tableau = { } 	local entete = [[{| class="wikitable alternance sortable" |- !scope=col|Alias !scope=col|Code IETF !scope=col|Nom principal !scope=col|Page (si différente du nom) !scope=col|RTL !scope=col|Invalide]]  	local ligneTab, ligneSrt 	for i, v in pairs( dataLangue ) do 		if v.code then 			ligneTab = { 				i, 				v.code, 				v.nom, 				v.page or '', 				v.rtl and '[[Image:Yes check.svg|15px|oui|lien=]]' or '', 				v.invalide and '[[Image:Yes check.svg|15px|oui|lien=]]' or '', 			} 			ligneSrt = table.concat( ligneTab, '\n|' ) 			table.insert( tableau, ligneSrt ) 		end 	end 	table.sort( tableau ) 	table.insert( tableau, 1, entete ) 	table.insert( tableau, '}' ) 	 	return table.concat( tableau, '\n|-\n|' ) end  -- listeCodeAlias génère une liste ; les langues sont la forme : * code : alias1, alias2 function Langue.listeCodeAlias () 	if type( dataLangue ) ~= 'table' then 		return 	end 	local languesTab, listeCodesAlias = { }, { } 	local code, alias, codeAlias 	for i, v in pairs( dataLangue ) do 		-- on construit un table avec pour indices les codes de langue, et pour valeurs une table avec la liste des alias 		code = v.code 		if code and not v.invalide then 			languesTab[code] = languesTab[code] or { } 			if i ~= mw.ustring.lower( code ) then 				table.insert( languesTab[code], i ) 			end 		end 	end 	for i, v in pairs( languesTab ) do 		-- transformation en un table séquence, avec pour valeur une chaine correspondant à une ligne de la liste 		alias = table.concat( v, ', ' ) 		if alias == '' then 			codeAlias = '\n* <code>' .. i .. '</code>' 		else 			codeAlias = '\n* <code>' .. i .. '</code> : ' .. alias 		end 		table.insert( listeCodesAlias, codeAlias ) 	end 	table.sort( listeCodesAlias ) 	 	return table.concat( listeCodesAlias ) end  -- listeCodeAlias génère une liste ; les langues sont la forme :  * code : alias1, alias2 function Langue.listeAliasCode () 	if type( dataLangue ) ~= 'table' then 		return 	end 	local languesTab = { '' } 	local code 	for i, v in pairs( dataLangue ) do 		-- on construit un table avec pour indices les codes de langue, et pour valeurs une table avec la liste des alias 		code = v.code 		if code and i ~= code and not v.invalide then 			table.insert( languesTab, i .. ' = ' .. code ) 		end 	end 	table.sort( languesTab ) 	 	return table.concat( languesTab, '\n*' ) end  return Langue