fbpx
วิกิพีเดีย

มอดูล:Lang

คู่มือการใช้งานมอดูล[สร้าง]
--[=[  Lua support for the {{lang}}, {{lang-xx}}, and {{transl}} templates and replacement of various supporting templates.   ]=]  require('มอดูล:No globals');  local getArgs = require ('มอดูล:Arguments').getArgs; local unicode = require ("มอดูล:Unicode data"); -- for is_latin() and is_rtl() local yesno = require ('มอดูล:Yesno');  local lang_data = mw.loadData ('มอดูล:Lang/data'); -- language name override and transliteration tool-tip tables local lang_name_table = lang_data.lang_name_table; -- language codes, names, regions, scripts, suppressed scripts 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 ('มอดูล: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   seg[1] = invert_pattern_table[seg[1]] or seg[1]; -- replace leading markup according to pattern table  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   if count > 1 then -- return nil and an error message if more than one is set   return nil, 'only one of |italic=, |italics=, or |i= can be specified';  end   return properties[args.italic or args.italics or args.i], nil; -- return an appropriate value and a nil error message end   --[=[--------------------------< V A L I D A T E _ C A T _ A R G S >----------------------------------------------------------  Default behavior of the {{lang}} and {{lang-xx}} templates is to add categorization when the templates are used in mainspace. This default functionality may be suppressed by setting |nocat=yes or |cat=no. This function selects one of these two parameters to control categorization.  Because having two parameters with 'opposite' names and 'opposite' values is confusing, this function accepts only affirmative values for |nocat= and only negative values for |cat=; in both cases the 'other' sense (and non-sense) is not accepted and the parameter is treated as if it were not set in the template.  Sets args.nocat to true if categorization is to be turned off; to nil if the default behavior should apply.  Accepted values for |nocat= are the text strings:  'yes', 'y', 'true', 't', on, '1' -- [[มอดูล:Yesno]] returns logical true for all of these; false or nil else for |cat=  'no', 'n', 'false', 'f', 'off', '0' -- [[มอดูล: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   --[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------  Whether needle is in haystack  ]]  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   --[[--------------------------< F O R M A T _ I E T F _ T A G >------------------------------------------------  prettify ietf tags to use recommended subtag formats:  code: lower case  script: sentence case  region: upper case  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   --[[--------------------------< G E T _ I E T F _ P A R T S >--------------------------------------------------  extracts and returns IETF language tag parts:  primary language subtag (required) - 2 or 3 character IANA language code  script subtag - four character IANA script code  region subtag - two-letter or three digit IANA region code  variant subtag - four digit or 5-8 alnum variant code; only one variant subtag supported  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, 'ไม่มีแท็กภาษา';  end   local pattern = { -- table of tables holding acceptibe ietf tag patterns and short names of the ietf part captured by the pattern  {'^(%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)  {'^(%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)  {'^(%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)  {'^(%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)   {'^(%a%a%a?)%-(%a%a%a%a)%-(%d%d%d%d)$', 's', 'v'}, -- 5 - ll-Ssss-variant (where variant is 4 digits)  {'^(%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)   {'^(%a%a%a?)%-(%a%a)%-(%d%d%d%d)$', 'r', 'v'}, -- 7 - ll-RR-variant (where variant is 4 digits)  {'^(%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)  {'^(%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)  {'^(%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)   {'^(%a%a%a?)%-(%d%d%d%d)$', 'v'}, -- 11 - ll-variant (where variant is 4 digits)  {'^(%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   if not code then  return nil, nil, nil, nil, nil, table.concat ({'แท็กภาษาที่ไม่รู้จัก: ', 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  return nil, nil, nil, nil, nil, table.concat ({'รหัสภาษาที่ไม่รู้จัก: ', code}); -- invalid language code, don't know about the others (don't care?)  end   if synonym_table[code] then -- if 639-2/639-2T code has a 639-1 synonym  table.insert (maint_cats, table.concat ({'รหัส Lang และ lang-xx เลื่อนระดับเป็น ISO 639-1|', code}));  table.insert (maint_msgs, table.concat ({'รหัส: ', 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, 'แท็กสคริปต์ซ้ำซ้อน'; -- 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  script = script:lower(); -- ensure that we use and return lower case version of this  if not script_table[script] then  return code, nil, nil, nil, nil, table.concat ({'สคริปต์ที่ไม่รู้จัก: ', script, ' สำหรับรหัส: ', code}); -- language code ok, invalid script, don't know about the others (don't care?)  end  end  if suppressed_table[script] then -- ensure that code-script does not use a suppressed script  if in_array (code, suppressed_table[script]) then  return code, nil, nil, nil, nil, table.concat ({'สคริปต์: ', script, ' ไม่รองรับรหัส: ', code}); -- language code ok, script is suppressed for this code  end  end   if is_set (region) then  if is_set (args_region) then  return code, nil, nil, nil, nil, 'แท็กภูมิภาคซ้ำซ้อน'; -- 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 ({'ภูมิภาคที่ไม่รู้จัก: ', region, ' สำหรับรหัส: ', code});  end  end   if is_set (variant) then  if is_set (args_variant) then  return code, nil, nil, nil, nil, 'แท็กตัวแปรซ้ำซ้อน'; -- both code with variant and |variant= not allowed  end  else  variant = args_variant or ''; -- use args.variant if provided  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 ({'ตัวแปรที่ไม่รู้จัก: ', 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 ({'ตัวแปรที่ไม่รู้จัก: ', variant, ' สำหรับคู่รหัสสคริปต์: ', 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 ({'ตัวแปรที่ไม่รู้จัก: ', variant, ' สำหรับคู่รหัสภูมิภาค: ', code, '-', region});  end  end  else  if not in_array (code, variant_table[variant]['prefixes']) then  return code, script, region, nil, nil, table.concat ({'ตัวแปรที่ไม่รู้จัก: ', variant, ' สำหรับรหัส: ', code});  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 ({'แท็กส่วนตัวที่ไม่รู้จัก: ', private});  end  end  return code, script, region, variant, private, nil; -- return the good bits; make sure that msg is nil end   --[[--------------------------< M A K E _ E R R O R _ M S G >--------------------------------------------------  assembles an error message from template name, message text, help link, and error category.  ]]  local function make_error_msg (msg, args, template)  local out = {};  local category;   if 'Transl' == template then  category = 'Transl';  else  category = 'Lang และ lang-xx'  end   table.insert (out, table.concat ({'[', args.text or 'ไม่ได้กำหนด', '] '})); -- for error messages output args.text if available  table.insert (out, table.concat ({'<span style=\"font-size: 100%; font-style: normal;\" class=\"error\">ข้อผิดพลาด: {{', template, '}}: '}));  table.insert (out, msg);  table.insert (out, table.concat ({' ([[:หมวดหมู่:ข้อผิดพลาดแม่แบบ ', category, '|ช่วยเหลือ]])'}));  table.insert (out, '</span>');   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, ']]'}));  end   return table.concat (out); end   --[=[-------------------------< M A K E _ W I K I L I N K >----------------------------------------------------  Makes a wikilink; when both link and display text is provided, returns a wikilink in the form [[L|D]]; if only link is provided, returns a wikilink in the form [[L]]; if neither are provided or link is omitted, returns an empty string.  ]=]  local function make_wikilink (link, display)  if is_set (link) then  if is_set (display) then  return table.concat ({'[[', link, '|', display, ']]'});  else  return table.concat ({'[[', link, ']]'});  end  else  return '';  end end   --[[--------------------------< D I V _ M A R K U P _ A D D >--------------------------------------------------  adds <i> and </i> tags to list-item text or to implied <p>..</p> text. mixed not supported  ]]  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   if text:find ('\n+') then -- look for any number of \n characters in text  text = text:gsub ('([^\n])\n([^\n])', '%1 %2'); -- replace single newline characters with a space character which mimics mediawiki   if 'italic' == style 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)  else  text = text:gsub ('[^\n]+', '<p>%1</p>'); -- insert p markup at each impled p  text = text:gsub ('\n', ''); -- strip newline characters  end  end   return text; end   --[[--------------------------< 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   if 'span' == tag then -- default html tag for inline content  if 'italic' == style then -- but if italic  tag = 'i'; -- change to <i> tags  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   if is_set (language) then  table.insert (html, table.concat ({style_added, ' title=\"', language})); --start the title text  if language:find ('languages') then  table.insert (html, ' collective text'); -- for collective languages  else  table.insert (html, '-language text'); -- for individual languages  end  table.insert (html, '\">'); -- close the opening html tag  else  table.insert (html, table.concat ({style_added, '>'})); -- close the style attribute and close opening html tag  end  table.insert (html, text); -- insert the text   table.insert (html, table.concat ({'</', tag, '>'})); -- close the <i>, <span>, or <div> html tag   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   --[=[-------------------------< M A K E _ C A T E G O R Y >----------------------------------------------------  สำหรับแต่ละภาษา <language> จะส่งคืนค่า:  [[หมวดหมู่:บทความที่มีข้อความภาษา<language>]]  สำหรับไทย:  [[หมวดหมู่:บทความที่มีข้อความภาษาไทยอ้างอิงอย่างชัดเจน]]   สำหรับ ISO 639-2 (และสำหรับ 639-1 bh):  [[หมวดหมู่:บทความที่มีข้อความภาษา<language>]]  ]=]  local function make_category (code, language_name, nocat, name_get)  local cat = {};  local retval;   if ((0 ~= namespace) or nocat) and not name_get then -- only categorize in article space  return ''; -- return empty string for concatenation  end   if language_name:find ('languages') then  return table.concat ({'[[หมวดหมู่:บทความที่มีข้อความในภาษา', language_name, ']]'});  end   table.insert (cat, '[[หมวดหมู่:บทความที่มีข้อความภาษา');   if 'th' == code then  table.insert (cat, language_name .. 'อ้างอิงอย่างชัดเจน'); -- falls back to Thai if regional name not available  else  table.insert (cat, language_name);  end   table.insert (cat, ']]');   return table.concat (cat); end   --[[--------------------------< M A K E _ T R A N S L I T >----------------------------------------------------  return translit <i lang=xx-Latn>...</i> where xx is the language code; else return empty string  The value |script= is not used in {{transl}} for this purpose; instead it uses |code. Because language scripts are listed in the {{transl}} switches they are included in the data tables. The script parameter is introduced at {{Language with name and transliteration}}. If |script= is set, this function uses it in preference to code.  To avoid confusion, in this module and the templates that use it, the transliteration script parameter is renamed to be |translit-script= (in this function, tscript)  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 style then -- nil for the default italic style  table.insert (tout, "<i lang=\""); -- so use <i> tag  else  table.insert (tout, table.concat ({'<span style=\"font-style: ', style, '\" lang=\"'})); -- non-standard style, construct a span tag for it  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   std = std and std:lower(); -- lower case for table indexing   if not is_set (std) and not is_set (tscript) then -- when neither standard nor script specified  table.insert (tout, language_name); -- write a generic tool tip  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, ' romanization'); -- finish the tool tip; use romanization when neither script nor standard supplied  elseif is_set (std) and is_set (tscript) then -- when both are specified  if title_table[std] then -- and if standard is legitimate  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  return ''; -- invalid standard, setup for error message  end   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 ('ไม่มีข้อความ', 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 ('ข้อความมีมาร์กอัปผิดรูปแบบ', 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 ('ข้อความมีมาร์กอัปตัวเอียง', args, template);  end  end end   --[[--------------------------< 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  table.insert (maint, table.concat ({'<span class="lang-comment" style="font-style: normal; display: none; color: #33aa33; margin-left: 0.3em;">'})); -- opening <span> tag  for _, msg in ipairs (maint_msgs) do  table.insert (maint, table.concat ({msg, ' '})); -- add message strings  end  table.insert (maint, '</span>'); -- close the span  end   if (0 < #maint_cats) and (0 == namespace) and not nocat then -- when there are maintenance categories; article namespace only  for _, cat in ipairs (maint_cats) do  table.insert (maint, table.concat ({'[[Category:', cat, ']]'})); -- format and add the categories  end  end   return table.concat (maint); end   --[[--------------------------< P R O T O _ P R E F I X >------------------------------------------------------  for proto languages, text is prefixed with a splat. We do that here as a flag for make_text_html() so that a splat will be rendered outside of italic markup (if used). If the first character in text here is already a splat, we do nothing  proto_param is boolean or nil; true adds splat prefix regardless of language name; false removes and / or inhibits regardless of language name; nil does nothing; presumes that the value in text is correct but removes extra splac  ]]  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   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.  ]]  local function has_poem_tag (text)  return text:find ('\127[^\127]*UNIQ%-%-poem%-[%a%d]+%-QINU[^\127]*\127') and true or false; end   --[[--------------------------< H T M L _ T A G _ S E L E C T >------------------------------------------------  Inspects content of and selectively trims text. Returns text and the name of an appropriate html tag for text.  If text contains:  \n\n text has implied <p>..</p> tags - trim leading and trailing whitespace and return  If text begins with list markup:  \n* unordered  \n; definition  \n: definition  \n# ordered 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   return text, tag; end   --[[--------------------------< V A L I D A T E _ P R O T O >--------------------------------------------------  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=  ]]  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   --[[--------------------------< L A N G U A G E _ N A M E _ G E T >--------------------------------------------  common function to return language name from the data set according to IETF tag  returns language name if found in data tables; nil else  ]]  local function language_name_get (ietf, code, cat)  ietf = ietf:lower(); -- ietf:lower() because format_ietf_tag() returns mixed case   local name; -- remains nil if not found   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   if is_set (subtags.script) then -- if script set, override rtl setting  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   --[[--------------------------< 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 (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  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   if is_set (subtags.script) then -- if script set override rtl setting  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.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  if language_name:find ('languages') then  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_name)); -- language name with wikilink  end  end  table.insert (out, ': '); -- separator  end   if 'invert' == args.italic then  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, ('none' == args.label) and language_name or 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)  table.insert (out, ', '); -- comma to separate text from translit  if 'none' ~= args.label then  table.insert (out, '<small>');  if script_table[args['translit-script']] then -- when |translit-script= is set, try to use the script's name  translit_script_name = script_table[args['translit-script'][1]];  else  translit_script_name = language_name; -- fall back on language name  end  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, 'อักษรโรมัน:'); -- 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   if is_set (args.translation) then -- translation (not supported in {{lang}})  args.translation = table.concat ({'&#39;', args.translation, '&#39;'}); -- format the translation; use html entities to avoid wiki markup confusion  table.insert (out, ', ');  if 'none' ~= args.label then  table.insert (out, '<span class="nowrap"><small>'); -- open nowrap span and small tags   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, "&thinsp;</small>"); -- &thinsp; is apparently preferred; renders same width as &nbsp; using chrome as of 2021-03-26   if args.translation:find ('%s') then -- if there are space characters (multiple words) in the translation  args.translation = args.translation:gsub ('%s+', '</span>%1', 1); -- insert the closing nowrap span tag before the first space  else  args.translation = args.translation .. '</span>'; -- else closing nowrap span tag goes after the single word  end  end   table.insert (out, args.translation); -- add the formatted translation  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   --[[--------------------------< 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; also get parent frame end   --[[--------------------------< I S _ I E T F _ T A G _ F R A M E >--------------------------------------------  Module entry point from an {{#invoke:}}; same as is_ietf_tag() except does not get parameters from the parent (template) frame. This function not useful when called by {{lang|fn=is_ietf_tag_frame|<tag>}} because <tag> is in the parent frame.  ]]  local function is_ietf_tag_frame (frame)  return _is_ietf_tag (getArgs (frame, {frameOnly = true,})[1]); -- args[1] is the ietf language tag to be tested; do not 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, label or language_name); -- language name with wikilink  end  end   return language_name; end   --[[--------------------------< N A M E _ F R O M _ T A G >----------------------------------------------------  Module entry point from an {{#invoke:}}  ]]  local function name_from_tag (frame) -- entry point from an {{#invoke:Lang|name_from_tag|<ietf tag>|link=<yes>|template=<template name>}}  return _name_from_tag (getArgs(frame)) -- pass-on the args table, nothing else; getArgs() so we also get parent frame end   --[[--------------------------< _ T A G _ F R O M _ N A M E >--------------------------------------------------  Returns the ietf language tag associated with the language name. Spelling of language name must be correct according to the spelling in the source tables. When a standard language name has a parenthetical disambiguator, that disambiguator must be omitted (they are not present in the data name-to-tag tables).  Module entry point from another module  ]]  local function _tag_from_name (args) -- entry point from another module  local msg;   if args[1] and '' ~= args[1] then  local data = mw.loadData ('มอดูล:Lang/tag from name'); -- get the reversed data tables TODO: change when going live  local lang = args[1]:lower(); -- allow any-case for the language name (speeling must till be correct)  local tag = data.rev_override_table[lang] or data.rev_lang_table[lang] or data.rev_lang_dep_table[lang]; -- get the code; look first in the override then in the standard   if tag then  return tag, true; -- language name found so return tag and done; second return used by is_lang_name()  else  msg = 'language: ' .. args[1] .. ' not found' -- language name not found, error message  end  else  msg = 'missing language name' -- language name not provided, error message  end   local template = '';  if args.template and '' ~= args.template then  template = table.concat ({'{{', args['template'], '}}: '}); -- make template name (if provided by the template)  end  return table.concat ({'<span style=\"font-size: 100%; font-style: normal;\" class=\"error\">Error: ', template, msg, '</span>'}); end   --[[--------------------------< T A G _ F R O M _ N A M E >----------------------------------------------------  Module entry point from an {{#invoke:}}  ]]  local function tag_from_name (frame) -- entry point from an {{#invoke:Lang|tag_from_name|<language name>|link=<yes>|template=<template name>}}  local result, _ = _tag_from_name (getArgs(frame)) -- pass-on the args table, nothing else; getArgs() so we also get parent frame; supress second return used by is_lang_name()  return result; end   --[[--------------------------< I S _ L A N G _ N A M E >------------------------------------------------------  Module entry point from an {{#invoke:}}  ]]  local function is_lang_name (frame)  local _, result = _tag_from_name (getArgs(frame)) -- pass-on the args table, nothing else; getArgs() so we also get parent frame; supress second return used by tag_from_name()  return result and true or nil; end   --[[--------------------------< _ T R A N S L >----------------------------------------------------------------  Module entry point from another module  ]]  local function _transl (args)  local title_table = lang_data.translit_title_table; -- table of transliteration standards and the language codes and scripts that apply to those standards  local language_name; -- language name that matches language code; used for tool tip  local translit; -- transliterated text to display  local script; -- IANA script  local msg; -- for when called functions return an error message   if is_set (args[3]) then -- [3] set when {{transl|code|standard|text}}  args.text = args[3]; -- get the transliterated text  args.translit_std = args[2] and args[2]:lower(); -- get the standard; lower case for table indexing   if not title_table[args.translit_std] then  return make_error_msg (table.concat ({'unrecognized transliteration standard: ', args.translit_std}), args, 'Transl');  end  else  if is_set (args[2]) then -- [2] set when {{transl|code|text}}  args.text = args[2]; -- get the transliterated text  else  if args[1] and args[1]:match ('^%a%a%a?%a?$') then -- args[2] missing; is args[1] a code or its it the transliterated text?  return make_error_msg ('no text', args, 'Transl'); -- args[1] is a code so we're missing text  else  args.text = args[1]; -- args[1] is not a code so we're missing that; assign args.text for error message  return make_error_msg ('missing language / script code', args, 'Transl');  end  end  end   if is_set (args[1]) then -- IANA language code used for html lang= attribute; or ISO 15924 script code  if args[1]:match ('^%a%a%a?%a?$') then -- args[1] has correct form?  args.code = args[1]:lower(); -- use the language/script code; only (2, 3, or 4 alpha characters); lower case because table indexes are lower case  else  return make_error_msg (table.concat ({'unrecognized language / script code: ', args[1]}), args, 'Transl'); -- invalid language / script code  end  else  return make_error_msg ('missing language / script code', args, 'Transl'); -- missing language / script code so quit  end   args.italic, msg = validate_italic (args);  if msg then  return make_error_msg (msg, args, 'Transl');  end   if 'italic' == args.italic then -- 'italic' when |italic=yes; because that is same as absent or not set and |italic=default  args.italic = nil; -- set to nil;   end   if override_table[args.code] then -- is code a language code defined in the override table?  language_name = override_table[args.code][1];  elseif lang_table[args.code] then -- is code a language code defined in the standard language code tables?  language_name = lang_table[args.code][1];  elseif lang_dep_table[args.code] then -- is code a language code defined in the deprecated language code tables?  language_name = lang_dep_table[args.code][1];  elseif script_table[args.code] then -- if here, code is not a language code; is it a script code?  language_name = script_table[args.code][1];  script = args.code; -- code was an ISO 15924 script so use that instead  args.code = ''; -- unset because not a language code  else  return make_error_msg (table.concat ({'unrecognized language / script code: ', args.code}), args, 'Transl'); -- invalid language / script code  end  -- here only when all parameters passed to make_translit() are valid  return make_translit (args.code, language_name, args.text, args.translit_std, script, args.italic); end   --[[--------------------------< T R A N S L >------------------------------------------------------------------  Module entry point from an {{#invoke:}}  ]]  local function transl (frame)  return _transl (getArgs(frame)); end   --[[--------------------------< C A T E G O R Y _ F R O M _ T A G >--------------------------------------------  Returns category 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.  Module entry point from another module  ]]  local function _category_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 category_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  category_name = language_name_get (raw_code, code); -- get language name; try ietf tag first, then code w/o variant then code w/ variant  category_name = make_category (code, category_name, nil, true):gsub ('[%[%]]', '');   return category_name; end   --[[--------------------------< C A T E G O R Y _ F R O M _ T A G >--------------------------------------------  Module entry point from an {{#invoke:}}  ]]  local function category_from_tag (frame) -- entry point from an {{#invoke:Lang|category_from_tag|<ietf tag>|template=<template name>}}  return _category_from_tag (getArgs (frame)); -- pass-on the args table, nothing else; getArgs() so we also get parent frame end   --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]]  return {  category_from_tag = category_from_tag,  lang = lang, -- entry point for {{lang}}  lang_xx_inherit = lang_xx_inherit, -- entry points for {{lang-??}}  lang_xx_italic = lang_xx_italic,  is_ietf_tag = is_ietf_tag,  is_ietf_tag_frame = is_ietf_tag_frame,  is_lang_name = is_lang_name,  tag_from_name = tag_from_name, -- returns ietf tag associated with language name  name_from_tag = name_from_tag, -- used for template documentation; possible use in ISO 639 name from code templates  transl = transl, -- entry point for {{transl}}   _category_from_tag = _category_from_tag, -- entry points when this module is require()d into other modules  _lang = _lang,  _lang_xx_inherit = _lang_xx_inherit,  _lang_xx_italic = _lang_xx_italic,  _is_ietf_tag = _is_ietf_tag,  get_ietf_parts = get_ietf_parts,  _tag_from_name = _tag_from_name,  _name_from_tag = _name_from_tag,  _transl = _transl,  }; 

มอด, lang, อการใช, งานมอด, สร, าง, ณอาจจะต, องการสร, างค, อการใช, งานของมอด, ลน, เข, ยนสามารถทำการทดลองได, กระบะทราย, สร, าง, ดลอก, และช, ดทดสอบ, สร, าง, ของมอด, ลน, โปรดเพ, มหมวดหม, ไปท, หน, าย, อย, หน, าย, อยของมอด, ลน, support, lang, lang, transl, templates. khumuxkarichnganmxdul srang khunxaccatxngkarsrangkhumuxkarichngankhxngmxdulniphuekhiynsamarththakarthdlxngidthikrabathray srang khdlxk aelachudthdsxb srang khxngmxdulnioprdephimhmwdhmuipthihnayxy doc hnayxykhxngmxdulni Lua support for the lang lang xx and transl templates and replacement of various supporting templates require mxdul No globals local getArgs require mxdul Arguments getArgs local unicode require mxdul Unicode data for is latin and is rtl local yesno require mxdul Yesno local lang data mw loadData mxdul Lang data language name override and transliteration tool tip tables local lang name table lang data lang name table language codes names regions scripts suppressed scripts 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 mxdul 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 lt I S S E T gt 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 lt I N V E R T I T A L I C S gt 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 amp 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 seg 1 invert pattern table seg 1 or seg 1 replace leading markup according to pattern table 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 lt V A L I D A T E I T A L I C gt 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 if count gt 1 then return nil and an error message if more than one is set return nil only one of italic italics or i can be specified end return properties args italic or args italics or args i nil return an appropriate value and a nil error message end lt V A L I D A T E C A T A R G S gt Default behavior of the lang and lang xx templates is to add categorization when the templates are used in mainspace This default functionality may be suppressed by setting nocat yes or cat no This function selects one of these two parameters to control categorization Because having two parameters with opposite names and opposite values is confusing this function accepts only affirmative values for nocat and only negative values for cat in both cases the other sense and non sense is not accepted and the parameter is treated as if it were not set in the template Sets args nocat to true if categorization is to be turned off to nil if the default behavior should apply Accepted values for nocat are the text strings yes y true t on 1 mxdul Yesno returns logical true for all of these false or nil else for cat no n false f off 0 mxdul 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 lt I N A R R A Y gt Whether needle is in haystack 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 lt F O R M A T I E T F T A G gt prettify ietf tags to use recommended subtag formats code lower case script sentence case region upper case 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 lt G E T I E T F P A R T S gt extracts and returns IETF language tag parts primary language subtag required 2 or 3 character IANA language code script subtag four character IANA script code region subtag two letter or three digit IANA region code variant subtag four digit or 5 8 alnum variant code only one variant subtag supported 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 immiaethkphasa end local pattern table of tables holding acceptibe ietf tag patterns and short names of the ietf part captured by the pattern 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 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 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 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 a a a a a a a d d d d s v 5 ll Ssss variant where variant is 4 digits 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 a a a a a d d d d r v 7 ll RR variant where variant is 4 digits 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 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 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 a a a d d d d v 11 ll variant where variant is 4 digits 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 if not code then return nil nil nil nil nil table concat aethkphasathiimruck 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 return nil nil nil nil nil table concat rhsphasathiimruck code invalid language code don t know about the others don t care end if synonym table code then if 639 2 639 2T code has a 639 1 synonym table insert maint cats table concat rhs Lang aela lang xx eluxnradbepn ISO 639 1 code table insert maint msgs table concat rhs code eluxnradbepnrhs 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 aethkskhriptsasxn 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 script script lower ensure that we use and return lower case version of this if not script table script then return code nil nil nil nil table concat skhriptthiimruck script sahrbrhs code language code ok invalid script don t know about the others don t care end end if suppressed table script then ensure that code script does not use a suppressed script if in array code suppressed table script then return code nil nil nil nil table concat skhript script imrxngrbrhs code language code ok script is suppressed for this code end end if is set region then if is set args region then return code nil nil nil nil aethkphumiphakhsasxn 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 phumiphakhthiimruck region sahrbrhs code end end if is set variant then if is set args variant then return code nil nil nil nil aethktwaeprsasxn both code with variant and variant not allowed end else variant args variant or use args variant if provided 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 twaeprthiimruck 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 twaeprthiimruck variant sahrbkhurhsskhript 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 twaeprthiimruck variant sahrbkhurhsphumiphakh code region end end else if not in array code variant table variant prefixes then return code script region nil nil table concat twaeprthiimruck variant sahrbrhs code 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 aethkswntwthiimruck private end end return code script region variant private nil return the good bits make sure that msg is nil end lt M A K E E R R O R M S G gt assembles an error message from template name message text help link and error category local function make error msg msg args template local out local category if Transl template then category Transl else category Lang aela lang xx end table insert out table concat args text or imidkahnd for error messages output args text if available table insert out table concat lt span style font size 100 font style normal class error gt khxphidphlad template table insert out msg table insert out table concat hmwdhmu khxphidphladaemaebb category chwyehlux table insert out lt span gt 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 hmwdhmu khxphidphladaemaebb category end return table concat out end lt M A K E W I K I L I N K gt Makes a wikilink when both link and display text is provided returns a wikilink in the form L D if only link is provided returns a wikilink in the form L if neither are provided or link is omitted returns an empty string local function make wikilink link display if is set link then if is set display then return table concat link display else return table concat link end else return end end lt D I V M A R K U P A D D gt adds lt i gt and lt i gt tags to list item text or to implied lt p gt lt p gt text mixed not supported 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 lt i gt 2 lt i gt insert italic markup at each list item else return text end end if text find n then look for any number of n characters in text text text gsub n n n 1 2 replace single newline characters with a space character which mimics mediawiki if italic style then text text gsub n lt p gt lt i gt 1 lt i gt lt p gt insert p and italic markup tags at each impled p two or more consecutive n n sequences else text text gsub n lt p gt 1 lt p gt insert p markup at each impled p text text gsub n strip newline characters end end return text end lt M A K E T E X T H T M L gt Add the html markup to text according to the type of content that it is lt span gt or lt i gt tags for inline content or lt div gt 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 amp 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 if span tag then default html tag for inline content if italic style then but if italic tag i change to lt i gt tags end else must be div so go text div markup add text style handle implied lt p gt implied lt p gt with lt i gt and list markup with lt i gt end table insert html table concat lt tag open the lt i gt lt span gt or lt div gt 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 lt something gt 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 if is set language then table insert html table concat style added title language start the title text if language find languages then table insert html collective text for collective languages else table insert html language text for individual languages end table insert html gt close the opening html tag else table insert html table concat style added gt close the style attribute and close opening html tag end table insert html text insert the text table insert html table concat lt tag gt close the lt i gt lt span gt or lt div gt html tag 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 amp 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 lt M A K E C A T E G O R Y gt sahrbaetlaphasa lt language gt casngkhunkha hmwdhmu bthkhwamthimikhxkhwamphasa lt language gt sahrbithy hmwdhmu bthkhwamthimikhxkhwamphasaithyxangxingxyangchdecn sahrb ISO 639 2 aelasahrb 639 1 bh hmwdhmu bthkhwamthimikhxkhwamphasa lt language gt local function make category code language name nocat name get local cat local retval if 0 namespace or nocat and not name get then only categorize in article space return return empty string for concatenation end if language name find languages then return table concat hmwdhmu bthkhwamthimikhxkhwaminphasa language name end table insert cat hmwdhmu bthkhwamthimikhxkhwamphasa if th code then table insert cat language name xangxingxyangchdecn falls back to Thai if regional name not available else table insert cat language name end table insert cat return table concat cat end lt M A K E T R A N S L I T gt return translit lt i lang xx Latn gt lt i gt where xx is the language code else return empty string The value script is not used in transl for this purpose instead it uses code Because language scripts are listed in the transl switches they are included in the data tables The script parameter is introduced at Language with name and transliteration If script is set this function uses it in preference to code To avoid confusion in this module and the templates that use it the transliteration script parameter is renamed to be translit script in this function tscript 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 style then nil for the default italic style table insert tout lt i lang so use lt i gt tag else table insert tout table concat lt span style font style style lang non standard style construct a span tag for it end table insert tout code table insert tout Latn title transliterations are always Latin script else table insert tout lt span title when no language code no lang attribute not italic transl only end std std and std lower lower case for table indexing if not is set std and not is set tscript then when neither standard nor script specified table insert tout language name write a generic tool tip 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 romanization finish the tool tip use romanization when neither script nor standard supplied elseif is set std and is set tscript then when both are specified if title table std then and if standard is legitimate 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 return invalid standard setup for error message end 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 gt 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 lt i gt close the italic tag else table insert tout lt span gt no language code so close the span tag end return table concat tout end lt V A L I D A T E T E X T gt 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 immikhxkhwam 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 khxkhwammimarkxpphidrupaebb 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 khxkhwammimarkxptwexiyng args template end end end lt R E N D E R M A I N T gt render mainenance messages and categories local function render maint nocat local maint if 0 lt maint msgs then when there are maintenance messages table insert maint table concat lt span class lang comment style font style normal display none color 33aa33 margin left 0 3em gt opening lt span gt tag for msg in ipairs maint msgs do table insert maint table concat msg add message strings end table insert maint lt span gt close the span end if 0 lt maint cats and 0 namespace and not nocat then when there are maintenance categories article namespace only for cat in ipairs maint cats do table insert maint table concat Category cat format and add the categories end end return table concat maint end lt P R O T O P R E F I X gt for proto languages text is prefixed with a splat We do that here as a flag for make text html so that a splat will be rendered outside of italic markup if used If the first character in text here is already a splat we do nothing proto param is boolean or nil true adds splat prefix regardless of language name false removes and or inhibits regardless of language name nil does nothing presumes that the value in text is correct but removes extra splac 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 return text gsub return text unmolested except multiple splats reduced to one splat end lt H A S P O E M T A G gt 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 local function has poem tag text return text find 127 127 UNIQ poem a d QINU 127 127 and true or false end lt H T M L T A G S E L E C T gt Inspects content of and selectively trims text Returns text and the name of an appropriate html tag for text If text contains n n text has implied lt p gt lt p gt tags trim leading and trailing whitespace and return If text begins with list markup n unordered n definition n definition n ordered trim all leading whitespace except n and trim all trailing whitespace If text contains lt poem gt lt poem gt stripmarker return text unmodified and choose lt div gt lt div gt tags because the stripmarker is replaced with text wrapped in lt div gt lt div gt 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 return text tag end lt V A L I D A T E P R O T O gt 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 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 lt L A N G U A G E N A M E G E T gt common function to return language name from the data set according to IETF tag returns language name if found in data tables nil else local function language name get ietf code cat ietf ietf lower ietf lower because format ietf tag returns mixed case local name remains nil if not found 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 lt L A N G gt entry point for lang there should be no reason to set parameters in the lang invoke lt includeonly gt invoke lang lang lt includeonly gt 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 gt true other values gt 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 if is set subtags script then if script set override rtl setting 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 lt L A N G gt entry point for lang there should be no reason to set parameters in the lang invoke lt includeonly gt invoke lang lang lt includeonly gt parameters are received from the template s frame parent frame 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 return nil value was empty or contained only whitespace end end of valueFunc return lang args end lt L A N G X X gt 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 lt includeonly gt invoke lang lang xx inherit code xx lt includeonly gt For italic style lt includeonly gt invoke lang lang xx italic code xx lt includeonly gt 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 gt true other values gt 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 lt initial style state gt end else args italic initial style state here when italic and script not set set for font style lt initial style state gt end end if is set subtags script then if script set override rtl setting 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 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 if language name find languages then 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 phasa language name language name language name with wikilink end end table insert out separator end if invert args italic then 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 none args label and language name or 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 table insert out comma to separate text from translit if none args label then table insert out lt small gt if script table args translit script then when translit script is set try to use the script s name translit script name script table args translit script 1 else translit script name language name fall back on language name end 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 xksrormn else plain text end table insert out amp nbsp lt small gt 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 if is set args translation then translation not supported in lang args translation table concat amp 39 args translation amp 39 format the translation use html entities to avoid wiki markup confusion table insert out if none args label then table insert out lt span class nowrap gt lt small gt open nowrap span and small tags if no args link then table insert out lt abbr title literal translation gt lit lt abbr gt else table insert out make wikilink Literal translation lit end table insert out amp thinsp lt small gt amp thinsp is apparently preferred renders same width as amp nbsp using chrome as of 2021 03 26 if args translation find s then if there are space characters multiple words in the translation args translation args translation gsub s lt span gt 1 1 insert the closing nowrap span tag before the first space else args translation args translation lt span gt else closing nowrap span tag goes after the single word end end table insert out args translation add the formatted translation 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 lt L A N G X X A R G S G E T gt 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 lt L A N G X X I T A L I C gt 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 lt L A N G X X I T A L I C gt 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 lt L A N G X X I N H E R I T gt 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 lt L A N G X X I N H E R I T gt 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 lt I S I E T F T A G gt 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 lt I S I E T F T A G gt 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 also get parent frame end lt I S I E T F T A G F R A M E gt Module entry point from an invoke same as is ietf tag except does not get parameters from the parent template frame This function not useful when called by lang fn is ietf tag frame lt tag gt because lt tag gt is in the parent frame local function is ietf tag frame frame return is ietf tag getArgs frame frameOnly true 1 args 1 is the ietf language tag to be tested do not get parent frame end lt N A M E F R O M T A G gt 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 lt span style font size 100 font style normal class error gt Error template msg lt span gt 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 phasa language name label or language name language name with wikilink end end return language name end lt N A M E F R O M T A G gt Module entry point from an invoke local function name from tag frame entry point from an invoke Lang name from tag lt ietf tag gt link lt yes gt template lt template name gt return name from tag getArgs frame pass on the args table nothing else getArgs so we also get parent frame end lt T A G F R O M N A M E gt Returns the ietf language tag associated with the language name Spelling of language name must be correct according to the spelling in the source tables When a standard language name has a parenthetical disambiguator that disambiguator must be omitted they are not present in the data name to tag tables Module entry point from another module local function tag from name args entry point from another module local msg if args 1 and args 1 then local data mw loadData mxdul Lang tag from name get the reversed data tables TODO change when going live local lang args 1 lower allow any case for the language name speeling must till be correct local tag data rev override table lang or data rev lang table lang or data rev lang dep table lang get the code look first in the override then in the standard if tag then return tag true language name found so return tag and done second return used by is lang name else msg language args 1 not found language name not found error message end else msg missing language name language name not provided error message end local template if args template and args template then template table concat args template make template name if provided by the template end return table concat lt span style font size 100 font style normal class error gt Error template msg lt span gt end lt T A G F R O M N A M E gt Module entry point from an invoke local function tag from name frame entry point from an invoke Lang tag from name lt language name gt link lt yes gt template lt template name gt local result tag from name getArgs frame pass on the args table nothing else getArgs so we also get parent frame supress second return used by is lang name return result end lt I S L A N G N A M E gt Module entry point from an invoke local function is lang name frame local result tag from name getArgs frame pass on the args table nothing else getArgs so we also get parent frame supress second return used by tag from name return result and true or nil end lt T R A N S L gt Module entry point from another module local function transl args local title table lang data translit title table table of transliteration standards and the language codes and scripts that apply to those standards local language name language name that matches language code used for tool tip local translit transliterated text to display local script IANA script local msg for when called functions return an error message if is set args 3 then 3 set when transl code standard text args text args 3 get the transliterated text args translit std args 2 and args 2 lower get the standard lower case for table indexing if not title table args translit std then return make error msg table concat unrecognized transliteration standard args translit std args Transl end else if is set args 2 then 2 set when transl code text args text args 2 get the transliterated text else if args 1 and args 1 match a a a a then args 2 missing is args 1 a code or its it the transliterated text return make error msg no text args Transl args 1 is a code so we re missing text else args text args 1 args 1 is not a code so we re missing that assign args text for error message return make error msg missing language script code args Transl end end end if is set args 1 then IANA language code used for html lang attribute or ISO 15924 script code if args 1 match a a a a then args 1 has correct form args code args 1 lower use the language script code only 2 3 or 4 alpha characters lower case because table indexes are lower case else return make error msg table concat unrecognized language script code args 1 args Transl invalid language script code end else return make error msg missing language script code args Transl missing language script code so quit end args italic msg validate italic args if msg then return make error msg msg args Transl end if italic args italic then italic when italic yes because that is same as absent or not set and italic default args italic nil set to nil end if override table args code then is code a language code defined in the override table language name override table args code 1 elseif lang table args code then is code a language code defined in the standard language code tables language name lang table args code 1 elseif lang dep table args code then is code a language code defined in the deprecated language code tables language name lang dep table args code 1 elseif script table args code then if here code is not a language code is it a script code language name script table args code 1 script args code code was an ISO 15924 script so use that instead args code unset because not a language code else return make error msg table concat unrecognized language script code args code args Transl invalid language script code end here only when all parameters passed to make translit are valid return make translit args code language name args text args translit std script args italic end lt T R A N S L gt Module entry point from an invoke local function transl frame return transl getArgs frame end lt C A T E G O R Y F R O M T A G gt Returns category 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 Module entry point from another module local function category 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 category 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 lt span style font size 100 font style normal class error gt Error template msg lt span gt end raw code format ietf tag code subtags script subtags region subtags variant subtags private format to recommended subtag styles private omitted because private category name language name get raw code code get language name try ietf tag first then code w o variant then code w variant category name make category code category name nil true gsub return category name end lt C A T E G O R Y F R O M T A G gt Module entry point from an invoke local function category from tag frame entry point from an invoke Lang category from tag lt ietf tag gt template lt template name gt return category from tag getArgs frame pass on the args table nothing else getArgs so we also get parent frame end lt E X P O R T E D F U N C T I O N S gt return category from tag category from tag lang lang entry point for lang lang xx inherit lang xx inherit entry points for lang lang xx italic lang xx italic is ietf tag is ietf tag is ietf tag frame is ietf tag frame is lang name is lang name tag from name tag from name returns ietf tag associated with language name name from tag name from tag used for template documentation possible use in ISO 639 name from code templates transl transl entry point for transl category from tag category from tag entry points when this module is require d into other modules lang lang lang xx inherit lang xx inherit lang xx italic lang xx italic is ietf tag is ietf tag get ietf parts get ietf parts tag from name tag from name name from tag name from tag transl transl ekhathungcak https th wikipedia org w index php title mxdul Lang amp oldid 9323649, wikipedia, วิกิ หนังสือ, หนังสือ, ห้องสมุด,

บทความ

, อ่าน, ดาวน์โหลด, ฟรี, ดาวน์โหลดฟรี, mp3, วิดีโอ, mp4, 3gp, jpg, jpeg, gif, png, รูปภาพ, เพลง, เพลง, หนัง, หนังสือ, เกม, เกม