<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.pttlink.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMultilingual_description%2Fsort%2Ftestcases</id>
	<title>Module:Multilingual description/sort/testcases - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.pttlink.org/index.php?action=history&amp;feed=atom&amp;title=Module%3AMultilingual_description%2Fsort%2Ftestcases"/>
	<link rel="alternate" type="text/html" href="https://wiki.pttlink.org/index.php?title=Module:Multilingual_description/sort/testcases&amp;action=history"/>
	<updated>2026-05-17T03:22:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.5</generator>
	<entry>
		<id>https://wiki.pttlink.org/index.php?title=Module:Multilingual_description/sort/testcases&amp;diff=6059&amp;oldid=prev</id>
		<title>Kg7qin: Created page with &quot;local p = {}  local char = string.char local floor = math.floor local insert = table.insert require('mw.ustring') local langs = require('Module:Multilingual description/sort')...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.pttlink.org/index.php?title=Module:Multilingual_description/sort/testcases&amp;diff=6059&amp;oldid=prev"/>
		<updated>2022-01-21T09:15:23Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local p = {}  local char = string.char local floor = math.floor local insert = table.insert require(&amp;#039;mw.ustring&amp;#039;) local langs = require(&amp;#039;Module:Multilingual description/sort&amp;#039;)...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local char = string.char&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
require('mw.ustring')&lt;br /&gt;
local langs = require('Module:Multilingual description/sort')&lt;br /&gt;
local dir = require('Module:Dir')&lt;br /&gt;
&lt;br /&gt;
local function toUTF8(code)&lt;br /&gt;
   -- Note: this function is stricter than the builtin function of the Lua library, but it&lt;br /&gt;
   -- detects without error invalid codes (which are &amp;quot;escaped&amp;quot; insterad of returning an error)&lt;br /&gt;
   if code &amp;gt;= 0 and code == floor(code) then&lt;br /&gt;
       if code &amp;lt;= 0x7F then -- use 1-byte UTF-8 for ASCII (including C0 controls)&lt;br /&gt;
           return char(code)&lt;br /&gt;
       elseif code &amp;lt;= 0x7FF then -- use 2-byte UTF-8 for characters in the lowest alphabetic part of the BMP (C1 controls, generic diacritics, and most frequently used characters for Latin, Greek, Cyrillic, Armenian, Hebrew, Arabic, Syriac, Thaana or N'Ko scripts)&lt;br /&gt;
           local b0, b1 = code % 64, floor(code / 64)&lt;br /&gt;
           return char(0xC0 + b1) .. char(0x80 + b0)&lt;br /&gt;
       elseif code &amp;lt;= 0xD7FF&lt;br /&gt;
           or code &amp;gt;= 0xE000 and code &amp;lt;= 0xFFCF&lt;br /&gt;
           or code &amp;gt;= 0xFFF0 and code &amp;lt;= 0xFFFD then -- use 3-byte UTF-8 for the rest of the BMP (excluding surrogate code points and non-characters)&lt;br /&gt;
           local b0, b1, b2 = code % 64, floor(code / 64)&lt;br /&gt;
           b1, b2 = b1 % 64, floor(b1 / 64)&lt;br /&gt;
           return char(0xE0 + b2) .. char(0x80 + b1) .. char(0x80 + b0)&lt;br /&gt;
       elseif code &amp;lt;= 0x10FFFF and code % 0x10000 &amp;lt;= 0xFFFD then -- use 4-byte UTF-8 for supplementary characters (excluding non-characters)&lt;br /&gt;
           local b0, b1, b2, b3 = code % 64, floor(code / 64)&lt;br /&gt;
           b1, b2 = b1 % 64, floor(b1 / 64)&lt;br /&gt;
           b2, b3 = b2 % 64, floor(b2 / 64)&lt;br /&gt;
           return char(0xF0 + b3) .. char(0x80 + b2) .. char(0x80 + b1) .. char(0x80 + b0)&lt;br /&gt;
       end&lt;br /&gt;
   end&lt;br /&gt;
   return '\\{' .. tostring(code) .. '}' -- not a valid Unicode code point, or non-character&lt;br /&gt;
end&lt;br /&gt;
local nce = { -- used in the first pass of htmlize(wikitext) for converting some known named character entities to UTF-8&lt;br /&gt;
    quot = '&amp;quot;',&lt;br /&gt;
    amp = '&amp;amp;',&lt;br /&gt;
    apos = &amp;quot;'&amp;quot;,&lt;br /&gt;
    lt = '&amp;lt;',&lt;br /&gt;
    gt = '&amp;gt;',&lt;br /&gt;
    nbsp = toUTF8(0xA0),&lt;br /&gt;
    shy = toUTF8(0xAD),&lt;br /&gt;
    enquad = toUTF8(0x2000),&lt;br /&gt;
    emquad = toUTF8(0x2001),&lt;br /&gt;
    ensp = toUTF8(0x2002),&lt;br /&gt;
    emsp = toUTF8(0x2003),&lt;br /&gt;
    emsp13 = toUTF8(0x2004),&lt;br /&gt;
    emsp14 = toUTF8(0x2005),&lt;br /&gt;
    emsp16 = toUTF8(0x2006),&lt;br /&gt;
    numsp = toUTF8(0x2007),&lt;br /&gt;
    puncsp = toUTF8(0x2008),&lt;br /&gt;
    thinsp = toUTF8(0x2009),&lt;br /&gt;
    hairsp = toUTF8(0x200A),&lt;br /&gt;
    zwsp = toUTF8(0x200B),&lt;br /&gt;
    zwnj = toUTF8(0x200C),&lt;br /&gt;
    zwj  = toUTF8(0x200D),&lt;br /&gt;
    lrm  = toUTF8(0x200E),&lt;br /&gt;
    rlm  = toUTF8(0x200F),&lt;br /&gt;
    lsep = toUTF8(0x2028),&lt;br /&gt;
    psep = toUTF8(0x2029),&lt;br /&gt;
    lre = toUTF8(0x202A),&lt;br /&gt;
    rle = toUTF8(0x202B),&lt;br /&gt;
    pdf = toUTF8(0x202C),&lt;br /&gt;
    lro = toUTF8(0x202D),&lt;br /&gt;
    rlo = toUTF8(0x202E),&lt;br /&gt;
    nnbsp = toUTF8(0x202F),&lt;br /&gt;
    mathsp = toUTF8(0x205F),&lt;br /&gt;
    wj = toUTF8(0x2060), NoBreak = toUTF8(0x2060),&lt;br /&gt;
    lri = toUTF8(0x2066),&lt;br /&gt;
    rli = toUTF8(0x2067),&lt;br /&gt;
    fsi = toUTF8(0x2068),&lt;br /&gt;
    pdi = toUTF8(0x2069),&lt;br /&gt;
    iss = toUTF8(0x206A),&lt;br /&gt;
    ass = toUTF8(0x206B),&lt;br /&gt;
    iafs = toUTF8(0x206C),&lt;br /&gt;
    aafs = toUTF8(0x206D),&lt;br /&gt;
    natds = toUTF8(0x206E),&lt;br /&gt;
    nomds = toUTF8(0x206F),&lt;br /&gt;
    idsp = toUTF8(0x3000),&lt;br /&gt;
    zwnbsp  = toUTF8(0xFEFF),&lt;br /&gt;
}&lt;br /&gt;
local codemap = { -- will generate a stringmap used in the second pass htmlize(wikitext) for visual sanity check of the UTF-8 encoding of isolated characters&lt;br /&gt;
    -- Indexed by Unicode codepoint:&lt;br /&gt;
    -- Non-ASCII codepoints will be added to a stringmap (from their multibyte UTF-8 encoding), in an unspecified order of code point values, to replace them first by visual strings.&lt;br /&gt;
    -- ASCII codepoints will be converted using a single character pattern, after mapping all other non-ASCII codepoints from this table.&lt;br /&gt;
    [0x00] = '\\000',  -- &amp;lt;control&amp;gt; &amp;lt;NUL&amp;gt;      invalid in HTML (%z class in patterns)&lt;br /&gt;
    [0x01] = '\\001',  -- &amp;lt;control&amp;gt; &amp;lt;SOH&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x02] = '\\002',  -- &amp;lt;control&amp;gt; &amp;lt;STX&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x03] = '\\003',  -- &amp;lt;control&amp;gt; &amp;lt;ETX&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x04] = '\\004',  -- &amp;lt;control&amp;gt; &amp;lt;EOT&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x05] = '\\005',  -- &amp;lt;control&amp;gt; &amp;lt;ENQ&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x06] = '\\006',  -- &amp;lt;control&amp;gt; &amp;lt;ACK&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x07] = '\\a',    -- &amp;lt;control&amp;gt; &amp;lt;BEL&amp;gt; '\a' invalid in HTML&lt;br /&gt;
    [0x08] = '\\b',    -- &amp;lt;control&amp;gt; &amp;lt;BS&amp;gt;  '\b' invalid in HTML&lt;br /&gt;
    [0x09] = '&amp;amp;#9;',   -- &amp;lt;control&amp;gt; &amp;lt;HT&amp;gt;  '\t' valid in HTML (use source form, can be interpreted)&lt;br /&gt;
    [0x0A] = '&amp;amp;#10;',  -- &amp;lt;control&amp;gt; &amp;lt;LF&amp;gt;  '\n' valid in HTML (use source form, can be interpreted)&lt;br /&gt;
    [0x0B] = '\\v',    -- &amp;lt;control&amp;gt; &amp;lt;VT&amp;gt;  '\v' invalid in HTML&lt;br /&gt;
    [0x0C] = '\\f',    -- &amp;lt;control&amp;gt; &amp;lt;FF&amp;gt;  '\f' invalid in HTML&lt;br /&gt;
    [0x0D] = '&amp;amp;#13;',  -- &amp;lt;control&amp;gt; &amp;lt;CR&amp;gt;  '\r' valid in HTML (use source form, can be interpreted)&lt;br /&gt;
    [0x0E] = '\\014',  -- &amp;lt;control&amp;gt; &amp;lt;SO&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x0F] = '\\015',  -- &amp;lt;control&amp;gt; &amp;lt;SI&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x10] = '\\016',  -- &amp;lt;control&amp;gt; &amp;lt;DLE&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x11] = '\\017',  -- &amp;lt;control&amp;gt; &amp;lt;DC1&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x12] = '\\018',  -- &amp;lt;control&amp;gt; &amp;lt;DC2&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x13] = '\\019',  -- &amp;lt;control&amp;gt; &amp;lt;DC3&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x14] = '\\020',  -- &amp;lt;control&amp;gt; &amp;lt;DC4&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x15] = '\\021',  -- &amp;lt;control&amp;gt; &amp;lt;NAK&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x16] = '\\022',  -- &amp;lt;control&amp;gt; &amp;lt;SYN&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x17] = '\\023',  -- &amp;lt;control&amp;gt; &amp;lt;ETB&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x18] = '\\024',  -- &amp;lt;control&amp;gt; &amp;lt;CAN&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x19] = '\\025',  -- &amp;lt;control&amp;gt; &amp;lt;EM&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x1A] = '\\026',  -- &amp;lt;control&amp;gt; &amp;lt;SUB&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x1B] = '\\027',  -- &amp;lt;control&amp;gt; &amp;lt;ESC&amp;gt; '\E' invalid in HTML&lt;br /&gt;
    [0x1C] = '\\028',  -- &amp;lt;control&amp;gt; &amp;lt;FS&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x1D] = '\\029',  -- &amp;lt;control&amp;gt; &amp;lt;GS&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x1E] = '\\030',  -- &amp;lt;control&amp;gt; &amp;lt;RS&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x1F] = '\\031',  -- &amp;lt;control&amp;gt; &amp;lt;US&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x20] = '&amp;amp;#32;',  -- make sure it is visible and not stripped (use source form, can be interpreted)&lt;br /&gt;
    [0x22] = '&amp;amp;quot;', -- '&amp;quot;' HTML escape&lt;br /&gt;
    [0x26] = '&amp;amp;amp;',  -- '&amp;amp;' HTML escape&lt;br /&gt;
    [0x3C] = '&amp;amp;lt;',   -- '&amp;lt;' HTML escape&lt;br /&gt;
    [0x3E] = '&amp;amp;gt;',   -- '&amp;gt;' HTML escape&lt;br /&gt;
    [0x5B] = '&amp;amp;#91;',  -- '[' Wiki escape&lt;br /&gt;
    [0x5C] = '\\\\',   -- '\\' make sure it is distinguished visually from an escape for invalid controls in HTML&lt;br /&gt;
    [0x5D] = '&amp;amp;#93;',  -- ']' Wiki escape&lt;br /&gt;
    [0x7B] = '&amp;amp;#123;', -- '{' Wiki escape&lt;br /&gt;
    [0x7C] = '&amp;amp;#124;', -- '|' Wiki escape&lt;br /&gt;
    [0x7D] = '&amp;amp;#125;', -- '}' Wiki escape&lt;br /&gt;
    [0x7F] = '\\127',  -- &amp;lt;control&amp;gt; &amp;lt;DEL&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x80] = '\\128',  -- &amp;lt;control&amp;gt; &amp;lt;PAD&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x81] = '\\129',  -- &amp;lt;control&amp;gt; &amp;lt;HOP&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x82] = '\\130',  -- &amp;lt;control&amp;gt; &amp;lt;BPH&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x83] = '\\131',  -- &amp;lt;control&amp;gt; &amp;lt;NBH&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x84] = '\\132',  -- &amp;lt;control&amp;gt; &amp;lt;IND&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x85] = '&amp;amp;#133;', -- &amp;lt;control&amp;gt; &amp;lt;NEL&amp;gt;      valid in HTML&lt;br /&gt;
    [0x86] = '\\134',  -- &amp;lt;control&amp;gt; &amp;lt;SSA&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x87] = '\\135',  -- &amp;lt;control&amp;gt; &amp;lt;ESA&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x88] = '\\136',  -- &amp;lt;control&amp;gt; &amp;lt;HTS&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x89] = '\\137',  -- &amp;lt;control&amp;gt; &amp;lt;HTJ&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x8A] = '\\138',  -- &amp;lt;control&amp;gt; &amp;lt;LTS&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x8B] = '\\139',  -- &amp;lt;control&amp;gt; &amp;lt;PLD&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x8C] = '\\140',  -- &amp;lt;control&amp;gt; &amp;lt;PLU&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x8D] = '\\141',  -- &amp;lt;control&amp;gt; &amp;lt;RI&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x8E] = '\\142',  -- &amp;lt;control&amp;gt; &amp;lt;SS2&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x8F] = '\\143',  -- &amp;lt;control&amp;gt; &amp;lt;SS3&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x90] = '\\144',  -- &amp;lt;control&amp;gt; &amp;lt;DCS&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x91] = '\\145',  -- &amp;lt;control&amp;gt; &amp;lt;PU1&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x92] = '\\146',  -- &amp;lt;control&amp;gt; &amp;lt;PU2&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x93] = '\\147',  -- &amp;lt;control&amp;gt; &amp;lt;STS&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x94] = '\\148',  -- &amp;lt;control&amp;gt; &amp;lt;CCH&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x95] = '\\149',  -- &amp;lt;control&amp;gt; &amp;lt;MW&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x96] = '\\150',  -- &amp;lt;control&amp;gt; &amp;lt;SPA&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x97] = '\\151',  -- &amp;lt;control&amp;gt; &amp;lt;EPA&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x98] = '\\152',  -- &amp;lt;control&amp;gt; &amp;lt;SOS&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x99] = '\\153',  -- &amp;lt;control&amp;gt; &amp;lt;SGCI&amp;gt;     invalid in HTML&lt;br /&gt;
    [0x9A] = '\\154',  -- &amp;lt;control&amp;gt; &amp;lt;SCI&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x9B] = '\\155',  -- &amp;lt;control&amp;gt; &amp;lt;CSI&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x9C] = '\\156',  -- &amp;lt;control&amp;gt; &amp;lt;ST&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x9D] = '\\157',  -- &amp;lt;control&amp;gt; &amp;lt;OSC&amp;gt;      invalid in HTML&lt;br /&gt;
    [0x9E] = '\\158',  -- &amp;lt;control&amp;gt; &amp;lt;PM&amp;gt;       invalid in HTML&lt;br /&gt;
    [0x9F] = '\\159',  -- &amp;lt;control&amp;gt; &amp;lt;APC&amp;gt;      invalid in HTML&lt;br /&gt;
    [0xA0] = '&amp;amp;nbsp;',     -- &amp;lt;NON-BREAKING SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0xAD] = '&amp;amp;shy;',      -- &amp;lt;SOFT HYPHEN&amp;gt; HTML escape&lt;br /&gt;
    [0x2000] = '&amp;amp;enquad;', -- &amp;lt;EN QUAD&amp;gt; HTML escape&lt;br /&gt;
    [0x2001] = '&amp;amp;emquad;', -- &amp;lt;EN QUAD&amp;gt; HTML escape&lt;br /&gt;
    [0x2002] = '&amp;amp;ensp;',   -- &amp;lt;EN SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2003] = '&amp;amp;emsp;',   -- &amp;lt;EM SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2004] = '&amp;amp;emsp13;', -- &amp;lt;THREE-PER-EM SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2005] = '&amp;amp;emsp14;', -- &amp;lt;FOUR-PER-EM SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2006] = '&amp;amp;emsp16;', -- &amp;lt;SIX-PER-EM SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2007] = '&amp;amp;numsp;',  -- &amp;lt;FIGURE SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2008] = '&amp;amp;puncsp;', -- &amp;lt;PUNCTUATION SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2009] = '&amp;amp;thinsp;', -- &amp;lt;THIN SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x200A] = '&amp;amp;hairsp;', -- &amp;lt;HAIRY SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x200B] = '&amp;amp;zwsp;',   -- &amp;lt;ZERO-WIDTH SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x200C] = '&amp;amp;zwnj;',   -- &amp;lt;ZERO-WIDTH NON-JOINER&amp;gt; HTML escape&lt;br /&gt;
    [0x200D] = '&amp;amp;zwj;',    -- &amp;lt;ZERO-WIDTH JOINER&amp;gt; HTML escape&lt;br /&gt;
    [0x200E] = '&amp;amp;lrm;',    -- &amp;lt;LEFT TO RIGHT MARK&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0x200F] = '&amp;amp;rlm;',    -- &amp;lt;RIGHT TO LEFT MARK&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0x2028] = '&amp;amp;lsep;',   -- &amp;lt;LINE SEPARATOR&amp;gt; HTML escape&lt;br /&gt;
    [0x2029] = '&amp;amp;psep;',   -- &amp;lt;PARAGRAPH SEPARATOR&amp;gt; HTML escape&lt;br /&gt;
    [0x202A] = '&amp;amp;lre;',    -- &amp;lt;LEFT-TO-RIGHT EMBEDDING&amp;gt; HTML escape, like &amp;lt;bde dir=&amp;quot;ltr&amp;quot;&amp;gt; (deprecated)&lt;br /&gt;
    [0x202B] = '&amp;amp;rle;',    -- &amp;lt;RIGHT-TO-LEFT EMBEDDING&amp;gt; HTML escape, like &amp;lt;bde dir=&amp;quot;rtl&amp;quot;&amp;gt; (deprecated)&lt;br /&gt;
    [0x202C] = '&amp;amp;pdf;',    -- &amp;lt;POP DIRECTIONAL FORMATTING&amp;gt; HTML escape, like &amp;lt;/bde&amp;gt; or &amp;lt;/bdo&amp;gt; (deprecated)&lt;br /&gt;
    [0x202D] = '&amp;amp;lro;',    -- &amp;lt;LEFT-TO-RIGHT OVERRIDE&amp;gt; HTML escape, like &amp;lt;bdo dir=&amp;quot;ltr&amp;quot;&amp;gt; (deprecated)&lt;br /&gt;
    [0x202E] = '&amp;amp;rlo;',    -- &amp;lt;RIGHT-TO-LEFT OVERRIDE&amp;gt; HTML escape, like &amp;lt;bdo dir=&amp;quot;rtl&amp;quot;&amp;gt; (deprecated)&lt;br /&gt;
    [0x202F] = '&amp;amp;nnbsp;',  -- &amp;lt;NARROW NON-BREAKING SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x205F] = '&amp;amp;mathsp;', -- &amp;lt;MATHEMATICAL MEAN SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0x2060] = '&amp;amp;wj;',     -- &amp;lt;WORD JOINER&amp;gt; HTML escape&lt;br /&gt;
    [0x2066] = '&amp;amp;lri;',    -- &amp;lt;LEFT-TO-RIGHT ISOLATE&amp;gt; HTML escape, like &amp;lt;bdi dir=&amp;quot;ltr&amp;quot;&amp;gt; (recommended)&lt;br /&gt;
    [0x2067] = '&amp;amp;rli;',    -- &amp;lt;RIGHT-TO-LEFT ISOLATE&amp;gt; HTML escape, like &amp;lt;bdi dir=&amp;quot;rtl&amp;quot;&amp;gt; (recommended)&lt;br /&gt;
    [0x2068] = '&amp;amp;fsi;',    -- &amp;lt;FIRST STRONG ISOLATE&amp;gt; HTML escape, like &amp;lt;bdi dir=&amp;quot;auto&amp;quot;&amp;gt; or &amp;lt;bdi&amp;gt; (recommended)&lt;br /&gt;
    [0x2069] = '&amp;amp;pdi;',    -- &amp;lt;POP DIRECTIONAL ISOLATE&amp;gt; HTML escape, like &amp;lt;/bdi&amp;gt; (recommended)&lt;br /&gt;
    [0x206A] = '&amp;amp;iss;',    -- &amp;lt;INHIBIT SYMMETRIC SWAPPING&amp;gt; HTML escape&lt;br /&gt;
    [0x206B] = '&amp;amp;ass;',    -- &amp;lt;ACTIVATE SYMMETRIC SWAPPING&amp;gt; HTML escape&lt;br /&gt;
    [0x206C] = '&amp;amp;iafs;',   -- &amp;lt;INHIBIT ARABIC FORM SHAPING&amp;gt; HTML escape&lt;br /&gt;
    [0x206D] = '&amp;amp;aafs;',   -- &amp;lt;ACTIVATE ARABIC FORM SHAPING&amp;gt; HTML escape&lt;br /&gt;
    [0x206E] = '&amp;amp;natds;',  -- &amp;lt;NATIONAL DIGIT SHAPES&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0x206F] = '&amp;amp;nomds;',  -- &amp;lt;NOMINAL DIGIT SHAPES&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0x3000] = '&amp;amp;idsp;',   -- &amp;lt;IDEOGRAPHIC SPACE&amp;gt; HTML escape&lt;br /&gt;
    [0xFEFF] = '&amp;amp;zwnbsp;', -- &amp;lt;ZERO-WIDTH NON-BREAKING SPACE&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0xFFFC] = '&amp;amp;objr;',   -- &amp;lt;OBJECT REPLACEMENT CHARACTER&amp;gt; HTML escape (deprecated)&lt;br /&gt;
    [0xFFFD] = '&amp;amp;repl;',   -- &amp;lt;REPLACEMENT CHARACTER&amp;gt; HTML escape (deprecated)&lt;br /&gt;
}&lt;br /&gt;
-- There's no way to handle multibyte strings in a single gsub(), because Lua patterns do not support alternation with '|'.&lt;br /&gt;
-- Instead we build a character class for fast 1-to-1 substitutions. This only works for single-byte ASCII, not for&lt;br /&gt;
-- substituting multibyte UTF-8. For others, we generate separate gsub() patterns.&lt;br /&gt;
local charsubst, stringmap = {}, {}&lt;br /&gt;
for code, subst in pairs(codemap) do&lt;br /&gt;
   local pattern = toUTF8(code)&lt;br /&gt;
   if #pattern == 1 then&lt;br /&gt;
       charsubst[pattern] = subst&lt;br /&gt;
   else&lt;br /&gt;
       pattern = pattern:gsub('^^', '%%^'):gsub('$$', '%%$'):gsub('[%%()*+%-.?%[]','%%%1') -- magic characters in search patterns&lt;br /&gt;
       subst = subst:gsub('%%', '%%%%') -- magic characters in substitutions&lt;br /&gt;
       insert(stringmap, { pattern, subst })&lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
insert(stringmap, { '&amp;amp;' , '&amp;amp;#38;' }) -- HTML escape (standard)&lt;br /&gt;
insert(stringmap, { '&amp;lt;' , '&amp;amp;#60;' }) -- HTML escape (standard)&lt;br /&gt;
insert(stringmap, { '&amp;gt;' , '&amp;amp;#62;' }) -- HTML escape (standard)&lt;br /&gt;
insert(stringmap, { '^ ' , '&amp;amp;#32;' }) -- Wiki escape (reserved for monospaced line)&lt;br /&gt;
insert(stringmap, { &amp;quot;''&amp;quot; , &amp;quot;'&amp;amp;apos;&amp;quot; }) -- Wiki escape (reserved for italic or bold styles)&lt;br /&gt;
insert(stringmap, { '^!' , '&amp;amp;#33;' }) -- Wiki escape (reserved for table header start)&lt;br /&gt;
insert(stringmap, { '!!' , '!&amp;amp;#33;' }) -- Wiki escape (reserved for table header middle)&lt;br /&gt;
insert(stringmap, { '^#' , '&amp;amp;#35;' }) -- Wiki escape (reserved for item of numbered lists)&lt;br /&gt;
insert(stringmap, { '^%*' , '&amp;amp;#42;' }) -- Wiki escape (reserved for item of bulleted lists)&lt;br /&gt;
insert(stringmap, { ':' , '&amp;amp;#58;' }) -- Wiki escape (reserved for definition item of definition list)&lt;br /&gt;
insert(stringmap, { '^;' , '&amp;amp;#59;' }) -- Wiki escape (reserved for term item of  of definition list)&lt;br /&gt;
insert(stringmap, { '^=' , '&amp;amp;#61;' }) -- Wiki escape (reserved for section headings)&lt;br /&gt;
insert(stringmap, { &amp;quot;%[&amp;quot; , &amp;quot;&amp;amp;#91&amp;quot; }) -- Wiki escape (reserved for external links or wikilinks)&lt;br /&gt;
insert(stringmap, { &amp;quot;%]&amp;quot; , &amp;quot;&amp;amp;#92;&amp;quot; }) -- Wiki escape (reserved for external links or wikilinks)&lt;br /&gt;
insert(stringmap, { &amp;quot;{{&amp;quot; , &amp;quot;{&amp;amp;#123;&amp;quot; }) -- Wiki escape (reserved for transcluding templates, calling parser functions, or replacing a template parameter value)&lt;br /&gt;
insert(stringmap, { &amp;quot;^{|&amp;quot; , &amp;quot;{&amp;amp;#124;&amp;quot; }) -- Wiki escape (reserved for tables)&lt;br /&gt;
insert(stringmap, { &amp;quot;|&amp;quot; , &amp;quot;&amp;amp;#124;&amp;quot; }) -- Wiki escape (reserved between table cells, or parameters of template transclusion or parser functions)&lt;br /&gt;
insert(stringmap, { &amp;quot;}}&amp;quot; , &amp;quot;}&amp;amp;#125;&amp;quot; }) -- Wiki escape (reserved for transcluding templates, calling parser functions, or replacing a template parameter value)&lt;br /&gt;
insert(stringmap, { '~~~' , '~~&amp;amp;#126;' }) -- Wiki escape (reserved for user signatures)&lt;br /&gt;
local function htmlize(wikitext)&lt;br /&gt;
    wikitext = wikitext&lt;br /&gt;
       :gsub('(&amp;amp;[#%w]+;)', function(s)&lt;br /&gt;
               if s:sub(2, 2) == '#' then&lt;br /&gt;
                   if s:sub(3, 3) == 'x' then s = tonumber(s:sub(4,-2), 16) else s = tonumber(s(3,-2), 10) end&lt;br /&gt;
                   if s ~= nil then return toUTF8(s) end&lt;br /&gt;
                   return nil&lt;br /&gt;
               end&lt;br /&gt;
               return nce[s:sub(2,-2)]&lt;br /&gt;
           end)&lt;br /&gt;
       :gsub('.', charsubst)&lt;br /&gt;
    for _, map in ipairs(stringmap) do&lt;br /&gt;
        wikitext = wikitext:gsub(map[1], map[2])&lt;br /&gt;
    end&lt;br /&gt;
    return wikitext&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.test_order()&lt;br /&gt;
    local names = mw.language.fetchLanguageNames()&lt;br /&gt;
    local seen, result = {}, {}&lt;br /&gt;
    insert(result, '&amp;lt;div lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;font-size:smaller;float:right;margin-left:.5em&amp;quot;&amp;gt;&amp;amp;#91;&amp;amp;nbsp;[' .. mw.getCurrentFrame():preprocess('{{FULLURL:{{FULLPAGENAME}}}}') .. '?action=purge Refresh this page]&amp;amp;nbsp;&amp;amp;#93;&amp;lt;/div&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;table lang=&amp;quot;en&amp;quot; dir=&amp;quot;ltr&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-family:\'Noto Sans\',\'Segoe UI\',\'Noto Sans Historic\',\'Segoe UI Historic\',Robo,sans-serif&amp;quot;&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;caption&amp;gt;' ..&lt;br /&gt;
        'Check display order (native names grouped by direction, script, then sorted in locale-neutral UCA order)&amp;lt;br /&amp;gt;' ..&lt;br /&gt;
        '&amp;lt;small&amp;gt;If you see green lines at bottom of this table, these languages added to MediaWiki are missing in the [[Module:Multilingual description/sort|sort order]] (check also their assigned [[Module:Dir/RTL overrides|direction]])&amp;lt;/small&amp;gt;' ..&lt;br /&gt;
        '&amp;lt;/caption&amp;gt;')&lt;br /&gt;
    -- &amp;lt;thead&amp;gt;&lt;br /&gt;
    insert(result, '&amp;lt;tr&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;#&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Code&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Valid&amp;lt;br /&amp;gt;Code,&amp;lt;br /&amp;gt; Valid&amp;lt;br /&amp;gt;BuiltInCode?')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Known&amp;lt;br /&amp;gt;Language&amp;lt;br /&amp;gt;Tag?&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;MediaWiki&amp;lt;br /&amp;gt; support&amp;lt;br/&amp;gt; &amp;lt;small&amp;gt;(known by &amp;lt;code&amp;gt;&amp;amp;#123;{#language:}&amp;amp;#125;&amp;lt;/code&amp;gt;)&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Supports&amp;lt;br /&amp;gt; full&amp;lt;br /&amp;gt; localisation?&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Direction, &amp;lt;br /&amp;gt; Sorting&amp;lt;br /&amp;gt; initial&amp;lt;br/&amp;gt; &amp;lt;small&amp;gt;(uppercased)&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Native name&amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(lowercase initial is often preferred)&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;Known fallbacks&amp;lt;br/&amp;gt; &amp;lt;small&amp;gt;(on this wiki)&amp;lt;/small&amp;gt;&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;English name (HTML-encoded)&amp;lt;br /&amp;gt; &amp;lt;ul style=&amp;quot;text-align:left;font-size:smaller&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Yellow: same as native?&amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(not necessarily wrong)&amp;lt;/small&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Red: non-Basic Latin, incorrect encoding or missing data&amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(report bug in MediaWiki #language)&amp;lt;/small&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&amp;lt;/th&amp;gt;')&lt;br /&gt;
    insert(result, '&amp;lt;/tr&amp;gt;')&lt;br /&gt;
    -- &amp;lt;/thead&amp;gt;&lt;br /&gt;
    -- &amp;lt;tbody&amp;gt;&lt;br /&gt;
    local rank = 0&lt;br /&gt;
    for _,lang in pairs(langs) do&lt;br /&gt;
        if type(lang) == 'string' then&lt;br /&gt;
            rank = rank + 1&lt;br /&gt;
            local status = 'OK'&lt;br /&gt;
			local valid = mw.language.isValidCode(lang)&lt;br /&gt;
			local validBuiltIn = mw.language.isValidBuiltInCode(lang)&lt;br /&gt;
            local known = mw.language.isKnownLanguageTag(lang)&lt;br /&gt;
            local supported = mw.language.isSupportedLanguage(lang)&lt;br /&gt;
            local enname = mw.language.fetchLanguageName(lang, 'en')&lt;br /&gt;
            local duplicate = seen[lang]&lt;br /&gt;
            if duplicate ~= nil then&lt;br /&gt;
                status = 'Duplicate code'&lt;br /&gt;
            else&lt;br /&gt;
                nativename, names[lang] = names[lang], nil&lt;br /&gt;
                if nativename == nil then&lt;br /&gt;
                    status = '&amp;lt;b&amp;gt;Unknown code&amp;lt;/b&amp;gt;'&lt;br /&gt;
                    nativename = mw.language.fetchLanguageName(lang)&lt;br /&gt;
                    seen[lang] = nativename&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            local nativedir = dir.select(lang, 'rtl', 'ltr')&lt;br /&gt;
            local initial = mw.ustring.sub(mw.ustring.upper(mw.ustring.lower(nativename)), 1, 1)&lt;br /&gt;
            --&lt;br /&gt;
            insert(result, '&amp;lt;tr style=&amp;quot;background:#' .. (supported and 'FFF' or known and 'FFC' or 'FCC') .. ';color:#000&amp;quot;&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;th scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:right&amp;quot;&amp;gt;' .. rank .. '&amp;lt;/th&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;' .. lang .. '&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (valid and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') ..&lt;br /&gt;
                ', ' .. (validBuiltIn and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (known and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (supported and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;' .. status .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. nativedir .. ', ' .. initial .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td dir=&amp;quot;' .. nativedir .. '&amp;quot;&amp;gt;' .. nativename .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;' .. table.concat(mw.language.getFallbacksFor(lang), ', ') .. '&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;background:#' ..&lt;br /&gt;
                ((nativename == enname and (enname:find(&amp;quot;^[A-Z][ '()%-/0-9A-Za-z]*['()%-/0-9A-Za-z]$&amp;quot;) and 'FFC' or 'FCC')&lt;br /&gt;
                ) or 'FFF') .. ';color:000&amp;quot;&amp;gt;' .. htmlize(enname) .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;/tr&amp;gt;')&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    -- Other languages not seen&lt;br /&gt;
    langs = {}&lt;br /&gt;
    for lang, _ in pairs(names) do&lt;br /&gt;
        insert(langs, lang)&lt;br /&gt;
    end&lt;br /&gt;
    table.sort(langs, function(lang1, lang2)&lt;br /&gt;
        return names[lang1] &amp;lt; names[lang2]&lt;br /&gt;
    end)&lt;br /&gt;
    for _, lang in pairs(langs) do&lt;br /&gt;
        if type(lang) == 'string' then&lt;br /&gt;
            rank = rank + 1&lt;br /&gt;
            local status = '&amp;lt;b&amp;gt;Missing code (still not sorted)&amp;lt;/b&amp;gt;'&lt;br /&gt;
			local valid = mw.language.isValidCode(lang)&lt;br /&gt;
			local validBuiltIn = mw.language.isValidBuiltInCode(lang)&lt;br /&gt;
            local known = mw.language.isKnownLanguageTag(lang)&lt;br /&gt;
            local supported = mw.language.isSupportedLanguage(lang)&lt;br /&gt;
            local enname = mw.language.fetchLanguageName(lang, 'en')&lt;br /&gt;
            local nativename = names[lang]&lt;br /&gt;
            local nativedir = dir.select(lang, 'rtl', 'ltr')&lt;br /&gt;
            local initial = mw.ustring.sub(mw.ustring.upper(mw.ustring.lower(nativename)), 1, 1)&lt;br /&gt;
            --&lt;br /&gt;
            insert(result, '&amp;lt;tr style=&amp;quot;background:#' .. (supported and '0F0' or known and 'FFC' or 'FCC') .. ';color:#000&amp;quot;&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;th scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:right&amp;quot;&amp;gt;' .. rank .. '&amp;lt;/th&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;' .. lang .. '&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (valid and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') ..&lt;br /&gt;
                ', ' .. (validBuiltIn and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (known and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. (supported and 'Yes' or '&amp;lt;b&amp;gt;No&amp;lt;/b&amp;gt;') .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;' .. status .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;text-align:center&amp;quot;&amp;gt;' .. nativedir .. ', ' .. initial .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td dir=&amp;quot;' .. nativedir .. '&amp;quot;&amp;gt;' .. nativename .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td&amp;gt;&amp;lt;code&amp;gt;' .. table.concat(mw.language.getFallbacksFor(lang), ', ') .. '&amp;lt;/code&amp;gt;&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;td style=&amp;quot;background:#' ..&lt;br /&gt;
                ((nativename == enname and (enname:find(&amp;quot;^[A-Z][ '()%-/0-9A-Za-z]*['()%-/0-9A-Za-z]$&amp;quot;) and 'FFC' or 'FCC')&lt;br /&gt;
                ) or 'FFF') .. ';color:#000&amp;quot;&amp;gt;' .. htmlize(enname) .. '&amp;lt;/td&amp;gt;')&lt;br /&gt;
            insert(result, '&amp;lt;/tr&amp;gt;')&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    -- &amp;lt;/tbody&amp;gt;&lt;br /&gt;
    insert(result, '&amp;lt;/table&amp;gt;')&lt;br /&gt;
    return table.concat(result)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Tricky test functions, needed during search of solutions for the severly limited methods of MediaWiki &amp;quot;frame&amp;quot; objects&lt;br /&gt;
-- that now no longer not support any kind of expansion for MediaWiki special tags (except &amp;quot;nowiki&amp;quot; tags).&lt;br /&gt;
-- May be we'll have some Lua extension library for supporting some special tags (such libraries exist now for Wikidata, and for &amp;quot;#expr&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
local function show(title, text)&lt;br /&gt;
    return '&amp;lt;b&amp;gt;' .. title .. ':&amp;lt;/b&amp;gt; &amp;quot;&amp;lt;tt&amp;gt;' .. htmlize(text) .. '&amp;lt;/tt&amp;gt;&amp;quot;'&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.test_prefix(...)&lt;br /&gt;
    local args = { ... }&lt;br /&gt;
    local frame&lt;br /&gt;
    if type(args[1]) == 'table' and type(args[1].args) == 'table' and type(args[1].getParent) == 'function' then&lt;br /&gt;
        frame = args[1]&lt;br /&gt;
        local pframe = frame:getParent() or frame&lt;br /&gt;
        local args = frame.args or pframe.args or {}&lt;br /&gt;
    else&lt;br /&gt;
       frame = mw.getCurrentFrame()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local text = args.text or ''&lt;br /&gt;
&lt;br /&gt;
    local preprocessed = frame:preprocess(text)&lt;br /&gt;
    local expanded = mw.text.unstrip(preprocessed)&lt;br /&gt;
&lt;br /&gt;
    return show('text', text) .. ',&amp;lt;br /&amp;gt; '&lt;br /&gt;
        .. show('preprocessed', preprocessed) .. ',&amp;lt;br /&amp;gt; '&lt;br /&gt;
        .. show('expanded', expanded) .. '.'&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--p.test_tag(frame) -- {{#invoke:...|test_tag|1=tag|2=content|option1=value1|option2=value2...}}&lt;br /&gt;
--p.test_tag('tag','content')&lt;br /&gt;
--p.test_tag{'tag','content'}&lt;br /&gt;
--p.test_tag('tag', nil,      { option1 = &amp;quot;value1&amp;quot;, option2 = &amp;quot;value2&amp;quot;... })&lt;br /&gt;
--p.test_tag('tag','content', { option1 = &amp;quot;value1&amp;quot;, option2 = &amp;quot;value2&amp;quot;... })&lt;br /&gt;
--p.test_tag{'tag',             option1 = &amp;quot;value1&amp;quot;, option2 = &amp;quot;value2&amp;quot;... }&lt;br /&gt;
--p.test_tag{'tag','content',   option1 = &amp;quot;value1&amp;quot;, option2 = &amp;quot;value2&amp;quot;... }&lt;br /&gt;
function p.test_tag(...)&lt;br /&gt;
    local args = { ... }&lt;br /&gt;
    local frame&lt;br /&gt;
    if type(args[1]) == 'table' and type(args[1].args) == 'table' and type(args[1].getParent) == 'function' then&lt;br /&gt;
        frame = args[1]&lt;br /&gt;
        local pframe = frame:getParent() or frame&lt;br /&gt;
        local args = frame.args or pframe.args or {}&lt;br /&gt;
    else&lt;br /&gt;
       frame = mw.getCurrentFrame()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local tag, content = args[1] or '', args[2] or ''&lt;br /&gt;
    if type(tag) == 'table' then&lt;br /&gt;
        args = tag&lt;br /&gt;
        tag, content = args[1] or '', args[2] or ''&lt;br /&gt;
        table.remove(args, 2)&lt;br /&gt;
        table.remove(args, 1)&lt;br /&gt;
    elseif type(args[3]) == 'table' then&lt;br /&gt;
        args = args[3]&lt;br /&gt;
    else&lt;br /&gt;
        table.remove(args, 2)&lt;br /&gt;
        table.remove(args, 1)&lt;br /&gt;
    end&lt;br /&gt;
    local text = '{{#tag:' .. tag .. '|' .. content&lt;br /&gt;
    for k, v in pairs(args) do&lt;br /&gt;
	    if type(v) == 'string' or type(v) == 'number' then&lt;br /&gt;
            text = text .. '|' .. k .. '=' .. v&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    text = text .. '}}'&lt;br /&gt;
&lt;br /&gt;
    local preprocessed = frame:extensionTag{name=tag, content=content, args=args}&lt;br /&gt;
    local expanded = mw.text.unstrip(preprocessed)&lt;br /&gt;
&lt;br /&gt;
    return show('text', text) .. ',&amp;lt;br /&amp;gt; '&lt;br /&gt;
        .. show('preprocessed', preprocessed) .. ',&amp;lt;br /&amp;gt; '&lt;br /&gt;
        .. show('expanded', expanded) .. '.'&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Kg7qin</name></author>
	</entry>
</feed>