Module:typing-aids: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
fix previous errors
in Gothic, preserve translit if it has a macron in it that will survive canonicalization
Line 36: Line 36:


local acute = U(0x0301)
local acute = U(0x0301)
local macron = U(0x0304)


local function clone_args(frame)
local function clone_args(frame)
Line 232: Line 233:
-- accent when the Devanagari doesn't.
-- accent when the Devanagari doesn't.
if lang == "sa" then
if lang == "sa" then
content = decompose(content, lang)
local proposed_trcontent = interpretShortcuts(content, "sa-tr")
if find(content, "/") or find(content, acute) then
if find(proposed_trcontent, acute) then
trcontent = interpretShortcuts(content, "sa-tr")
trcontent = proposed_trcontent
end
end
-- If Gothic and there's a macron specified somehow or other
-- in the source content that remains after canonicalization, preserve
-- the translit, which includes the accent when the Gothic doesn't.
if lang == "got" then
local proposed_trcontent = interpretShortcuts(content, "got-tr")
if find(proposed_trcontent, macron) then
trcontent = proposed_trcontent
end
end
end
end

Revision as of 23:35, 22 April 2017

This module is invoked by {{chars}} (and {{chars/example}}). It replaces ASCII keyboard shortcuts with characters used in various languages.

To edit the list of shortcuts, see Module:typing-aids/data.

Testcases

22 of 114 tests failed. (refresh)

TextExpectedActual
test_Akkadian:
Script error during testing: Module:typing-aids:136: The language code "akk" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:115: in function <Module:typing-aids/testcases:110>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Arabic:
Passedal-Huruuf al-qamariyyat'الْحُرُوف الْقَمَرِيَّةالْحُرُوف الْقَمَرِيَّة
Passedal-Huruuf al-xamsiyyat'الْحُرُوف الشَّمْسِيَّةالْحُرُوف الشَّمْسِيَّة
Passedealifu WlwaSliأَلِفُ ٱلْوَصْلِأَلِفُ ٱلْوَصْلِ
Passedmaaeمَاءمَاء
Passedmueminمُؤْمِنمُؤْمِن
PassedeiDaafat'إِضَافَةإِضَافَة
Passedeaabآبآب
Passedqureaanقُرْآنقُرْآن
PassedqiTTat'قِطَّةقِطَّة
PassedfaEEaalفَعَّالفَعَّال
Passedxayeuشَيْءُشَيْءُ
PassedxayeaNشَيْءًشَيْءً
PasseddaaeimaNدَائِمًادَائِمًا
Passedmabduueat'مَبْدُوءَةمَبْدُوءَة
Passedmabduu'at'مَبْدُوءَةمَبْدُوءَة
PassedbadaaeiyyuNبَدَائِيٌّبَدَائِيٌّ
Passedbadaaeat'بَدَاءَةبَدَاءَة
Passedmaktuubمَكْتُوبمَكْتُوب
PassedtaHriirتَحْرِيرتَحْرِير
PassedEuZmaaaعُظْمَىعُظْمَى
Passedean0أَنْأَنْ
Passedlaw0لَوْلَوْ
Passedxay'aNشَيْءًشَيْءً
Passedta7riirتَحْرِيرتَحْرِير
Passed3axarat'عَشَرَةعَشَرَة
TextExpectedActual
test_Armenian:
Script error during testing: Module:typing-aids:136: The language code "hy" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:63: in function 'do_tests'
	Module:typing-aids/testcases:126: in function <Module:typing-aids/testcases:125>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Armenian_tr:
Script error during testing: Module:typing-aids:136: The language code "hy-tr" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:130: in function <Module:typing-aids/testcases:129>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Avestan:
Passedap𐬀𐬞𐬀𐬞
Passedxs.^uuas^𐬑𐬴𐬎𐬎𐬀𐬱𐬑𐬴𐬎𐬎𐬀𐬱
Passedxṣ̌uuaš𐬑𐬴𐬎𐬎𐬀𐬱𐬑𐬴𐬎𐬎𐬀𐬱
Passedv@hrka_na𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀
Passedvəhrkāna𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀
Passednae_za𐬥𐬀𐬉𐬰𐬀𐬥𐬀𐬉𐬰𐬀
Passednaēza𐬥𐬀𐬉𐬰𐬀𐬥𐬀𐬉𐬰𐬀
FailedzaaO𐬰𐬃𐬰ā̊
Passedzā̊𐬰𐬃𐬰𐬃
FailedhizwaO𐬵𐬌𐬰𐬎𐬎𐬂𐬵𐬌𐬰𐬎𐬎å
Passedhizuuå𐬵𐬌𐬰𐬎𐬎𐬂𐬵𐬌𐬰𐬎𐬎𐬂
TextExpectedActual
test_Avestan_tr:
Passedapapap
Passedxs.^uuas^xṣ̌uuašxṣ̌uuaš
Passedv@hrka_navəhrkānavəhrkāna
Passednae_zanaēzanaēza
PassedzaaOzā̊zā̊
PassedhizwaOhizuuåhizuuå
TextExpectedActual
test_Germanic:
Passed*t'a_ko^`*þākǫ̂*þākǫ̂
Passed*T'eudo_balt'az*Þeudōbalþaz*Þeudōbalþaz
Passed*bo_kijo_`*bōkijǭ*bōkijǭ
TextExpectedActual
test_Gothic:
Passedƕaiwa𐍈𐌰𐌹𐍅𐌰𐍈𐌰𐌹𐍅𐌰
Passedanþar𐌰𐌽𐌸𐌰𐍂𐌰𐌽𐌸𐌰𐍂
Passedfidwōr𐍆𐌹𐌳𐍅𐍉𐍂𐍆𐌹𐌳𐍅𐍉𐍂
Passedfidwor𐍆𐌹𐌳𐍅𐍉𐍂𐍆𐌹𐌳𐍅𐍉𐍂
Passedmikils𐌼𐌹𐌺𐌹𐌻𐍃𐌼𐌹𐌺𐌹𐌻𐍃
Passedhēr𐌷𐌴𐍂𐌷𐌴𐍂
Passedher𐌷𐌴𐍂𐌷𐌴𐍂
Passedvac𐍈𐌰𐌸𐍈𐌰𐌸
TextExpectedActual
test_Greek:
Passeda__iᾱͅᾱͅ
Passeda)lhqh/sἀληθήςἀληθής
Passeda)lhqhs*ἀληθησἀληθησ
Passeda)lhqhs-ἀληθησ-ἀληθησ-
Passeda^)nh/rᾰ̓νήρᾰ̓νήρ
PassedPhlhi+a/dhsΠηληϊάδηςΠηληϊάδης
PassedPhlhi^+a^/dhsΠηληῐ̈ᾰ́δηςΠηληῐ̈ᾰ́δης
PassedΠηληϊ^ά^δηςΠηληῐ̈ᾰ́δηςΠηληῐ̈ᾰ́δης
Passede)a_/nἐᾱ́νἐᾱ́ν
Passedἐά_νἐᾱ́νἐᾱ́ν
Passedpa=sa^πᾶσᾰπᾶσᾰ
Passedu_(mei=sῡ̔μεῖςῡ̔μεῖς
Passeda/)^nerᾰ̓́νερᾰ̓́νερ
Passeda/^)nerᾰ̓́νερᾰ̓́νερ
Passeda)/^nerᾰ̓́νερᾰ̓́νερ
Passeda)^/nerᾰ̓́νερᾰ̓́νερ
Passeddai+/frwnδαΐφρωνδαΐφρων
Passeddai/+frwnδαΐφρωνδαΐφρων
TextExpectedActual
test_Hellenic:
Passed*tat^t^o_*taťťō*taťťō
Passed*d^o_'yyon*ďṓyyon*ďṓyyon
Passed*gw@n'n'o_*gʷəňňō*gʷəňňō
Passed*gw@n^n^o_*gʷəňňō*gʷəňňō
Passed*kwhe_r*kʷʰēr*kʷʰēr
Passed*khwe_r*kʷʰēr*kʷʰēr
TextExpectedActual
test_Hittite:
Passeda-ku𒀀𒆪𒀀𒆪
Passedan-tu-wa-ah-ha-as𒀭𒌅𒉿𒄴𒄩𒀸𒀭𒌅𒉿𒄴𒄩𒀸
Passedan-tu-wa-aḫ-ḫa-aš𒀭𒌅𒉿𒄴𒄩𒀸𒀭𒌅𒉿𒄴𒄩𒀸
FailedDINGIRIŠKUR𒀭𒅎<šup>DINGIR</šup>IŠKUR
TextExpectedActual
test_Imperial_Aramaic:
Script error during testing: Module:typing-aids:136: The language code "arc" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:439: in function <Module:typing-aids/testcases:434>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Japanese:
Script error during testing: Module:typing-aids:136: The language code "ja" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:367: in function <Module:typing-aids/testcases:351>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Kannada:
Script error during testing: Module:typing-aids:136: The language code "kn" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:275: in function <Module:typing-aids/testcases:264>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Maithili:
Script error during testing: Module:typing-aids:136: The language code "mai" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:310: in function <Module:typing-aids/testcases:300>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Marwari:
Script error during testing: Module:typing-aids:136: The language code "mwr" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:323: in function <Module:typing-aids/testcases:313>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Old_Church_Slavonic:
Script error during testing: Module:typing-aids:136: The language code "cu" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:379: in function <Module:typing-aids/testcases:370>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Old_Marathi:
Script error during testing: Module:typing-aids:136: The language code "omr" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:63: in function 'do_tests'
	Module:typing-aids/testcases:415: in function <Module:typing-aids/testcases:414>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Old_Marathi_tr:
Script error during testing: Module:typing-aids:136: The language code "omr-tr" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:419: in function <Module:typing-aids/testcases:418>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Old_Persian:
Script error during testing: Module:typing-aids:136: The language code "peo" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:336: in function <Module:typing-aids/testcases:326>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Old_South_Arabian:
Script error during testing: Module:typing-aids:136: The language code "xsa" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:447: in function <Module:typing-aids/testcases:442>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Ossetian:
Script error during testing: Module:typing-aids:136: The language code "os" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:431: in function <Module:typing-aids/testcases:422>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_PIE:
Passed*dye_'ws*dyḗws*dyḗws
Passed*n0mr0to's*n̥mr̥tós*n̥mr̥tós
Passed*tk'e'yti*tḱéyti*tḱéyti
Passed*h1es-*h₁es-*h₁es-
Passed*t_ep-e'h1(ye)-ti*tₔp-éh₁(ye)-ti*tₔp-éh₁(ye)-ti
Passed*h1e'k'wos*h₁éḱwos*h₁éḱwos
Passed*bhebho'ydhe*bʰebʰóydʰe*bʰebʰóydʰe
Passed*dh3to's*dh₃tós*dh₃tós
Passed*dhewg'h-*dʰewǵʰ-*dʰewǵʰ-
TextExpectedActual
test_Parthian:
Script error during testing: Module:typing-aids:136: The language code "xpr" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:348: in function <Module:typing-aids/testcases:339>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Persian:
Script error during testing: Module:typing-aids:136: The language code "fa" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:170: in function <Module:typing-aids/testcases:165>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Sanskrit:
Script error during testing: Module:typing-aids:100: attempt to concatenate field '?' (a nil value)
stack traceback:
	[C]: ?
	Module:typing-aids:100: in function '_replace'
	Module:typing-aids:158: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:63: in function 'do_tests'
	Module:typing-aids/testcases:293: in function <Module:typing-aids/testcases:292>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Sanskrit_tr:
PassedsaMskRta/saṃskṛtásaṃskṛtá
PassedkSatri/yakṣatríyakṣatríya
PassedrAja suprabuddharāja suprabuddharāja suprabuddha
PassedzAkyamuniśākyamuniśākyamuni
PassedsiMhasiṃhasiṃha
PassednAmannāmannāman
PassedanA/anā́anā́
PassedayuSmAnayuṣmānayuṣmān
Passedghatsyatighatsyatighatsyati
PassedtApa-itāpa-itāpa-i
PassedtApaïtāpaïtāpaï
TextExpectedActual
test_Saurashtra:
Script error during testing: Module:typing-aids:136: The language code "saz" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:459: in function <Module:typing-aids/testcases:450>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_Sindhi:
Script error during testing: Module:typing-aids:136: The language code "sd" does not have a set of replacements in Module:typing-aids/data or its submodules.
stack traceback:
	[C]: ?
	[C]: in function 'error'
	Module:typing-aids:136: in function 'interpretShortcuts'
	Module:typing-aids:355: in function 'replace'
	Module:typing-aids/testcases:37: in function 'check_output'
	Module:typing-aids/testcases:68: in function 'do_tests'
	Module:typing-aids/testcases:479: in function <Module:typing-aids/testcases:462>
	(tail call): ?
	[C]: in function 'xpcall'
	Module:UnitTests:369: in function <Module:UnitTests:328>
	(tail call): ?
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
	[C]: in function 'expandTemplate'
	mw.lua:333: in function 'expandTemplate'
	Module:documentation:864: in function 'chunk'
	mw.lua:527: in function <mw.lua:507>
	[C]: ?
TextExpectedActual
test_all:
Passed*dye_'ws*dyḗws*dyḗws
Passed*n0mr0to's*n̥mr̥tós*n̥mr̥tós
Passed*tk'e'yti*tḱéyti*tḱéyti
Passed*h1es-*h₁es-*h₁es-
Passed*t_ep-e'h1(ye)-ti*tₔp-éh₁(ye)-ti*tₔp-éh₁(ye)-ti
Passed*h1e'k'wos*h₁éḱwos*h₁éḱwos
Passed*bhebho'ydhe*bʰebʰóydʰe*bʰebʰóydʰe
Passed*dh3to's*dh₃tós*dh₃tós
Passed*t'a_ko^`*þākǫ̂*þākǫ̂
Passed*T'eudo_balt'az*Þeudōbalþaz*Þeudōbalþaz
Passed*bo_kijo_`*bōkijǭ*bōkijǭ
Passed*tat^t^o_*taťťō*taťťō
Passed*d^o_'yyon*ďṓyyon*ďṓyyon

local export = {}

local reorderDiacritics = require("Module:grc-utilities").reorderDiacritics
local formatLink = require("Module:template link").format_link
local m_data = mw.loadData("Module:typing-aids/data")
local m_data_ae = mw.loadData("Module:typing-aids/data/ae")
local m_data_ar = mw.loadData("Module:typing-aids/data/ar")
local m_data_grc = mw.loadData("Module:typing-aids/data/grc")
local m_data_hit = mw.loadData("Module:typing-aids/data/hit")
local m_data_sa = mw.loadData("Module:typing-aids/data/sa")
local m_data_got = mw.loadData("Module:typing-aids/data/got")

--[=[	The first string is the subpage of [[Module:typing-aids/data]] that contains the language's replacements;
		the second is the index in the exported table of that module that contains
		the language's replacements.								]=]
data_modules = {
	["ae"] = { "ae", "ae", },
	["ar"] = { "ar" },
	["ae-tr"] = { "ae", "ae-tr", },
	["hit"] = { "hit", "hit" },
	["hit-tr"] = { "hit", "hit-tr" },
	["sa"] = { "sa", "sa" },
	["sa-tr"] = { "sa", "sa-tr" },
	["got"] = { "got", "got" },
	["got-tr"] = { "got", "got-tr" },
	["grc"] = { "grc" },
--	[""] = { "" },
}

local U = mw.ustring.char
local gsub = mw.ustring.gsub
local find = mw.ustring.find
local match = mw.ustring.match
local gmatch = mw.ustring.gmatch
local sub = mw.ustring.sub

local acute = U(0x0301)
local macron = U(0x0304)

local function clone_args(frame)
	local args = frame.getParent and frame:getParent().args or frame
	local newargs = {}
	for k, v in pairs(args) do
		if v == "" then v = nil end
		if v then
			newargs[k] = v
		end
	end
	return newargs
end
			
local function tag(text, lang)
	if  lang and not find(lang, "%-tr$") then
		return '<span lang="' .. lang .. '">' .. text .. '</span>'
	else
		return text
	end
end

local acute_decomposer = {
	["á"] = "a" .. acute,
	["é"] = "e" .. acute,
	["í"] = "i" .. acute,
	["ó"] = "o" .. acute,
	["ú"] = "u" .. acute,
	["ý"] = "y" .. acute,
	["ḗ"] = "ē" .. acute,
	["ṓ"] = "ō" .. acute,
	["Á"] = "A" .. acute,
	["É"] = "E" .. acute,
	["Í"] = "I" .. acute,
	["Ó"] = "O" .. acute,
	["Ú"] = "U" .. acute,
	["Ý"] = "Y" .. acute,
	["Ḗ"] = "Ē" .. acute,
	["Ṓ"] = "Ō" .. acute,
}

-- decompose Latin text into sequences of letter and combining accent, either
-- partly or completely depending on the language.
local function decompose(text, lang)
	if lang == "sa" then
		text = gsub(text, ".", acute_decomposer)
	else
		text = mw.ustring.toNFD(text)
	end
	return text
end

local function _replace(text, replacements)
	for shortcut, symbol in pairs(replacements) do
		if type(symbol) == "table" then
			local before =
				symbol.before and { "("..symbol.before..")", "%1" }
				or { "", "" }
			local after =
				symbol.after and { "("..symbol.after..")", symbol.before and  "%2" or "%1" }
				or { "", "" }
			
			text = gsub(text, before[1]..shortcut..after[1], before[2]..symbol[1]..after[2])
		elseif type(symbol) == "string" then
			text = gsub(text, shortcut, symbol)
		end
	end
	text = mw.text.trim(text)
	return text
end

local function interpretShortcuts(text, lang)
	if not text or type(text) ~= "string" then
		return nil
	end
	
	local module_name = data_modules[lang]
	local data_module
	if module_name then
		data_module = mw.loadData("Module:typing-aids/data/" .. module_name[1])
	else
		data_module = mw.loadData("Module:typing-aids/data")
	end
	
	local replacements
	if not module_name then
		if lang then
			replacements = data_module[lang]
		else
			replacements = data_module.all
		end
	elseif module_name[2] then
		replacements = data_module[module_name[2]]
	else
		replacements = data_module
	end
	
	if not replacements then
		error("The language code \"" .. tostring(lang) .. "\" does not have a set of replacements in Module:typing-aids/data or its submodules.")
	end

	text = decompose(text, lang)
	
	if lang == "ae" or lang == "sa" or lang == "got" then
		local transliterationTable
		if lang == "sa" then
			transliterationTable = m_data_sa["sa-tr"]
		elseif lang == "ae" then
			transliterationTable = m_data_ae["ae-tr"]
		elseif lang == "got" then
			transliterationTable = m_data_got["got-tr"]
		end
		
		for ordering, table in ipairs(transliterationTable) do
			for symbol, symbolWithDiacritic in pairs(table) do
				text = gsub(text, symbol, symbolWithDiacritic)
			end
		end
		
		for i, replacementsTable in ipairs(replacements) do
			text = _replace(text, replacementsTable)
		end
	else
		if replacements[1] then
			for i, replacementsTable in ipairs(replacements) do
				text = _replace(text, replacementsTable)
			end
		else
			text = _replace(text, replacements)
		end
		
		if lang == "grc" then
			text = reorderDiacritics(text)
		end
	end
	
	return text
end

local function intoHittite(text)
	local replacements = m_data_hit["hit"]
	
	for k, v in pairs(replacements.pre) do
		text = gsub(text, k, v)
	end
	
	local output = {}
	-- Find groups of characters that aren't hyphens or whitespace.
	for symbol in text:gmatch("([^%-%s]+)") do
		table.insert(output, replacements[symbol] or symbol)
	end
	
	return table.concat(output)
end

local function addParameter(list, args, key, content)
	if not content then content = args[key] end
	args[key] = nil
	if not content then return false end

	if find(content, "=") or type(key) == "string" then
		table.insert(list, key .. "=" .. content)
	else
		while list.maxarg < key - 1 do
			table.insert(list, "")
			list.maxarg = list.maxarg + 1
		end
		table.insert(list, content)
		list.maxarg = key
	end
	return true
end

local function addAndConvertParameter(list, args, key, altkey1, altkey2, trkey, lang)
	if altkey1 and args[altkey1] then
		addAndConvertParameter(list, args, key, nil, nil, nil, lang)
		key = altkey1
	elseif altkey2 and args[altkey2] then
		addAndConvertParameter(list, args, key, nil, nil, nil, lang)
		key = altkey2
	end
	local content = args[key]
	if trkey and args[trkey] then
		if not content then
			content = args[trkey]
			args[trkey] = nil
		else
			error("Can't specify manual translit " .. trkey .. "=" ..
				args[trkey] .. " along with parameter " .. key .. "=" .. content)
		end
	end
	if not content then return false end
	local trcontent = nil
	-- If Sanskrit and there's an acute accent specified somehow or other
	-- in the source content, preserve the translit, which includes the
	-- accent when the Devanagari doesn't.
	if lang == "sa" then
		local proposed_trcontent = interpretShortcuts(content, "sa-tr")
		if find(proposed_trcontent, acute) then
			trcontent = proposed_trcontent
		end
	end
	-- If Gothic and there's a macron specified somehow or other
	-- in the source content that remains after canonicalization, preserve
	-- the translit, which includes the accent when the Gothic doesn't.
	if lang == "got" then
		local proposed_trcontent = interpretShortcuts(content, "got-tr")
		if find(proposed_trcontent, macron) then
			trcontent = proposed_trcontent
		end
	end
	content = interpretShortcuts(content, lang)
	addParameter(list, args, key, content)
	if trcontent then
		addParameter(list, args, trkey, trcontent)
	end
	return true
end

local isCompound = {}
for _, templateName in pairs{ "affix", "suffix", "prefix" } do
	isCompound[templateName] = true
end
local isLinkTemplate = {}
for _, templateName in pairs{ "m", "l", "ll", "cog", "noncog", "cognate", "ncog", "m-self", "l-self", "desc" } do
	isLinkTemplate[templateName] = true
end
local isTwoLangLinkTemplate = {}
for _, templateName in pairs{ "der", "inh", "bor" } do
	isTwoLangLinkTemplate[templateName] = true
end
local isTransTemplate = {}
for _, templateName in pairs{ "t", "t+", "t-check", "t+check" } do
	isTransTemplate[templateName] = true
end

local function printTemplate(args)
	local parameters = {}
	for key, value in pairs(args) do
		parameters[key] = value
	end
	
	local template = parameters[1]
	
	local result = { }
	local lang = nil
	result.maxarg = 0
	
	addParameter(result, parameters, 1)
	lang = parameters[2]
	addParameter(result, parameters, 2)
	if isLinkTemplate[template] then
		addAndConvertParameter(result, parameters, 3, "alt", 4, "tr", lang)
		for _, param in ipairs({ 5, "gloss", "t" }) do
			addParameter(result, parameters, param)
		end
	elseif isTwoLangLinkTemplate[template] then
		lang = parameters[3]
		addParameter(result, parameters, 3)
		addAndConvertParameter(result, parameters, 4, "alt", 5, "tr", lang)
		for _, param in ipairs({ 6, "gloss", "t" }) do
			addParameter(result, parameters, param)
		end
	elseif isTransTemplate[template] then
		addAndConvertParameter(result, parameters, 3, "alt", nil, "tr", lang)
		local i = 4
		while true do
			if not parameters[i] then
				break
			end
			addParameter(result, parameters, i)
		end
	elseif isCompound[template] then
		local i = 1
		while true do
			local sawparam = addAndConvertParameter(result, parameters, i + 2, "alt" .. i, nil, "tr" .. i, lang)
			if not sawparam then
				break
			end
			for _, param in ipairs({ "id", "lang", "sc", "t", "pos", "lit" }) do
				addParameter(result, parameters, param .. i)
			end
			i = i + 1
		end
	else
		error("Unrecognized template name '" .. template .. "'")
	end
	-- Copy any remaining parameters
	for k, v in pairs(parameters) do
		addParameter(result, parameters, k)
	end
	return "{{" .. table.concat(result, "|") .. "}}"
end

function export.link(frame)
	local args = frame.args or frame
	
	return printTemplate(args)
end

function export.replace(frame)
	local args = clone_args(frame)
	local text, lang
	
	if args[3] or args.tr then
		return printTemplate(args)
	else
		if args[2] then
			lang, text = args[1], args[2]
		else
			lang, text = "all", args[1]
		end
	end
	
	if lang == "hit" then
		return intoHittite(text)
	else
		text = interpretShortcuts(text, lang)
	end
	
	return text or ""
end

function export.example(frame)
	local args = clone_args(frame)
	
	local text, lang
	
	if args[2] then
		lang, text = args[1], args[2]
	else
		lang, text = "all", args[1]
	end
	
	local textparam
	if find(text, "=") then
		textparam = "2="..text -- Currently, "=" is only used in the shortcuts for Greek, and Greek is always found in the second parameter, since the first parameter specify the language, "grc".
	else
		textparam = text
	end
	
	local template = {
		[1] = "subst:chars",
		[2] = lang ~= "all" and lang or textparam,
		[3] = lang ~= "all" and textparam or nil,
	}
	
	local output = { formatLink(template) }
	table.insert(output, "\n| ")
	table.insert(output, lang ~= "all" and "<span lang=\""..lang.."\">" or "")
	table.insert(output, export.replace({lang, text}))
	table.insert(output, lang ~= "all" and "</span>" or "")
	
	return table.concat(output)
end

function export.examples(frame)
	local args = frame.getParent and frame:getParent().args or frame.args[1] and frame.args or frame
	
	local examples = args[1] and mw.text.split(args[1], ";%s+") or error('No content in the first parameter.')
	local lang = args["lang"]
	
	local output = {
[[
{| class="wikitable"
! shortcut !! result
]]
	}
	
	local row = [[
|-
| templateCode || result
]]
	
	for _, example in pairs(examples) do
		local textparam
		if find(example, "=") then
			textparam = "2=" .. example -- Currently, "=" is only used in the shortcuts for Greek, and Greek is always found in the second parameter, since the first parameter specify the language, "grc".
		else
			textparam = example
		end
		
		local template = {
			[1] = "subst:chars",
			[2] = lang or textparam,
			[3] = lang and textparam,
		}
		
		local result = export.replace{lang, example}
		
		local content = {
			templateCode = formatLink(template),
			result = tag(result, lang),
		}
		
		local function addContent(item)
			if content[item] then
				return content[item]
			else
				return 'No content for "' .. item .. '".'
			end
		end
		
		local row = gsub(row, "%a+", addContent)
		
		table.insert(output, row)
	end
	
	return table.concat(output) .. "|}"
end

return export