Diqqət! 4 aprel 2024-cü il tarixdən saytın yeni versiyası sheki.org domenində fəaliyyət göstərir. Bu köhnə versiyadır və yenilənməsi məhdudlaşdırılıb.

"Module:Dil" səhifəsinin versiyaları arasındakı fərqlər

Şəki Ensiklopediyası səhifəsi
Jump to navigation Jump to search
k (WikiSysop moved page Module:Lang to Module:Dil without leaving a redirect)
 
(Eyni redaktor tərəfindən edilmiş bir dəyişiklik göstərilmir)
Sətir 1: Sətir 1:
--[=[
+
local Langue = { }
  
Lua support for the {{lang}}, {{lang-xx}}, and {{transl}} templates and replacement of various supporting templates.  
+
local dataLangue = mw.loadData 'Module:Dil/Data'
 +
local langErrorMess = '<span class="error">langue non reconnue : %s</span>'
  
]=]
+
-- 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.
require('Module:No globals');
+
-- 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 getArgs = require ('Module:Arguments').getArgs;
+
local function premierParametre( frame, lowerCase )
local unicode = require ("Module:Unicode data"); -- for is_latin() and is_rtl()
+
local arg
local yesno = require ('Module:Yesno');
+
if type( frame ) == 'table' then
 
+
arg = ( frame.getParent and ( frame.args[1] or frame:getParent().args[1] ) ) or frame[1]
local lang_data =  mw.loadData ('Module:Lang/data'); -- language name override and transliteration tool-tip tables
+
elseif type( frame ) == 'string' then
local lang_name_table = lang_data.lang_name_table; -- language codes, names, regions, scripts, suppressed scripts
+
arg = frame
local lang_table = lang_data.lang_name_table.lang;
 
local lang_dep_table = lang_data.lang_name_table.lang_dep;
 
local script_table = lang_data.lang_name_table.script;
 
local region_table = lang_data.lang_name_table.region;
 
local variant_table = lang_data.lang_name_table.variant;
 
local suppressed_table = lang_data.lang_name_table.suppressed;
 
local override_table = lang_data.override;
 
 
 
local synonym_table = mw.loadData ('Module:Lang/ISO 639 synonyms'); -- ISO 639-2/639-2T code translation to 639-1 code
 
 
 
local namespace = mw.title.getCurrentTitle().namespace; -- used for categorization
 
 
 
local this_wiki_lang = mw.language.getContentLanguage().code; -- get this wiki's language
 
 
 
local initial_style_state; -- set by lang_xx_normal() and lang_xx_italic()
 
 
 
local maint_cats = {}; -- maintenance categories go here
 
local maint_msgs = {}; -- and their messages go here
 
 
 
 
 
--[[--------------------------< 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
 
 
 
 
 
--[[--------------------------< I N V E R T  _ I T A L I C S >-------------------------------------------------
 
 
 
This function attempts to invert the italic markup a args.text by adding/removing leading/trailing italic markup
 
in args.text.  Like |italic=unset, |italic=invert disables automatic italic markup. Individual leading/trailing
 
apostrophes are converted to their html numeric entity equivalent so that the new italic markup doesn't become
 
bold markup inadvertently.
 
 
 
Leading and trailing wiki markup is extracted from args.text into separate table elements.  Addition, removal,
 
replacement of wiki markup is handled by a string.gsub() replacement table operating only on these separate elements.
 
In the string.gsub() matching pattern, '.*' matches empty string as well as the three expected wiki markup patterns.
 
 
 
This function expects that markup in args.text is complete and correct; if it is not, oddness may result.
 
 
 
]]
 
 
 
local function invert_italics (source)
 
local invert_pattern_table = { -- leading/trailing markup add/remove/replace patterns
 
[""]="\'\'", -- empty string becomes italic markup
 
["\'\'"]="", -- italic markup becomes empty string
 
["\'\'\'"]="\'\'\'\'\'", -- bold becomes bold italic
 
["\'\'\'\'\'"]="\'\'\'", -- bold italic become bold
 
};
 
local seg = {};
 
 
 
source = source:gsub ("%f[\']\'%f[^\']", '&#39;'); -- protect single quote marks from being interpreted as bold markup
 
 
 
seg[1] = source:match ('^(\'\'+%f[^\']).+') or ''; -- get leading markup, if any; ignore single quote
 
seg[3] = source:match ('.+(%f[\']\'\'+)$') or ''; -- get trailing markup, if any; ignore single quote
 
 
 
if '' ~= seg[1] and '' ~= seg[3] then -- extract the 'text'
 
seg[2] = source:match ('^\'\'+%f[^\'](.+)%f[\']\'\'+$') -- from between leading and trailing markup
 
elseif '' ~= seg[1] then
 
seg[2] = source:match ('^\'\'+%f[^\'](.+)') -- following leading markup
 
elseif '' ~= seg[3] then
 
seg[2] = source:match ('(.+)%f[\']\'\'+$') -- preceding trailing markup
 
else
 
seg[2] = source -- when there is no markup
 
 
end
 
end
 
+
if type( arg ) ~= 'string' then
seg[1] = invert_pattern_table[seg[1]] or seg[1]; -- replace leading markup according to pattern table
+
arg = nil
seg[3] = invert_pattern_table[seg[3]] or seg[3]; -- replace leading markup according to pattern table
 
 
 
return table.concat (seg); -- put it all back together and done
 
end
 
 
 
 
 
--[[--------------------------< V A L I D A T E _ I T A L I C >------------------------------------------------
 
 
 
validates |italic= or |italics= assigned values.
 
 
 
When |italic= is set and has an acceptible assigned value, return the matching css font-style property value or,
 
for the special case 'default', return nil.
 
 
 
When |italic= is not set, or has an unacceptible assigned value, return nil and a nil error message.
 
 
 
When both |italic= and |italics= are set, returns nil and a 'conflicting' error message.
 
 
 
The return value nil causes the calling lang, lang_xx, or transl function to set args.italic according to the template's
 
defined default ('inherit' for {{lang}}, 'inherit' or 'italic' for {{lang-xx}} depending on
 
the individual template's requirements, 'italic' for {{transl}}) or to the value appropriate to |script=, if set ({{lang}}
 
and {{lang-xx}} only).
 
 
 
Accepted values and the values that this function returns are are:
 
nil - when |italic= absent or not set; returns nil
 
default - for completeness, should rarely if ever be used; returns nil
 
yes - force args.text to be rendered in italic font; returns 'italic'
 
no - force args.text to be rendered in normal font; returns 'normal'
 
unset - disables font control so that font-style applied to text is dictated by markup inside or outside the template; returns 'inherit'
 
invert - disables font control so that font-style applied to text is dictated by markup outside or inverted inside the template; returns 'invert'
 
 
 
]]
 
 
 
local function validate_italic (args)
 
local properties = {['yes'] = 'italic', ['no'] = 'normal', ['unset'] = 'inherit', ['invert'] = 'invert', ['default'] = nil};
 
 
local count = 0
 
for _, arg in pairs {'italic', 'italics', 'i'} do
 
if args[arg] then
 
count = count + 1
 
end
 
 
end
 
end
 
+
if arg and lowerCase then
if count > 1 then -- return nil and an error message if more than one is set
+
arg = mw.ustring.lower( mw.text.trim( arg ) )
return nil, 'only one of |italic=, |italics=, or |i= can be specified';
 
 
end
 
end
+
return arg
return properties[args.italic or args.italics or args.i], nil; -- return an appropriate value and a nil error message
 
 
end
 
end
  
 
+
-- determinationCode retourne une table contenant le code de langue principal et la liste des subcode
--[=[--------------------------< V A L I D A T E _ C A T _ A R G S >----------------------------------------------------------
+
-- si le code de langue principal n'est pas reconnu, retourne nil.
 
+
function Langue.determinationCode( langue )
Default behavior of the {{lang}} and {{lang-xx}} templates is to add categorization when the templates are used in mainspace.
+
if type( langue ) == 'string' and langue ~= '' then
This default functionality may be suppressed by setting |nocat=yes or |cat=no.  This function selects one of these two parameters
+
local tabCode = mw.text.split( langue, '-' )
to control categorization.
+
local tabLangue = dataLangue[ mw.ustring.lower( tabCode[1] ) ]
 
+
if tabLangue and tabLangue.code then
Because having two parameters with 'opposite' names and 'opposite' values is confusing, this function accepts only affirmative
+
tabCode[1] = tabLangue.code
values for |nocat= and only negative values for |cat=; in both cases the 'other' sense (and non-sense) is not accepted and the
+
if tabLangue.invalide then
parameter is treated as if it were not set in the template.
+
tabCode.invalide=true
 
+
end
Sets args.nocat to true if categorization is to be turned off; to nil if the default behavior should apply.
+
return tabCode
 
+
end
Accepted values for |nocat= are the text strings:
 
'yes', 'y', 'true', 't', on, '1' -- [[Module:Yesno]] returns logical true for all of these; false or nil else
 
for |cat=
 
'no', 'n', 'false', 'f', 'off', '0' -- [[Module:Yesno]] returns logical false for all of these; true or nil else
 
 
 
]=]
 
 
 
local function validate_cat_args (args)
 
if not (args.nocat or args.cat) then -- both are nil, so categorize
 
return;
 
end
 
 
if false == yesno (args.cat) or true == yesno (args.nocat) then
 
args.nocat = true; -- set to true when args.nocat is affirmative; nil else (as if the parameter were not set in the template)
 
else -- args.nocat is the parameter actually used.
 
args.nocat = nil;
 
 
end
 
end
 
end
 
end
  
 
+
-- Voir Modèle:Code langue
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
+
-- Paramètre :
 
+
--     1  : nom de langue.
Whether needle is in haystack
+
function Langue.codeLangue( frame )
 
+
local arg = premierParametre( frame, true )
]]
+
local tabCode = Langue.determinationCode( arg )
 
+
return ( tabCode and table.concat( tabCode, '-' ) ) or arg or ''
local function in_array ( needle, haystack )
 
if needle == nil then
 
return false;
 
end
 
for n,v in ipairs( haystack ) do
 
if v == needle then
 
return n;
 
end
 
end
 
return false;
 
 
end
 
end
  
 
+
-- Voir Modèle:Code langue 2
--[[--------------------------< F O R M A T _ I E T F _ T A G >------------------------------------------------
+
-- Paramètre :
 
+
--     1  : nom de langue.
prettify ietf tags to use recommended subtag formats:
+
function Langue.codeLangue2( frame )
code: lower case
+
local arg = premierParametre( frame, true )
script: sentence case
+
local tabCode = Langue.determinationCode( arg )
region: upper case
+
return ( tabCode and table.concat( tabCode, '-' ) ) or ''
variant: lower case
 
private: lower case prefixed with -x-
 
 
]]
 
 
 
local function format_ietf_tag (code, script, region, variant, private)
 
local out = {};
 
 
 
if is_set (private) then
 
return table.concat ({code:lower(), 'x', private:lower()}, '-'); -- if private, all other tags ignored
 
end
 
 
table.insert (out, code:lower());
 
if is_set (script) then
 
script = script:lower():gsub ('^%a', string.upper);
 
table.insert (out, script);
 
end
 
 
 
if is_set (region) then
 
table.insert (out, region:upper());
 
end
 
 
if is_set (variant) then
 
table.insert (out, variant:lower());
 
end
 
 
return table.concat (out, '-');
 
 
end
 
end
  
  
--[[--------------------------< G E T _ I E T F _ P A R T S >--------------------------------------------------
+
-- Voir Modèle:Direction langue
 
+
-- Paramètre :
extracts and returns IETF language tag parts:
+
--     1 : nom de langue ou code IETF.
primary language subtag (required) - 2 or 3 character IANA language code
+
function Langue.directionLangue( frame )
script subtag - four character IANA script code
+
local arg = premierParametre( frame, true )
region subtag - two-letter or three digit IANA region code
+
if type( arg ) ~= 'string' or arg == '' then
variant subtag - four digit or 5-8 alnum variant code; only one variant subtag supported
+
return 'ltr'
private subtag - x- followed by 1-8 alnum private code; only supported with the primary language tag
 
 
 
in any one of these forms
 
lang lang-variant
 
lang-script lang-script-variant
 
lang-region lang-region-variant
 
lang-script-region lang-script-region-variant
 
lang-x-private
 
 
each of lang, script, region, variant, and private, when used, must be valid
 
 
 
Languages with both two- and three-character code synonyms are promoted to the two-character synonym because
 
the IANA registry file omits the synonymous three-character code; we cannot depend on browsers understanding
 
the synonymous three-character codes in the lang= attribute.
 
 
 
For {{lang-xx}} templates, the parameters |script=, |region=, and |variant= are supported (not supported in {{lang}}
 
because those parameters are superfluous to the IETF subtags in |code=)
 
 
 
returns six  values; all lower case. Valid parts are returned as themselves; omitted parts are returned as empty strings, invalid
 
parts are returned as nil; the sixth returned item is an error message (if an error detected) or nil.
 
 
 
see http://www.rfc-editor.org/rfc/bcp/bcp47.txt section 2.1
 
 
 
]]
 
 
 
local function get_ietf_parts (source, args_script, args_region, args_variant)
 
local code, script, region, variant, private; -- ietf tag parts
 
 
 
if not is_set (source) then
 
return nil, nil, nil, nil, nil, 'missing language tag';
 
 
end
 
end
 
+
-- séparation du code de langue en code principal et les différents subcode.
local pattern = { -- table of tables holding acceptibe ietf tag patterns and short names of the ietf part captured by the pattern
+
local tabCode = Langue.determinationCode( arg )
{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)%-(%d%d%d%d)$', 's', 'r', 'v'}, -- 1 -  ll-Ssss-RR-variant (where variant is 4 digits)
+
if tabCode then
{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)%-(%d%d%d%d)$', 's', 'r', 'v'}, -- 2 -  ll-Ssss-DDD-variant (where region is 3 digits; variant is 4 digits)
+
-- on essaye de savoir si la direction est de droite à gauche
{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'r', 'v'}, -- 3 -  ll-Ssss-RR-variant (where variant is 5-8 alnum characters)
+
local codeScript = tabCode[2]
{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'r', 'v'}, -- 4 -  ll-Ssss-DDD-variant (where region is 3 digits; variant is 5-8 alnum characters)
+
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
{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d%d)$', 's', 'v'}, -- 5 -  ll-Ssss-variant (where variant is 4 digits)
+
codeScript = string.upper( string.sub( codeScript, 1, 1 ) ) .. string.sub( codeScript, 2 )
{'^(%a%a%a?)%-(%a%a%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 's', 'v'}, -- 6 -  ll-Ssss-variant (where variant is 5-8 alnum characters)
+
if dataLangue[ 'rtl script' ][ codeScript ] then
+
return 'rtl'
{'^(%a%a%a?)%-(%a%a)%-(%d%d%d%d)$', 'r', 'v'}, -- 7 - ll-RR-variant (where variant is 4 digits)
+
end
{'^(%a%a%a?)%-(%d%d%d)%-(%d%d%d%d)$', 'r', 'v'}, -- 8 -  ll-DDD-variant (where region is 3 digits; variant is 4 digits)
+
else
{'^(%a%a%a?)%-(%a%a)%-(%w%w%w%w%w%w?%w?%w?)$', 'r', 'v'}, -- 9 -  ll-RR-variant (where variant is 5-8 alnum characters)
+
-- il n'y a pas de sub-code d'écriture, on prend en compte le code de langue principal.
{'^(%a%a%a?)%-(%d%d%d)%-(%w%w%w%w%w%w?%w?%w?)$', 'r', 'v'}, -- 10 - ll-DDD-variant (where region is 3 digits; variant is 5-8 alnum characters)
+
local tabLangue = dataLangue[ tabCode[1] ]
+
if tabLangue and tabLangue.rtl then
{'^(%a%a%a?)%-(%d%d%d%d)$', 'v'}, -- 11 - ll-variant (where variant is 4 digits)
+
return 'rtl'
{'^(%a%a%a?)%-(%w%w%w%w%w%w?%w?%w?)$', 'v'}, -- 12 - ll-variant (where variant is 5-8 alnum characters)
 
 
{'^(%a%a%a?)%-(%a%a%a%a)%-(%a%a)$', 's', 'r'}, -- 13 - ll-Ssss-RR
 
{'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d)$', 's', 'r'}, -- 14 - ll-Ssss-DDD (region is 3 digits)
 
 
{'^(%a%a%a?)%-(%a%a%a%a)$', 's'}, -- 15 - ll-Ssss
 
 
{'^(%a%a%a?)%-(%a%a)$', 'r'}, -- 16 - ll-RR
 
{'^(%a%a%a?)%-(%d%d%d)$', 'r'}, -- 17 - ll-DDD (region is 3 digits)
 
 
{'^(%a%a%a?)$'}, -- 18 - ll
 
 
{'^(%a%a%a?)%-x%-(%w%w?%w?%w?%w?%w?%w?%w?)$', 'p'}, -- 19 - ll-x-pppppppp (private is 1-8 alnum characters)
 
}
 
 
 
local t = {}; -- table of captures; serves as a translator between captured ietf tag parts and named variables
 
 
 
for i, v in ipairs (pattern) do -- spin through the pattern table looking for a match
 
local c1, c2, c3, c4; -- captures in the 'pattern' from the pattern table go here
 
 
c1, c2, c3, c4 = source:match (pattern[i][1]); -- one or more captures set if source matches pattern[i])
 
if c1 then -- c1 always set on match
 
code = c1; -- first capture is always code
 
t = {
 
[pattern[i][2] or 'x'] = c2, -- fill the table of captures with the rest of the captures
 
[pattern[i][3] or 'x'] = c3, -- take index names from pattern table and assign sequential captures
 
[pattern[i][4] or 'x'] = c4, -- index name may be nil in pattern[i] table so "or 'x'" spoofs a name for this index in this table
 
};
 
script = t.s or ''; -- translate table contents to named variables;
 
region = t.r or ''; -- absent table entries are nil so set named ietf parts to empty string for concatenation
 
variant= t.v or '';
 
private = t.p or '';
 
break; -- and done
 
 
end
 
end
 +
end
 
end
 
end
 
if not code then
 
return nil, nil, nil, nil, nil, table.concat ({'unrecognized language tag: ', source}); -- don't know what we got but it is malformed
 
end
 
 
code = code:lower(); -- ensure that we use and return lower case version of this
 
 
 
if not (override_table[code] or lang_table[code] or synonym_table[code] or lang_dep_table[code]) then
+
-- la langue n'est pas écrite de droite à gauche, donc ltr.
return nil, nil, nil, nil, nil, table.concat ({'unrecognized language code: ', code}); -- invalid language code, don't know about the others (don't care?)
+
return 'ltr'
end
+
end
 
if synonym_table[code] then -- if 639-2/639-2T code has a 639-1 synonym
 
table.insert (maint_cats, table.concat ({'Lang and lang-xx code promoted to ISO 639-1|', code}));
 
table.insert (maint_msgs, table.concat ({'code: ', code, ' promoted to code: ', synonym_table[code]}));
 
code = synonym_table[code]; -- use the synonym
 
end
 
  
if is_set (script) then
 
if is_set (args_script) then
 
return code, nil, nil, nil, nil, 'redundant script tag'; -- both code with script and |script= not allowed
 
end
 
else
 
script = args_script or ''; -- use args.script if provided
 
end
 
  
if is_set (script) then
+
-- Voir Modèle:Nom langue
script = script:lower(); -- ensure that we use and return lower case version of this
+
-- Paramètre :
if not script_table[script] then
+
--    1  : code IETF de langue.
return code, nil, nil, nil, nil, table.concat ({'unrecognized script: ', script, ' for code: ', code}); -- language code ok, invalid script, don't know about the others (don't care?)
+
function Langue.nomLangue( frame )
end
+
local arg = premierParametre( frame, true )
 +
if type( arg ) ~= 'string' or arg == '' then
 +
return '<span class="error">langue non précisée</span>'
 
end
 
end
if suppressed_table[script] then -- ensure that code-script does not use a suppressed script
+
local tabLangue = dataLangue[ arg ]
if in_array (code, suppressed_table[script]) then
+
if tabLangue == nil then
return code, nil, nil, nil, nil, table.concat ({'script: ', script, ' not supported for code: ', code}); -- language code ok, script is suppressed for this code
+
tabLangue = dataLangue[ mw.ustring.match( arg, '^(%a-)%-' ) ]
end
 
 
end
 
end
 
+
if not tabLangue then
if is_set (region) then
+
return string.format( langErrorMess, arg )
if is_set (args_region) then
 
return code, nil, nil, nil, nil, 'redundant region tag'; -- both code with region and |region= not allowed
 
end
 
else
 
region = args_region or ''; -- use args.region if provided
 
end
 
 
 
if is_set (region) then
 
region = region:lower(); -- ensure that we use and return lower case version of this
 
if not region_table[region] then
 
return code, script, nil, nil, nil, table.concat ({'unrecognized region: ', region, ' for code: ', code});
 
end
 
 
end
 
end
+
if type( tabLangue.page ) == 'string' then
if is_set (variant) then
+
if tabLangue.page ~= '' then
if is_set (args_variant) then
+
return '[[' .. tabLangue.page .. '|' .. tabLangue.nom .. ']]'
return code, nil, nil, nil, nil, 'redundant variant tag'; -- both code with variant and |variant= not allowed
+
else
 +
return tabLangue.nom
 
end
 
end
 
else
 
else
variant = args_variant or ''; -- use args.variant if provided
+
return '[[' .. tabLangue.nom .. ']]'
end
 
 
 
if is_set (variant) then
 
variant = variant:lower(); -- ensure that we use and return lower case version of this
 
if not variant_table[variant] then -- make sure variant is valid
 
return code, script, region, nil, nil, table.concat ({'unrecognized variant: ', variant});
 
end -- does this duplicate/replace tests in lang() and lang_xx()?
 
if is_set (script) then -- if script set it must be part of the 'prefix'
 
if not in_array (table.concat ({code, '-', script}), variant_table[variant]['prefixes']) then
 
return code, script, region, nil, nil, table.concat ({'unrecognized variant: ', variant, ' for code-script pair: ', code, '-', script});
 
end
 
elseif is_set (region) then -- if region set, there are some prefixes that require lang code and region (en-CA-newfound)
 
if not in_array (code, variant_table[variant]['prefixes']) then -- first see if lang code is all that's required (en-oxendict though en-GB-oxendict is preferred)
 
if not in_array (table.concat ({code, '-', region}), variant_table[variant]['prefixes']) then -- now try for lang code and region (en-CA-newfound)
 
return code, script, region, nil, nil, table.concat ({'unrecognized variant: ', variant, ' for code-region pair: ', code, '-', region});
 
end
 
end
 
else
 
if not in_array (code, variant_table[variant]['prefixes']) then
 
return code, script, region, nil, nil, table.concat ({'unrecognized variant: ', variant, ' for code: ', code});
 
end
 
end
 
 
end
 
end
 
if is_set (private) then
 
private = private:lower(); -- ensure that we use and return lower case version of this
 
if not override_table[table.concat ({code, '-x-', private})] then -- make sure private tag is valid; note that index
 
return code, script, region, nil, nil, table.concat ({'unrecognized private tag: ', private});
 
end
 
end
 
return code, script, region, variant, private, nil; -- return the good bits; make sure that msg is nil
 
 
end
 
end
  
  
--[[--------------------------< M A K E _ E R R O R _ M S G >--------------------------------------------------
+
-- Voir Modèle:Langue
 
+
-- Paramètres :
assembles an error message from template name, message text, help link, and error category.
+
--   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).
local function make_error_msg (msg, args, template)
+
function Langue.langue( frame )
local out = {};
+
local args = ( frame.getParent and frame:getParent().args ) or frame        -- préparation pour appel par modèle ou direct.
local category;
+
local code = mw.ustring.lower( mw.text.trim( args[1] or '' ) )
+
local texte = args.texte or ''
if 'Transl' == template then
+
if texte == '' then
category = 'Transl';
+
texte = args[2] or ''
else
 
category = 'Lang and lang-xx'
 
 
end
 
end
 +
local dir = args.dir
 +
local namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [12] = true, [14] = true, [100] = true }
 +
local categorisation = namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and not args.nocat
 
 
table.insert (out, table.concat ({'[', args.text or 'undefined', '] '})); -- for error messages output args.text if available
+
-- Décalage des paramètres si code contient la direction du texte (obsolète mais toujours possible).
table.insert (out, table.concat ({'<span style=\"font-size: 100%; font-style: normal;\" class=\"error\">Error: {{', template, '}}: '}));
+
if code == 'ltr' or code == 'rtl' then
table.insert (out, msg);
+
dir = code
table.insert (out, table.concat ({' ([[:Category:', category, ' template errors|help]])'}));
+
code = mw.ustring.lower( mw.text.trim( args[2] ) or '' )
table.insert (out, '</span>');
+
texte = args[3] or ''
 
if (0 == namespace or 10 == namespace) and not args.nocat then -- categorize in article space (and template space to take care of broken usages)
 
table.insert (out, table.concat ({'[[Category:', category, ' template errors]]'}));
 
 
end
 
end
 
+
local codeArg = code
return table.concat (out);
 
end
 
 
 
 
+
-- sortie immédiate s'il n'y a pas de texte
--[=[-------------------------< M A K E _ W I K I L I N K >----------------------------------------------------
+
if texte == '' then
 
+
if categorisation then
Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only
+
return '<span class="error">erreur du modèle [[modèle:Langue|{{langue}}]] : texte absent</span>[[Catégorie:Page utilisant un modèle avec une syntaxe erronée|Langue]]'
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
 
else
return table.concat ({'[[', link, ']]'});
+
return ''
 
end
 
end
else
 
return '';
 
 
end
 
end
end
+
 
+
-- récursion si texte contient des blocs
 
+
if texte:match('\n *\n') or texte:match('\n[*#:]') then
--[[--------------------------< D I V _ M A R K U P _ A D D >--------------------------------------------------
+
-- les parenthèses permettent d'éliminer la seconde valeur retournée par gsub (nombre de remplacement)
 
+
return ( texte:gsub(  
adds <i> and </i> tags to list-item text or to implied <p>..</p> text.  mixed not supported
+
'(\n?[*#:]?%s*)([^\n]+)',  
 
+
function ( init, ligne )  
]]
+
return init .. Langue.langue{ code, ligne }
 
+
end
local function div_markup_add (text, style)
+
) )
local implied_p = {};
 
 
 
if text:find ('^\n[%*:;#]') then -- look for list markup; list markup must begin at start of text
 
if 'italic' == style then
 
return mw.ustring.gsub (text, '(\n[%*:;#]+)([^\n]+)', '%1<i>%2</i>'); -- insert italic markup at each list item
 
else
 
return text;
 
end
 
 
end
 
end
 
+
if text:find ('\n+') then -- look for any number of \n characters in text
+
-- Si la langue est reconnue, la valeur de la table est prise en compte (permet de corriger les noms de langue en toutes lettres).
text = text:gsub ('([^\n])\n([^\n])', '%1 %2'); -- replace single newline characters with a space character which mimics mediawiki
+
local tabCode = Langue.determinationCode( code )
 
+
local tabLangue
if 'italic' == style then
+
if tabCode then
text = text:gsub('[^\n]+', '<p><i>%1</i></p>'); -- insert p and italic markup tags at each impled p (two or more consecutive '\n\n' sequences)
+
code = table.concat( tabCode, '-' )
else
+
tabLangue = dataLangue[ tabCode[1] ]
text = text:gsub ('[^\n]+', '<p>%1</p>'); -- insert p markup at each impled p
+
text = text:gsub ('\n', ''); -- strip newline characters
+
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
 
end
 
end
 
+
return text;
+
-- Préparation du rendu de direction du texte.
end
+
dir = dir and dir:lower()
 
+
if dir ~= 'ltr' and dir ~= 'rtl' then
 
+
dir = ( tabLangue and tabLangue.rtl and 'rtl' )
--[[--------------------------< M A K E _ T E X T _ H T M L >--------------------------------------------------
 
 
 
Add the html markup to text according to the type of content that it is: <span> or <i> tags for inline content or
 
<div> tags for block content
 
 
 
]]
 
 
 
local function make_text_html (code, text, tag, rtl, style, size, language)
 
local html = {};
 
local style_added = '';
 
 
 
if text:match ('^%*') then
 
table.insert (html, '&#42;'); -- move proto language text prefix outside of italic markup if any; use numeric entity because plain splat confuses MediaWiki
 
text = text:gsub ('^%*', ''); -- remove the splat from the text
 
 
end
 
end
  
if 'span' == tag then -- default html tag for inline content
+
-- Compilation du texte à retourner.
if 'italic' == style then -- but if italic
+
local html = mw.html.create( '' )
tag = 'i'; -- change to <i> tags
+
if code == '' then
 +
html:wikitext( texte )
 +
else
 +
html:tag( 'span' )
 +
:addClass( 'lang-' .. code )
 +
:addClass( args.class )
 +
:attr{ lang = code, dir = dir }
 +
:wikitext( texte )
 +
:done()
 +
 +
-- Translittération.
 +
if ( args.trans or '' ) ~= '' then
 +
local trans = args.trans:gsub( "^''([^'].*[^'])''$", "%1" )
 +
html:wikitext( " (''" )
 +
:tag( 'span' )
 +
:addClass( 'transcription lang-' .. code )
 +
:attr( 'lang', code .. '-Latn' )
 +
:attr( 'dir', 'ltr' )
 +
:wikitext( trans )
 +
:done()
 +
:wikitext( "'')" )
 
end
 
end
else -- must be div so go
 
text = div_markup_add (text, style); -- handle implied <p>, implied <p> with <i>, and list markup (*;:#) with <i>
 
end
 
 
table.insert (html, table.concat ({'<', tag})); -- open the <i>, <span>, or <div> html tag
 
table.insert (html, table.concat ({' lang="', code, '\"'})); -- add language attribute
 
 
if rtl or unicode.is_rtl(text) then
 
table.insert (html, ' dir="rtl"'); -- add direction attribute for right to left languages
 
end
 
 
if 'normal' == style then -- when |italic=no
 
table.insert (html, ' style=\"font-style: normal;'); -- override external markup, if any
 
style_added = '\"'; -- remember that style attribute added and is not yet closed
 
end
 
  
if is_set (size) then -- when |size=<something>
 
if is_set (style_added) then
 
table.insert (html, table.concat ({' font-size: ', size, ';'})); -- add when style attribute already inserted
 
else
 
table.insert (html, table.concat ({' style=\"font-size: ', size, ';'})); -- create style attribute
 
style_added = '\"'; -- remember that style attribute added and is not yet closed
 
end
 
 
end
 
end
  
if is_set (language) then
+
-- Ajout de la catégorie Page avec code de langue invalide si le code langue non reconnu ou invalide.
table.insert (html, table.concat ({style_added, ' title=\"', language})); --start the title text
+
if categorisation and ( type( tabLangue ) ~= 'table' or tabCode.invalide ) then
if language:find ('languages') then
+
local erreur = string.format( langErrorMess, codeArg )
table.insert (html, ' collective text'); -- for collective languages
+
if codeArg == '' then
else
+
erreur = '<span class="error">langue non précisée</span>'
table.insert (html, ' language text'); -- for individual languages
 
 
end
 
end
table.insert (html, '\">'); -- close the opening html tag
+
html:wikitext( '[[Catégorie:Page avec code de langue invalide|Langue]] ' .. erreur )
else
 
table.insert (html, table.concat ({style_added, '>'})); -- close the style attribute and close opening html tag
 
 
end
 
end
table.insert (html, text); -- insert the text
 
  
table.insert (html, table.concat ({'</', tag, '>'})); -- close the <i>, <span>, or <div> html tag
+
return tostring( html )
 
 
if rtl then -- legacy; shouldn't be necessary because all of the rtl text is wrapped inside an html tag with dir="rtl" attribute
 
table.insert (html, '&lrm;'); -- make sure the browser knows that we're at the end of the rtl
 
end
 
return table.concat (html); -- put it all together and done
 
 
end
 
end
  
 +
-- Alias nom de fonction
 +
Langue.lang = Langue.langue
  
--[=[-------------------------< M A K E _ C A T E G O R Y >----------------------------------------------------
 
  
For individual language, <language>, returns:
+
-- Voir Modèle:Indication de langue
[[Category:Articles containing <language>-language text]]
+
-- Paramètres :
 
+
--    1 : nom de langue ;
for English:
+
--    2 : code IETF ;
[[Category:Articles containing explicitly cited English-language text]]
+
--    texte : texte dans cette langue ;
+
--    dir : direction de la langue.
for ISO 639-2 collective languages (and for 639-1 bh):
+
function Langue.indicationDeLangue( frame )
[[Category:Articles with text in <language> languages]]
+
local args = ( frame.getParent and frame:getParent().args ) or frame
 
+
local nomLangue = mw.text.trim( args[1] or '' )
]=]
+
local code = mw.text.trim( args[2] or '' )
 
+
local texte = args.texte
local function make_category (code, language_name, nocat, name_get)
+
local dir = args.dir
local cat = {};
+
local wikiText = ''
local retval;
+
-- Cas où le premier et/ou le deuxième paramètre est vide.
 
+
if code == '' and nomLangue == '' then
if ((0 ~= namespace) or nocat) and not name_get then -- only categorize in article space
+
return texte
return ''; -- return empty string for concatenation
+
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
 
end
 
+
-- Gestion du texte.
if language_name:find ('languages') then
+
if texte and texte ~= '' then
return table.concat ({'[[Category:Articles with text in ', language_name, ']]'});
+
texte = '\194\160' .. Langue.lang{ code, dir = dir, texte = texte }
end
 
 
table.insert (cat, '[[Category:Articles containing ');
 
 
 
if 'en' == code then
 
table.insert (cat, 'explicitly cited ' .. language_name); -- falls back to English if regional name not available
 
 
else
 
else
table.insert (cat, language_name);
+
texte = ''
 
end
 
end
 +
-- Compilation de l'indicateur de langue et du texte.
 +
local html = mw.html.create()
 +
html:tag( 'abbr' )
 +
:addClass( 'abbr' )
 +
:addClass( 'indicateur-langue' )
 +
:attr( 'title', 'Langue : ' .. nomLangue )
 +
:wikitext( '(' .. code .. ')' )
 +
:done()
 +
:wikitext( texte )
 
 
table.insert (cat, '-language text]]');
+
return tostring( html )
 
 
return table.concat (cat);
 
 
end
 
end
  
 
+
-- Voir Modèle:Mul
--[[--------------------------< M A K E _ T R A N S L I T >----------------------------------------------------
+
-- Paramètres : codes IETF ou noms de langue, en nombre indéfini (string ou nil uniquement).
 
+
function Langue.indicationMultilingue( frame )
return translit <i lang=xx-Latn>...</i> where xx is the language code; else return empty string
+
local args = (frame.getParent and frame:getParent().args) or frame
 
+
local listeNom = { }
The value |script= is not used in {{transl}} for this purpose; instead it uses |code.  Because language scripts
+
local listeCode = { }
are listed in the {{transl}} switches they are included in the data tables. The script parameter is introduced
+
local tabLangue
at {{Language with name and transliteration}}.  If |script= is set, this function uses it in preference to code.
+
-- Valeur par défaut du premier paramètre = 'mul'.
 
+
local code = mw.text.trim( args[1] or '' )
To avoid confusion, in this module and the templates that use it, the transliteration script parameter is renamed
+
if code == '' then
to be |translit-script= (in this function, tscript)
+
code = 'mul'
 
+
end
This function is used by both lang_xx() and transl()
 
lang_xx() always provides code, language_name, and translit; may provide tscript; never provides style
 
transl() always provides language_name, translit, and one of code or tscript, never both; always provides style
 
 
 
For {{transl}}, style only applies when a language code is provided
 
]]
 
 
 
local function make_translit (code, language_name, translit, std, tscript, style)
 
local title;
 
local tout = {};
 
local title_table = lang_data.translit_title_table; -- table of transliteration standards and the language codes and scripts that apply to those standards
 
 
 
if is_set (code) then -- when a language code is provided (always with {{lang-xx}} templates, not always with {{transl}})
+
if not args[2] and not dataLangue[ mw.ustring.lower( code ) ] then
if not style then -- nil for the default italic style
+
local split = mw.text.split( code, '[+,;:/ .]+' )
table.insert (tout, "<i lang=\""); -- so use <i> tag
+
if #split > 1 then
else
+
return Langue.indicationMultilingue( split )
table.insert (tout, table.concat ({'<span style=\"font-style: ', style, '\" lang=\"'})); -- non-standard style, construct a span tag for it
 
 
end
 
end
table.insert (tout, code);
 
table.insert (tout, "-Latn\" title=\""); -- transliterations are always Latin script
 
else
 
table.insert (tout, "<span title=\""); -- when no language code: no lang= attribute, not italic ({{transl}} only)
 
 
end
 
end
+
-- Ajout des noms et codes de langue de chaque paramètre dans listeNom et ListeCode.
std = std and std:lower(); -- lower case for table indexing
+
local i = 1
+
repeat
if not is_set (std) and not is_set (tscript) then -- when neither standard nor script specified
+
code = mw.ustring.lower( code )
table.insert (tout, language_name); -- write a generic tool tip
+
local tabLangue = dataLangue[ code ]
if not language_name:find ('languages') then -- collective language names (plural 'languages' is part of the name)
+
if not tabLangue then
table.insert (tout, '-language') -- skip this text (individual and macro languages only)
+
code = mw.text.split( code, '-' )[1]
 +
tabLangue = dataLangue[ code ]
 
end
 
end
table.insert (tout, ' romanization'); -- finish the tool tip; use romanization when neither script nor standard supplied
+
if type( tabLangue ) == 'table' then
elseif is_set (std) and is_set (tscript) then -- when both are specified
+
table.insert( listeNom, tabLangue.nom )
if title_table[std] then -- and if standard is legitimate
+
table.insert( listeCode, tabLangue.code )
if title_table[std][tscript] then -- and if script for that standard is legitimate
 
table.insert (tout, table.concat ({title_table[std][tscript:lower()], ' (', script_table[tscript][1], ' script) transliteration'})); -- add the appropriate text to the tool tip
 
else
 
table.insert (tout, title_table[std]['default']); -- use the default if script not in std table; TODO: maint cat? error message because script not found for this standard?
 
end
 
 
else
 
else
return ''; -- invalid standard, setup for error message
+
table.insert( listeNom, '???' )
end
+
local erreur = string.format( langErrorMess, code )
 
+
table.insert( listeCode, erreur )
elseif is_set (std) then -- translit-script not set, use language code
 
if not title_table[std] then return ''; end -- invalid standard, setup for error message
 
 
if title_table[std][code] then -- if language code is in the table (transl may not provide a language code)
 
-- table.insert (tout, table.concat ({title_table[std][code:lower()], ' (', lang_table[code][1], ' language) transliteration'})); -- add the appropriate text to the tool tip
 
table.insert (tout, table.concat ({title_table[std][code:lower()], ' (', language_name, ' language) transliteration'})); -- add the appropriate text to the tool tip
 
else -- code doesn't match
 
table.insert (tout, title_table[std]['default']); -- so use the standard's default
 
end
 
else -- here if translit-script set but translit-std not set
 
if title_table['no_std'][tscript] then
 
table.insert (tout, title_table['no_std'][tscript]); -- use translit-script if set
 
elseif title_table['no_std'][code] then
 
table.insert (tout, title_table['no_std'][code]); -- use language code
 
else
 
if is_set (tscript) then
 
table.insert (tout, table.concat ({language_name, '-script transliteration'})); -- write a script tool tip
 
elseif is_set (code) then
 
if not language_name:find ('languages') then -- collective language names (plural 'languages' is part of the name)
 
table.insert (tout, '-language') -- skip this text (individual and macro languages only)
 
end
 
table.insert (tout, ' transliteration'); -- finish the tool tip
 
else
 
table.insert (tout, ' transliteration'); -- generic tool tip (can we ever get here?)
 
end
 
end
 
end
 
 
 
table.insert (tout, '">');
 
table.insert (tout, translit);
 
if is_set (code) and not style then -- when a language code is provided (always with {{lang-xx}} templates, not always with {{transl}})
 
table.insert (tout, "</i>"); -- close the italic tag
 
else
 
table.insert (tout, "</span>"); -- no language code so close the span tag
 
end
 
return table.concat (tout);
 
end
 
 
 
 
 
--[[--------------------------< V A L I D A T E _ T E X T >----------------------------------------------------
 
 
 
This function checks the content of args.text and returns empty string if nothing is amiss else it returns an
 
error message.  The tests are for empty or missing text and for improper or disallowed use of apostrophe markup.
 
 
 
Italic rendering is controlled by the |italic= template parameter so italic markup should never appear in args.text
 
either as ''itself'' or as '''''bold italic''''' unless |italic=unset or |italic=invert.
 
 
 
]]
 
 
 
local function validate_text (template, args)
 
if not is_set (args.text) then
 
return make_error_msg ('no text', args, template);
 
end
 
 
 
if args.text:find ("%f[\']\'\'\'\'%f[^\']") or args.text:find ("\'\'\'\'\'[\']+") then -- because we're looking, look for 4 appostrophes or 6+ appostrophes
 
return make_error_msg ('text has malformed markup', args, template);
 
end
 
 
 
local style = args.italic;
 
 
 
if ('unset' ~= style) and ('invert' ~=style) then
 
if args.text:find ("%f[\']\'\'%f[^\']") or args.text:find ("%f[\']\'\'\'\'\'%f[^\']") then -- italic but not bold, or bold italic
 
return make_error_msg ('text has italic markup', args, template);
 
 
end
 
end
end
+
i = i + 1
end
+
code = mw.text.trim( args[i] or '' )
 
+
until code == ''
 
 
--[[--------------------------< R E N D E R _ M A I N T >------------------------------------------------------
 
 
 
render mainenance messages and categories
 
 
 
]]
 
 
 
local function render_maint(nocat)
 
local maint = {};
 
 
 
if 0 < #maint_msgs then -- when there are maintenance messages
+
-- Préparation et renvoi du texte.
table.insert (maint, table.concat ({'<span class="lang-comment" style="font-style: normal; display: none; color: #33aa33; margin-left: 0.3em;">'})); -- opening <span> tag
+
local n = #listeCode
for _, msg in ipairs (maint_msgs) do
+
if n == 0 then
table.insert (maint, table.concat ({msg, ' '})); -- add message strings
+
return ''
end
 
table.insert (maint, '</span>'); -- close the span
 
 
end
 
end
 +
local plusieurs = ( n > 1 )
 
 
if (0 < #maint_cats) and (0 == namespace) and not nocat then -- when there are maintenance categories; article namespace only
+
local html = mw.html.create( 'abbr' )
for _, cat in ipairs (maint_cats) do
+
:addClass( 'abbr' )
table.insert (maint, table.concat ({'[[Category:', cat, ']]'})); -- format and add the categories
+
:addClass( 'indicateur-langue' )
end
+
:attr( 'title', 'Langue' .. ( plusieurs and 's' or '' ) .. ' : ' .. mw.text.listToText( listeNom ) )
end
+
:wikitext( '(' .. table.concat( listeCode, '\194\160+\194\160' ) .. ')' )
 
 
return table.concat (maint);
+
return tostring( html )
 
end
 
end
  
  
--[[--------------------------< P R O T O _ P R E F I X >------------------------------------------------------
+
-- 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
 +
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 = ''
  
for proto languages, text is prefixed with a splat. We do that here as a flag for make_text_html() so that a splat
+
-- Détection de la direction du texte.
will be rendered outside of italic markup (if used).  If the first character in text here is already a splat, we
+
if code == 'ltr' or code == 'rtl' then
do nothing
+
dir = code
 +
code = mw.ustring.lower( mw.text.trim( args[2] ) )
 +
texte = args[3] or ''
 +
end
  
proto_param is boolean or nil; true adds splat prefix regardless of language name; false removes and / or inhibits
+
-- Définition du nom de la langue en français.
regardless of language name; nil does nothing; presumes that the value in text is correct but removes extra splac
+
local nom = Langue.nomLangue{ code }
  
]]
+
if texte ~= '' then
 
+
texte = '\194\160' .. Langue.lang{ code, dir = dir, texte = texte, trans = trans }
local function proto_prefix (text, language_name, proto_param)
 
if false == proto_param then -- when forced by |proto=no
 
return text:gsub ('^%**', ''); -- return text without splat prefix regardless of language name or existing splat prefix in text
 
elseif (language_name:find ('^Proto%-') or (true == proto_param)) then -- language is a proto or forced by |proto=yes
 
return text:gsub ('^%**', '*'); -- prefix proto-language text with a splat; also removes duplicate prefixing splats
 
 
end
 
end
 
return text:gsub ('^%*+', '*'); -- return text unmolested except multiple splats reduced to one splat
 
end
 
 
 
--[[--------------------------< H A S _ P O E M _ T A G >------------------------------------------------------
 
 
looks for a poem strip marker in text; returns true when found; false else
 
 
auto-italic detection disabled when text has poem stripmarker because it is not possible for this code to know
 
the content that will replace the stripmarker.
 
  
]]
+
wikiText = nom .. ' :' .. texte
  
local function has_poem_tag (text)
+
return wikiText
return text:find ('\127[^\127]*UNIQ%-%-poem%-[%a%d]+%-QINU[^\127]*\127') and true or false;
 
 
end
 
end
  
 
+
---
--[[--------------------------< H T M L _ T A G _ S E L E C T >------------------------------------------------
+
-- latinOnly détermine si la chaine fournie contient uniquement des caractères latin (étendu, unicode < 880)
 
+
function Langue.nonLatin( frame )
Inspects content of and selectively trims text.  Returns text and the name of an appropriate html tag for text.
+
local texte = premierParametre( frame )
 
+
for codepoint in mw.ustring.gcodepoint( texte ) do
If text contains:
+
if codepoint > 879 and not (                 -- > 036F
\n\n text has implied <p>..</p> tags - trim leading and trailing whitespace and return
+
codepoint > 7423 and codepoint < 7936 or  -- suppléments phonétique, diacritiques et latin  (1D00 à 1EFF)
If text begins with list markup:
+
codepoint > 8191 and codepoint < 11392 or -- espace, indices, monaies et symboles divers (2000 à 2C7F)
\n* unordered
+
codepoint > 42783 and codepoint < 43008  -- latin étendu D  (A720 à A7FF)
\n; definition
+
) then
\n: definition
+
return true
\n# ordered
+
end
trim all leading whitespace except  \n and trim all trailing whitespace
 
 
 
If text contains <poem>...</poem> stripmarker, return text unmodified and choose <div>..</div> tags because
 
the stripmarker is replaced with text wrapped in <div>..</div> tags.
 
 
 
]]
 
 
 
local function html_tag_select (text)
 
local tag;
 
 
if has_poem_tag (text) then -- contains poem stripmarker (we can't know the content of that)
 
tag = 'div'; -- poem replacement is in div tags so lang must use div tags
 
elseif mw.text.trim (text):find ('\n\n+') then -- contains implied p tags
 
text = mw.text.trim (text); -- trim leading and trailing whitespace characters
 
tag = 'div'; -- must be div because span may not contain p tags (added later by MediaWiki); poem replacement is in div tags
 
elseif text:find ('\n[%*:;%#]') then -- if text has list markup
 
text = text:gsub ('^[\t\r\f ]*', ''):gsub ('%s*$', ''); -- trim all whitespace except leading newline character '\n'
 
tag = 'div'; -- must be div because span may not contain ul, dd, dl, ol tags (added later by MediaWiki)
 
else
 
text = mw.text.trim (text); -- plain text
 
tag = 'span'; -- so span is fine
 
 
end
 
end
+
return false
return text, tag;
 
 
end
 
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 type( dataLangue ) ~= 'table'  then
 +
local message = [[<strong class="error">Le chargement du module Langue/Data génère une erreur : </strong> <br>%s <br>
  
--[[--------------------------< V A L I D A T E _ P R O T O >--------------------------------------------------
+
<span class="error">Cette erreur doit être corrigée au plus vite car des milliers de pages ne s'affichent pas correctement.</span>
 
 
validates value assigned to |proto=; permitted values are yes and no; yes returns as true, no returns as false,
 
empty string (or parameter omitted) returns as nil; any other value returns as nil with a second return value of
 
true indicating that some other value has been assigned to |proto=
 
 
 
 
]]
 
]]
 
+
return string.format( message, resultat )
local function validate_proto (proto_param)
 
if 'yes' == proto_param then
 
return true;
 
elseif 'no' == proto_param then
 
return false;
 
elseif is_set (proto_param) then
 
return nil, true; -- |proto= something other than 'yes' or 'no'
 
else
 
return nil; -- missing or empty
 
 
end
 
end
 
end
 
end
  
 +
-- tableauLangues génère un tableau triable de la liste des langues disponible dans Module:langue/Data.
 +
function Langue.tableauLangues()
 +
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]]
  
--[[--------------------------< L A N G U A G E _ N A M E _ G E T >--------------------------------------------
+
local ligneTab, ligneSrt
 
+
for i, v in pairs( dataLangue ) do
common function to return language name from the data set according to IETF tag
+
if v.code then
 
+
ligneTab = {
returns language name if found in data tables; nil else
+
i,
 
+
v.code,
]]
+
v.nom,
 
+
v.page or '',
local function language_name_get (ietf, code, cat)
+
v.rtl and '[[Image:Yes check.svg|15px|oui|lien=]]' or '',
ietf = ietf:lower(); -- ietf:lower() because format_ietf_tag() returns mixed case
+
v.invalide and '[[Image:Yes check.svg|15px|oui|lien=]]' or '',
+
}
local name; -- remains nil if not found
+
ligneSrt = table.concat( ligneTab, '\n|' )
+
table.insert( tableau, ligneSrt )
if override_table[ietf] then -- look for whole IETF tag in override table
 
name = override_table[ietf][1];
 
elseif override_table[code] then -- not there so try basic language code
 
name = override_table[code][1];
 
elseif lang_table[code] then -- shift to iana code/name table
 
name = lang_table[code][1]; -- table entries sometimes have multiple names, always take the first one
 
elseif lang_dep_table[code] then
 
-- if cat then
 
-- table.insert (maint_cats, table.concat ({'Lang and lang-xx using deprecated ISO 639 codes|', code}));
 
-- table.insert (maint_msgs, table.concat ({'code: ', code, ' is deprecated'}));
 
-- end
 
name = lang_dep_table[code][1]; -- table entries sometimes have multiple names, always take the first one
 
end
 
 
 
if lang_dep_table[code] and cat then -- because deprecated code may have been overridden to en.wiki preferred name
 
table.insert (maint_cats, table.concat ({'Lang and lang-xx using deprecated ISO 639 codes|', code}));
 
table.insert (maint_msgs, table.concat ({'code: ', code, ' is deprecated'}));
 
end
 
 
 
return name; -- name from data tables or nil
 
end
 
 
 
 
 
--[[--------------------------< _ L A N G >--------------------------------------------------------------------
 
 
 
entry point for {{lang}}
 
 
 
there should be no reason to set parameters in the {{lang}} {{#invoke:}}
 
<includeonly>{{#invoke:lang|lang}}</includeonly>
 
 
 
parameters are received from the template's frame (parent frame)
 
 
 
]]
 
 
 
local function _lang (args)
 
local out = {};
 
local language_name; -- used to make category names
 
local category_name; -- same as language_name except that it retains any parenthetical disambiguators (if any) from the data set
 
local subtags = {}; -- IETF subtags script, region, variant, and private
 
local code; -- the language code
 
local msg; -- for error messages
 
local tag = 'span'; -- initial value for make_text_html()
 
local template = args.template or 'Lang';
 
 
 
validate_cat_args (args); -- determine if categorization should be suppressed
 
 
 
if args[1] and args.code then
 
return make_error_msg ('conflicting: {{{1}}} and |code=', args, template);
 
else
 
args.code = args[1] or args.code; -- prefer args.code
 
end
 
 
 
if args[2] and args.text then
 
return make_error_msg ('conflicting: {{{2}}} and |text=', args, template);
 
else
 
args.text = args[2] or args.text; -- prefer args.text
 
end
 
 
msg = validate_text (template, args); -- ensure that |text= is set
 
if is_set (msg) then -- msg is an already-formatted error message
 
return msg;
 
end
 
 
args.text, tag = html_tag_select (args.text); -- inspects text; returns appropriate html tag with text trimmed accordingly
 
 
 
args.rtl = args.rtl == 'yes'; -- convert to boolean: 'yes' -> true, other values -> false
 
 
 
args.proto, msg = validate_proto (args.proto); -- return boolean, or nil, or nil and error message flag
 
if msg then
 
return make_error_msg (table.concat ({'invalid |proto=: ', args.proto}), args, template);
 
end
 
 
 
code, subtags.script, subtags.region, subtags.variant, subtags.private, msg = get_ietf_parts (args.code); -- |script=, |region=, |variant= not supported because they should be part of args.code ({{{1}}} in {{lang}})
 
 
 
if msg then
 
return make_error_msg ( msg, args, template);
 
end
 
 
 
args.italic, msg = validate_italic (args);
 
if msg then
 
return make_error_msg (msg, args, template);
 
end
 
 
 
if nil == args.italic then -- nil when |italic= absent or not set or |italic=default; args.italic controls
 
if ('latn' == subtags.script) or -- script is latn
 
(this_wiki_lang ~= code and not is_set (subtags.script) and not has_poem_tag (args.text) and unicode.is_Latin (args.text)) then -- text not this wiki's language, no script specified and not in poem markup but is wholly latn script (auto-italics)
 
args.italic = 'italic'; -- DEFAULT for {{lang}} templates is upright; but if latn script set for font-style:italic
 
else
 
args.italic = 'inherit'; -- italic not set; script not latn; inherit current style
 
 
end
 
end
 
end
 
end
 +
table.sort( tableau )
 +
table.insert( tableau, 1, entete )
 +
table.insert( tableau, '}' )
 
 
if is_set (subtags.script) then -- if script set, override rtl setting
+
return table.concat( tableau, '\n|-\n|' )
if in_array (subtags.script, lang_data.rtl_scripts) then
 
args.rtl = true; -- script is an rtl script
 
else
 
args.rtl = false; -- script is not an rtl script
 
end
 
end
 
 
 
args.code = format_ietf_tag (code, subtags.script, subtags.region, subtags.variant, subtags.private); -- format to recommended subtag styles
 
language_name = language_name_get (args.code, code, true); -- get language name; try ietf tag first, then code w/o variant then code w/ variant
 
 
 
if 'invert' == args.italic and 'span' == tag then -- invert only supported for in-line content
 
args.text = invert_italics (args.text)
 
end
 
 
 
args.text = proto_prefix (args.text, language_name, args.proto); -- prefix proto-language text with a splat
 
 
 
table.insert (out, make_text_html (args.code, args.text, tag, args.rtl, args.italic, args.size, language_name));
 
table.insert (out, make_category (code, language_name, args.nocat));
 
table.insert (out, render_maint(args.nocat)); -- maintenance messages and categories
 
 
 
return table.concat (out); -- put it all together and done
 
 
end
 
end
  
 
+
-- listeCodeAlias génère une liste ; les langues sont de la forme : * code : alias1, alias2
--[[--------------------------< L A N G >----------------------------------------------------------------------
+
function Langue.listeCodeAlias()
 
+
local languesTab, listeCodesAlias = { }, { }
entry point for {{lang}}
+
local code, alias, codeAlias
 
+
for i, v in pairs( dataLangue ) do
there should be no reason to set parameters in the {{lang}} {{#invoke:}}
+
-- on construit un table avec pour indices les codes de langue, et pour valeurs une table avec la liste des alias
<includeonly>{{#invoke:lang|lang}}</includeonly>
+
code = v.code
 
+
if code and not v.invalide then
parameters are received from the template's frame (parent frame)
+
languesTab[code] = languesTab[code] or { }
 
+
if i ~= mw.ustring.lower( code ) then
]]
+
table.insert( languesTab[code], i )
 
 
local function lang (frame)
 
local args = getArgs (frame, { -- this code so that we can detect and handle wiki list markup in text
 
valueFunc = function (key, value)
 
if 2 == key or 'text' == key then -- the 'text' parameter; do not trim wite space
 
return value; -- return untrimmed 'text'
 
elseif value then -- all other values: if the value is not nil
 
value = mw.text.trim (value); -- trim whitespace
 
if '' ~= value then -- empty string when value was only whitespace
 
return value;
 
end
 
 
end
 
end
return nil; -- value was empty or contained only whitespace
 
end -- end of valueFunc
 
});
 
 
return _lang (args);
 
end
 
 
 
--[[--------------------------< L A N G _ X X >----------------------------------------------------------------
 
 
For the {{lang-xx}} templates, the only parameter required to be set in the template is the language code.  All
 
other parameters can, usually should, be written in the template call.  For {{lang-xx}} templates for languages
 
that can have multiple writing systems, it may be appropriate to set |script= as well.
 
 
For each {{lang-xx}} template choose the appropriate entry-point function so that this function knows the default
 
styling that should be applied to text.
 
 
For normal, upright style:
 
<includeonly>{{#invoke:lang|lang_xx_inherit|code=xx}}</includeonly>
 
For italic style:
 
<includeonly>{{#invoke:lang|lang_xx_italic|code=xx}}</includeonly>
 
 
All other parameters should be received from the template's frame (parent frame)
 
 
Supported parameters are:
 
|code = (required) the IANA language code
 
|script = IANA script code; especially for use with languages that use multiple writing systems
 
|region = IANA region code
 
|variant = IANA variant code
 
|text = (required) the displayed text in language specified by code
 
|link = boolean false ('no') does not link code-spcified language name to associated language article
 
|rtl = boolean true ('yes') identifies the language specified by code as a right-to-left language
 
|nocat = boolean true ('yes') inhibits normal categorization; error categories are not affected
 
|cat = boolian false ('no') opposite form of |nocat=
 
|italic = boolean true ('yes') renders displayed text in italic font; boolean false ('no') renders displayed text in normal font; not set renders according to initial_style_state
 
|lit = text that is a literal translation of text
 
|label = 'none' to suppress all labeling (language name, 'translit.', 'lit.')
 
any other text replaces language-name label - automatic wikilinking disabled
 
 
for those {{lang-xx}} templates that support transliteration (those templates where |text= is not entirely latn script):
 
|translit = text that is a transliteration of text
 
|translit-std = the standard that applies to the transliteration
 
|translit-script = ISO 15924 script name; falls back to code
 
 
For {{lang-xx}}, the positional parameters are:
 
{{{1}}} text
 
{{{2}}} transliterated text
 
{{{3}}} literal translation text
 
no other positional parameters are allowed
 
 
]]
 
 
local function _lang_xx (args)
 
local out = {};
 
local language_name; -- used to make display text, article links
 
local category_name; -- same as language_name except that it retains any parenthetical disambiguators (if any) from the data set
 
local subtags = {}; -- IETF subtags script, region, and variant
 
local code; -- the language code
 
 
local translit_script_name; -- name associated with IANA (ISO 15924) script code
 
local translit;
 
local translit_title;
 
local msg; -- for error messages
 
local tag = 'span'; -- initial value for make_text_html()
 
local template = args.template or 'Lang-xx';
 
 
if args[1] and args.text then
 
return make_error_msg ('conflicting: {{{1}}} and |text=', args, template);
 
else
 
args.text = args[1] or args.text; -- prefer args.text
 
end
 
 
msg = validate_text (template, args); -- ensure that |text= is set, does not contain italic markup and is protected from improper bolding
 
if is_set (msg) then
 
return msg;
 
end
 
 
args.text, tag = html_tag_select (args.text); -- inspects text; returns appropriate html tag with text trimmed accordingly
 
 
if args[2] and args.translit then
 
return make_error_msg ('conflicting: {{{2}}} and |translit=', args, template);
 
else
 
args.translit = args[2] or args.translit -- prefer args.translit
 
end
 
 
if args[3] and (args.translation or args.lit) then
 
return make_error_msg ('conflicting: {{{3}}} and |lit= or |translation=', args, template);
 
elseif args.translation and args.lit then
 
return make_error_msg ('conflicting: |lit= and |translation=', args, template);
 
else
 
args.translation = args[3] or args.translation or args.lit; -- prefer args.translation
 
end
 
 
if args.links and args.link then
 
return make_error_msg ('conflicting: |links= and |link=', args, template);
 
else
 
args.link = args.link or args.links; -- prefer args.link
 
end
 
 
validate_cat_args (args); -- determine if categorization should be suppressed
 
 
args.rtl = args.rtl == 'yes'; -- convert to boolean: 'yes' -> true, other values -> false
 
 
code, subtags.script, subtags.region, subtags.variant, subtags.private, msg = get_ietf_parts (args.code, args.script, args.region, args.variant); -- private omitted because private
 
 
if msg then -- if an error detected then there is an error message
 
return make_error_msg (msg, args, template);
 
end
 
 
args.italic, msg = validate_italic (args);
 
if msg then
 
return make_error_msg (msg, args, template);
 
end
 
 
if nil == args.italic then -- args.italic controls
 
if is_set (subtags.script) then
 
if 'latn' == subtags.script then
 
args.italic = 'italic'; -- |script=Latn; set for font-style:italic
 
else
 
args.italic = initial_style_state; -- italic not set; script is not latn; set for font-style:<initial_style_state>
 
end
 
else
 
args.italic = initial_style_state; -- here when |italic= and |script= not set; set for font-style:<initial_style_state>
 
 
end
 
end
 
end
 
end
+
for i, v in pairs( languesTab ) do
if is_set (subtags.script) then -- if script set override rtl setting
+
-- transformation en un table séquence, avec pour valeur une chaine correspondant à une ligne de la liste
if in_array (subtags.script, lang_data.rtl_scripts) then
+
alias = table.concat( v, ', ' )
args.rtl = true; -- script is an rtl script
+
if alias == '' then
else
+
codeAlias = '* <code>' .. i .. '</code>'
args.rtl = false; -- script is not an rtl script
 
end
 
end
 
 
 
args.proto, msg = validate_proto (args.proto); -- return boolean, or nil, or nil and error message flag
 
if msg then
 
return make_error_msg (table.concat ({'invalid |proto=: ', args.proto}), args, template);
 
end
 
 
 
args.code = format_ietf_tag (code, subtags.script, subtags.region, subtags.variant, subtags.private); -- format to recommended subtag styles
 
language_name = language_name_get (args.code, code, true); -- get language name; try ietf tag first, then code w/o variant then code w/ variant
 
 
 
category_name = language_name; -- category names retain IANA parenthetical diambiguators (if any)
 
language_name = language_name:gsub ('%s+%b()', ''); -- remove IANA parenthetical disambiguators or qualifiers from names that have them
 
 
 
if args.label then
 
if 'none' ~= args.label then
 
table.insert (out, table.concat ({args.label, ': '})); -- custom label
 
end
 
else
 
if 'no' == args.link then
 
table.insert (out, language_name); -- language name without wikilink
 
 
else
 
else
if language_name:find ('languages') then
+
codeAlias = '* <code>' .. i .. '</code> : ' .. alias
table.insert (out, make_wikilink (language_name)); -- collective language name uses simple wikilink
 
elseif lang_data.article_name[code] then
 
table.insert (out, make_wikilink (lang_data.article_name[code][1], language_name)); -- language name with wikilink from override data
 
else
 
table.insert (out, make_wikilink (language_name .. ' language', language_name)); -- language name with wikilink
 
end
 
 
end
 
end
table.insert (out, ': '); -- separator
+
table.insert( listeCodesAlias, codeAlias )
end
 
 
 
if 'invert' == args.italic then
 
args.text = invert_italics (args.text)
 
 
end
 
end
 +
table.sort( listeCodesAlias )
 
 
args.text = proto_prefix (args.text, language_name, args.proto); -- prefix proto-language text with a splat
+
return table.concat( listeCodesAlias, '\n' )
 
+
end
table.insert (out, make_text_html (args.code, args.text, tag, args.rtl, args.italic, args.size, nil))
 
  
if is_set (args.translit) and not unicode.is_Latin (args.text) then -- transliteration (not supported in {{lang}}); not supported when args.text is wholly latn text (this is an imperfect test)
+
-- listeAliasCode génère une liste ; les langues sont de la forme :  * alias : code
table.insert (out, ', '); -- comma to separate text from translit
+
function Langue.listeAliasCode()
if 'none' ~= args.label then
+
local languesTab = { }
table.insert (out, '<small>');
+
local code
if script_table[args['translit-script']] then -- when |translit-script= is set, try to use the script's name
+
for i, v in pairs( dataLangue ) do
translit_script_name = script_table[args['translit-script'][1]];
+
-- on construit un table avec pour indices les codes de langue, et pour valeurs une table avec la liste des alias
else
+
code = v.code
translit_script_name = language_name; -- fall back on language name
+
if code and i ~= code and not v.invalide then
end
+
table.insert( languesTab, '* ' .. i .. ' = ' .. code )
translit_title = mw.title.makeTitle (0, table.concat ({'Romanization of ', translit_script_name})); -- make a title object
 
if translit_title.exists and ('no' ~= args.link) then
 
table.insert (out, make_wikilink ('Romanization of ' .. translit_script_name or language_name, 'romanized') .. ':'); -- make a wikilink if there is an article to link to
 
else
 
table.insert (out, 'romanized:'); -- else plain text
 
end
 
table.insert (out, '&nbsp;</small>'); -- close the small tag
 
end
 
 
translit = make_translit (args.code, language_name, args.translit, args['translit-std'], args['translit-script'])
 
if is_set (translit) then
 
table.insert (out, translit);
 
else
 
return make_error_msg (table.concat ({'invalid translit-std: \'', args['translit-std'] or '[missing]'}), args, template);
 
 
end
 
end
 
end
 
end
 +
table.sort( languesTab )
 
 
if is_set (args.translation) then -- translation (not supported in {{lang}})
+
return table.concat( languesTab, '\n' )
table.insert (out, ', ');
 
if 'none' ~= args.label then
 
table.insert (out, '<small>');
 
if 'no' == args.link then
 
table.insert (out, '<abbr title="literal translation">lit.</abbr>');
 
else
 
table.insert (out, make_wikilink ('Literal translation', 'lit.'));
 
end
 
table.insert (out, "&nbsp;</small>");
 
end
 
table.insert (out, table.concat ({'&#39;', args.translation, '&#39;'})); -- use html entities to avoid wiki markup confusion
 
end
 
 
table.insert (out, make_category (code, category_name, args.nocat));
 
table.insert (out, render_maint(args.nocat)); -- maintenance messages and categories
 
 
 
return table.concat (out); -- put it all together and done
 
end
 
 
 
 
 
--[[--------------------------< L A N G _ X X _ A R G S _ G E T >----------------------------------------------
 
 
 
common function to get args table from {{lang-??}} templates
 
 
 
returns table of args
 
 
 
]]
 
 
 
local function lang_xx_args_get (frame)
 
local args = getArgs(frame,
 
{
 
parentFirst= true, -- parameters in the template override parameters set in the {{#invoke:}}
 
valueFunc = function (key, value)
 
if 1 == key then -- the 'text' parameter; do not trim wite space
 
return value; -- return untrimmed 'text'
 
elseif value then -- all other values: if the value is not nil
 
value = mw.text.trim (value); -- trim whitespace
 
if '' ~= value then -- empty string when value was only whitespace
 
return value;
 
end
 
end
 
return nil; -- value was empty or contained only whitespace
 
end -- end of valueFunc
 
});
 
 
 
return args;
 
end
 
 
 
 
 
--[[--------------------------< L A N G _ X X _ I T A L I C >--------------------------------------------------
 
 
 
Entry point for those {{lang-xx}} templates that call lang_xx_italic().  Sets the initial style state to italic.
 
 
 
]]
 
 
 
local function lang_xx_italic (frame)
 
local args = lang_xx_args_get (frame);
 
 
initial_style_state = 'italic';
 
return _lang_xx (args);
 
end
 
 
 
 
 
--[[--------------------------< _ L A N G _ X X _ I T A L I C >------------------------------------------------
 
 
 
Entry point ffrom another module.  Sets the initial style state to italic.
 
 
 
]]
 
 
 
local function _lang_xx_italic (args)
 
initial_style_state = 'italic';
 
return _lang_xx (args);
 
end
 
 
 
 
 
--[[--------------------------< L A N G _ X X _ I N H E R I T >------------------------------------------------
 
 
 
Entry point for those {{lang-xx}} templates that call lang_xx_inherit().  Sets the initial style state to inherit.
 
 
 
]]
 
 
 
local function lang_xx_inherit (frame)
 
local args = lang_xx_args_get (frame);
 
 
 
initial_style_state = 'inherit';
 
return _lang_xx (args);
 
end
 
 
 
 
 
--[[--------------------------< _ L A N G _ X X _ I N H E R I T >----------------------------------------------
 
 
 
Entry point from another module.  Sets the initial style state to inherit.
 
 
 
]]
 
 
 
local function _lang_xx_inherit (args)
 
initial_style_state = 'inherit';
 
return _lang_xx (args);
 
end
 
 
 
 
 
--[[--------------------------< _ I S _ I E T F _ T A G >------------------------------------------------------
 
 
 
Returns true when a language name associated with IETF language tag exists; nil else.  IETF language tag must be valid.
 
 
 
All code combinations supported by {{lang}} and the {{lang-xx}} templates are supported by this function.
 
 
 
Module entry point from another module
 
 
 
]]
 
 
 
local function _is_ietf_tag (tag) -- entry point when this module is require()d into another
 
local c, s, r, v, p, err; -- code, script, region, variant, private, error message
 
c, s, r, v, p, err = get_ietf_parts (tag); -- disassemble tag into constituent part and validate
 
 
 
return ((c and not err) and true) or nil; -- return true when code portion has a value without error message; nil else
 
 
end
 
end
  
 
+
return Langue
--[[--------------------------< I S _ I E T F _ T A G >--------------------------------------------------------
 
 
 
Module entry point from an {{#invoke:}}
 
 
 
]]
 
 
 
local function is_ietf_tag (frame)
 
return _is_ietf_tag (getArgs(frame)[1]); -- args[1] is the ietf language tag to be tested; getArgs() so we also get parent frame
 
end
 
 
 
 
 
--[[--------------------------< _ N A M E _ F R O M _ T A G >--------------------------------------------------
 
 
 
Returns language name associated with IETF language tag if valid; error message else.
 
 
 
All code combinations supported by {{lang}} and the {{lang-xx}} templates are supported by this function.
 
 
 
Set invoke's |link= parameter to yes to get wikilinked version of the language name.
 
 
 
Module entry point from another module
 
 
 
]]
 
 
 
local function _name_from_tag (args)
 
local subtags = {}; -- IETF subtags script, region, variant, and private
 
local raw_code = args[1]; -- save a copy of the input IETF subtag
 
local link = 'yes' == args['link']; -- make a boolean
 
local label = args.label;
 
local code; -- the language code
 
local msg; -- gets an error message if IETF language tag is malformed or invalid
 
local language_name = '';
 
 
code, subtags.script, subtags.region, subtags.variant, subtags.private, msg = get_ietf_parts (raw_code);
 
if msg then
 
local template = (args['template'] and table.concat ({'{{', args['template'], '}}: '})) or ''; -- make template name (if provided by the template)
 
return table.concat ({'<span style=\"font-size: 100%; font-style: normal;\" class=\"error\">Error: ', template, msg, '</span>'});
 
end
 
 
 
raw_code = format_ietf_tag (code, subtags.script, subtags.region, subtags.variant, subtags.private); -- format to recommended subtag styles; private omitted because private
 
language_name = language_name_get (raw_code, code); -- get language name; try ietf tag first, then code w/o variant then code w/ variant
 
 
 
language_name = language_name:gsub ('%s+%b()', ''); -- remove IANA parenthetical disambiguators or qualifiers from names that have them
 
 
 
if link then -- when |link=yes, wikilink the language name
 
if language_name:find ('languages') then
 
language_name = make_wikilink (language_name, label); -- collective language name uses simple wikilink
 
elseif lang_data.article_name[code] then
 
language_name = make_wikilink (lang_data.article_name[code][1], label or language_name); -- language name with wikilink from override data
 
else
 
language_name = make_wikilink (language_name .. ' language', label or language_name); -- language name with wikilink
 
end
 
end
 
 
 
return language_name;
 
end
 

Səhifəsinin 17:00, 15 noyabr 2020 tarixinə olan son halı

Bu modulun təlimatı üçün bu səhifə yaradıla bilər: Module:Dil/doc

local Langue = { }

local dataLangue = mw.loadData 'Module:Dil/Data'
local langErrorMess = '<span class="error">langue non reconnue : %s</span>'

-- 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 not tabLangue then
		return string.format( langErrorMess, arg )
	end
	if type( tabLangue.page ) == 'string' then
		if tabLangue.page ~= '' then
			return '[[' .. tabLangue.page .. '|' .. tabLangue.nom .. ']]'
		else
			return tabLangue.nom
		end
	else
		return '[[' .. tabLangue.nom .. ']]'
	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         -- 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 namespaceCategorisation = { [0] = true, [4] = true, [10] = true, [12] = true, [14] = true, [100] = true }
	local categorisation = namespaceCategorisation[ mw.title.getCurrentTitle().namespace ] and not args.nocat
	
	-- 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
	
	-- sortie immédiate s'il n'y a pas de texte
	if texte == '' then
		if categorisation then
			return '<span class="error">erreur du modèle [[modèle:Langue|{{langue}}]] : texte absent</span>[[Catégorie:Page utilisant un modèle avec une syntaxe erronée|Langue]]'
		else
			return ''
		end
	end
	
	-- récursion si texte contient des blocs
	if texte:match('\n *\n') or texte:match('\n[*#:]') then
		-- les parenthèses permettent d'éliminer la seconde valeur retournée par gsub (nombre de remplacement)
		return ( texte:gsub( 
		 	'(\n?[*#:]?%s*)([^\n]+)', 
		 	function ( init, ligne ) 
		 		return init .. Langue.langue{ code, ligne }
		 	end
		 ) )
	end
	
	-- 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éparation 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

	-- Compilation du texte à retourner.
	local html = mw.html.create( '' )
	if code == '' then
		html:wikitext( texte )
	else
		html:tag( 'span' )
				:addClass( 'lang-' .. code )
				:addClass( args.class )
				:attr{ lang = code, dir = dir }
				:wikitext( texte )
				:done()
		
		-- Translittération.
		if ( args.trans or '' ) ~= '' then
			local trans = args.trans:gsub( "^''([^'].*[^'])''$", "%1" )
			html:wikitext( " (''" )
				:tag( 'span' )
					:addClass( 'transcription lang-' .. code )
					:attr( 'lang', code .. '-Latn' )
					:attr( 'dir', 'ltr' )
					:wikitext( trans )
					:done()
				:wikitext( "'')" )
		end

	end

	-- Ajout de la catégorie Page avec code de langue invalide si le code langue non reconnu ou invalide.
	if categorisation and ( type( tabLangue ) ~= 'table' or tabCode.invalide ) then
		local erreur = string.format( langErrorMess, codeArg )
		if codeArg == '' then
			erreur = '<span class="error">langue non précisée</span>'
		end
		html:wikitext( '[[Catégorie:Page avec code de langue invalide|Langue]] ' .. erreur )
	end

	return tostring( html )
end

-- Alias nom de fonction
Langue.lang = Langue.langue


-- 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
	local nomLangue = mw.text.trim( args[1] or '' )
	local code = 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 == '' and 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 = '\194\160' .. 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( 'abbr' )
			:addClass( 'abbr' )
			:addClass( 'indicateur-langue' )
			:attr( 'title', 'Langue : ' .. nomLangue )
			:wikitext( '(' .. code .. ')' )
			:done()
		:wikitext( texte )
	
	return tostring( html )
end

-- Voir Modèle:Mul
-- 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 )
		else
			table.insert( listeNom, '???' )
			local erreur = string.format( langErrorMess, code )
			table.insert( listeCode, erreur )
		end
		i = i + 1
		code = mw.text.trim( args[i] or '' )
	until code == ''
	
	-- Préparation et renvoi du texte.
	local n = #listeCode
	if n == 0 then
		return ''
	end
	local plusieurs = ( n > 1 )
	
	local html = mw.html.create( 'abbr' )
		:addClass( 'abbr' )
		:addClass( 'indicateur-langue' )
		:attr( 'title', 'Langue' .. ( plusieurs and 's' or '' ) .. ' : ' .. mw.text.listToText( listeNom ) )
		:wikitext( '(' .. table.concat( listeCode, '\194\160+\194\160' ) .. ')' )
	
	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
	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 = '\194\160' .. Langue.lang{ code, dir = dir, texte = texte, trans = trans }
	end

	wikiText = nom .. ' :' .. texte

	return wikiText
end

---
-- latinOnly détermine si la chaine fournie contient uniquement des caractères 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 type( dataLangue ) ~= 'table'  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()
	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 de la forme : * code : alias1, alias2
function Langue.listeCodeAlias()
	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 = '* <code>' .. i .. '</code>'
		else
			codeAlias = '* <code>' .. i .. '</code> : ' .. alias
		end
		table.insert( listeCodesAlias, codeAlias )
	end
	table.sort( listeCodesAlias )
	
	return table.concat( listeCodesAlias, '\n' )
end

-- listeAliasCode génère une liste ; les langues sont de la forme :  * alias : code
function Langue.listeAliasCode()
	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