本模組由{{chars}}(以及{{chars/example}})調用,將ASCII鍵盤快捷鍵替換為多種語言中使用的字符。

要編輯快捷方式列表,請參見Module:Typing-aids/data

測試樣例

编辑

2測試s失敗。 (刷新)

文字 預期 實際
test_Akkadian:
Passed ša 𒊭 𒊭
文字 預期 實際
test_Arabic:
Passed al-Huruuf al-qamariyyat' الْحُرُوف الْقَمَرِيَّة الْحُرُوف الْقَمَرِيَّة
Passed al-Huruuf al-xamsiyyat' الْحُرُوف الشَّمْسِيَّة الْحُرُوف الشَّمْسِيَّة
Passed ealifu WlwaSli أَلِفُ ٱلْوَصْلِ أَلِفُ ٱلْوَصْلِ
Passed maae مَاء مَاء
Passed muemin مُؤْمِن مُؤْمِن
Passed eiDaafat' إِضَافَة إِضَافَة
Passed eaab آب آب
Passed qureaan قُرْآن قُرْآن
Passed qiTTat' قِطَّة قِطَّة
Passed faEEaal فَعَّال فَعَّال
Passed xayeu شَيْءُ شَيْءُ
Passed xayeaN شَيْءً شَيْءً
Passed daaeimaN دَائِمًا دَائِمًا
Passed mabduueat' مَبْدُوءَة مَبْدُوءَة
Passed mabduu'at' مَبْدُوءَة مَبْدُوءَة
Passed badaaeiyyuN بَدَائِيٌّ بَدَائِيٌّ
Passed badaaeat' بَدَاءَة بَدَاءَة
Passed maktuub مَكْتُوب مَكْتُوب
Passed taHriir تَحْرِير تَحْرِير
Passed EuZmaaa عُظْمَى عُظْمَى
Passed ean0 أَنْ أَنْ
Passed law0 لَوْ لَوْ
Passed xay'aN شَيْءً شَيْءً
Passed ta7riir تَحْرِير تَحْرِير
Passed 3axarat' عَشَرَة عَشَرَة
文字 預期 實際
test_Armenian:
Passed azgaynac`um ազգայնացում ազգայնացում
Failed azgaynacʿum ազգայնացում ազգայնածʿում
Passed terew տերև տերև
Passed burz^uazia բուրժուազիա բուրժուազիա
Passed buržuazia բուրժուազիա բուրժուազիա
Passed kol_mnaki կողմնակի կողմնակի
Passed kołmnaki կողմնակի կողմնակի
文字 預期 實際
test_Armenian_tr:
Failed azgaynac`um azgaynacʿum azgaynacʻum
Passed terew terew terew
Passed burz^uazia buržuazia buržuazia
Passed kol_mnaki kołmnaki kołmnaki
文字 預期 實際
test_Avestan:
Passed ap 𐬀𐬞 𐬀𐬞
Passed xs.^uuas^ 𐬑𐬴𐬎𐬎𐬀𐬱 𐬑𐬴𐬎𐬎𐬀𐬱
Passed xṣ̌uuaš 𐬑𐬴𐬎𐬎𐬀𐬱 𐬑𐬴𐬎𐬎𐬀𐬱
Passed v@hrka_na 𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀 𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀
Passed vəhrkāna 𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀 𐬬𐬆𐬵𐬭𐬐𐬁𐬥𐬀
Passed nae_za 𐬥𐬀𐬉𐬰𐬀 𐬥𐬀𐬉𐬰𐬀
Passed naēza 𐬥𐬀𐬉𐬰𐬀 𐬥𐬀𐬉𐬰𐬀
Passed zaaO 𐬰𐬃 𐬰𐬃
Passed zā̊ 𐬰𐬃 𐬰𐬃
Passed hizwaO 𐬵𐬌𐬰𐬎𐬎𐬂 𐬵𐬌𐬰𐬎𐬎𐬂
Passed hizuuå 𐬵𐬌𐬰𐬎𐬎𐬂 𐬵𐬌𐬰𐬎𐬎𐬂
文字 預期 實際
test_Avestan_tr:
Passed ap ap ap
Passed xs.^uuas^ xṣ̌uuaš xṣ̌uuaš
Passed v@hrka_na vəhrkāna vəhrkāna
Passed nae_za naēza naēza
Passed zaaO zā̊ zā̊
Passed hizwaO hizuuå hizuuå
文字 預期 實際
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ǭ
文字 預期 實際
test_Gothic:
Passed ƕaiwa 𐍈𐌰𐌹𐍅𐌰 𐍈𐌰𐌹𐍅𐌰
Passed anþar 𐌰𐌽𐌸𐌰𐍂 𐌰𐌽𐌸𐌰𐍂
Passed fidwōr 𐍆𐌹𐌳𐍅𐍉𐍂 𐍆𐌹𐌳𐍅𐍉𐍂
Passed fidwor 𐍆𐌹𐌳𐍅𐍉𐍂 𐍆𐌹𐌳𐍅𐍉𐍂
Passed mikils 𐌼𐌹𐌺𐌹𐌻𐍃 𐌼𐌹𐌺𐌹𐌻𐍃
Passed hēr 𐌷𐌴𐍂 𐌷𐌴𐍂
Passed her 𐌷𐌴𐍂 𐌷𐌴𐍂
Passed vac 𐍈𐌰𐌸 𐍈𐌰𐌸
文字 預期 實際
test_Greek:
Passed a__i ᾱͅ ᾱͅ
Passed a)lhqh/s ἀληθής ἀληθής
Passed a)lhqhs* ἀληθησ ἀληθησ
Passed a)lhqhs- ἀληθησ- ἀληθησ-
Passed a^)nh/r ᾰ̓νήρ ᾰ̓νήρ
Passed Phlhi+a/dhs Πηληϊάδης Πηληϊάδης
Passed Phlhi^+a^/dhs Πηληῐ̈ᾰ́δης Πηληῐ̈ᾰ́δης
Passed Πηληϊ^ά^δης Πηληῐ̈ᾰ́δης Πηληῐ̈ᾰ́δης
Passed e)a_/n ἐᾱ́ν ἐᾱ́ν
Passed ἐά_ν ἐᾱ́ν ἐᾱ́ν
Passed pa=sa^ πᾶσᾰ πᾶσᾰ
Passed u_(mei=s ῡ̔μεῖς ῡ̔μεῖς
Passed a/)^ner ᾰ̓́νερ ᾰ̓́νερ
Passed a/^)ner ᾰ̓́νερ ᾰ̓́νερ
Passed a)/^ner ᾰ̓́νερ ᾰ̓́νερ
Passed a)^/ner ᾰ̓́νερ ᾰ̓́νερ
Passed dai+/frwn δαΐφρων δαΐφρων
Passed dai/+frwn δαΐφρων δαΐφρων
文字 預期 實際
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
文字 預期 實際
test_Hittite:
Passed a-ku 𒀀𒆪 𒀀𒆪
Passed an-tu-wa-ah-ha-as 𒀭𒌅𒉿𒄴𒄩𒀸 𒀭𒌅𒉿𒄴𒄩𒀸
Passed an-tu-wa-aḫ-ḫa-aš 𒀭𒌅𒉿𒄴𒄩𒀸 𒀭𒌅𒉿𒄴𒄩𒀸
Passed DINGIRIŠKUR 𒀭𒅎 𒀭𒅎
文字 預期 實際
test_Imperial_Aramaic:
Passed 'nḥn 𐡀𐡍𐡇𐡍 𐡀𐡍𐡇𐡍
文字 預期 實際
test_Japanese:
Passed iro ha nihoheto いろ は にほへと いろ は にほへと
Passed uwyi no okuyama うゐ の おくやま うゐ の おくやま
Passed FAMIRI-MA-TO ファミリーマート ファミリーマート
Passed altu あっ あっ
Passed hi/mi/tu ひ・み・つ ひ・み・つ
Passed han'i はんい はんい
Passed hanni はんい はんい
Passed konnyou こんよう こんよう
Passed mannnaka まんなか まんなか
Passed attiike あっちいけ あっちいけ
Passed acchiike あっちいけ あっちいけ
Passed upnusi うpぬし うpぬし
文字 預期 實際
test_Kaithi:
Passed hanU 𑂯𑂢𑂴 𑂯𑂢𑂴
Passed pa_rh_ahi 𑂣𑂜𑂯𑂱 𑂣𑂜𑂯𑂱
Passed siya~ 𑂮𑂱𑂨𑂀 𑂮𑂱𑂨𑂀
Passed jhara-i 𑂕𑂩𑂅 𑂕𑂩𑂅
Passed jharaï 𑂕𑂩𑂅 𑂕𑂩𑂅
Passed Agi 𑂄𑂏𑂱 𑂄𑂏𑂱
Passed āgi 𑂄𑂏𑂱 𑂄𑂏𑂱
文字 預期 實際
test_Kannada:
Passed yaMtra ಯಂತ್ರ ಯಂತ್ರ
Passed sadāśiva ಸದಾಶಿವ ಸದಾಶಿವ
Passed muṣṭi ಮುಷ್ಟಿ ಮುಷ್ಟಿ
Passed dhairya ಧೈರ್ಯ ಧೈರ್ಯ
Passed ELu ಏಳು ಏಳು
Passed iMguzETiyA ಇಂಗುಶೇಟಿಯಾ ಇಂಗುಶೇಟಿಯಾ
Passed upayOga ಉಪಯೋಗ ಉಪಯೋಗ
文字 預期 實際
test_Maithili:
Passed maithilI 𑒧𑒻𑒟𑒱𑒪𑒲 𑒧𑒻𑒟𑒱𑒪𑒲
Passed ghO_r_A 𑒒𑒼𑒛𑓃𑒰 𑒒𑒼𑒛𑓃𑒰
Passed ga_rh_a 𑒑𑒜𑓃 𑒑𑒜𑓃
Passed mokAma 𑒧𑒽𑒏𑒰𑒧 𑒧𑒽𑒏𑒰𑒧
Passed pa~cakhaNDI 𑒣𑒿𑒔𑒐𑒝𑓂𑒛𑒲 𑒣𑒿𑒔𑒐𑒝𑓂𑒛𑒲
Passed heraba 𑒯𑒺𑒩𑒥 𑒯𑒺𑒩𑒥
文字 預期 實際
test_Marwari:
Passed mahAjanI 𑅬𑅱𑅛𑅧𑅑 𑅬𑅱𑅛𑅧𑅑
Passed mukAMm 𑅬𑅒𑅕𑅧𑅬 𑅬𑅒𑅕𑅧𑅬
Passed AvalA 𑅐𑅯𑅮 𑅐𑅯𑅮
Passed AgarA 𑅐𑅗𑅭 𑅐𑅗𑅭
Passed upama 𑅒𑅨𑅬 𑅒𑅨𑅬
Passed iMdaura 𑅑𑅧𑅥𑅒𑅭 𑅑𑅧𑅥𑅒𑅭
文字 預期 實際
test_Old_Church_Slavonic:
Passed ljudije людиѥ людиѥ
Passed azuh азъ азъ
Passed buky боукꙑ боукꙑ
Passed mŭčati мъчати мъчати
Passed Iosija Иосиꙗ Иосиꙗ
文字 預期 實際
test_Old_Marathi:
Passed kuhA 𑘎𑘳𑘮𑘰 𑘎𑘳𑘮𑘰
Passed kuhā 𑘎𑘳𑘮𑘰 𑘎𑘳𑘮𑘰
Passed nibara 𑘡𑘲𑘤𑘨 𑘡𑘲𑘤𑘨
Passed nIbara 𑘡𑘲𑘤𑘨 𑘡𑘲𑘤𑘨
Passed nībara 𑘡𑘲𑘤𑘨 𑘡𑘲𑘤𑘨
Passed Ai 𑘁𑘃 𑘁𑘃
Passed āi 𑘁𑘃 𑘁𑘃
Passed AI 𑘁𑘃 𑘁𑘃
Passed āī 𑘁𑘃 𑘁𑘃
Passed suta 𑘭𑘳𑘝 𑘭𑘳𑘝
Passed sUta 𑘭𑘳𑘝 𑘭𑘳𑘝
Passed suta 𑘭𑘳𑘝 𑘭𑘳𑘝
Passed uta 𑘄𑘝 𑘄𑘝
Passed Uta 𑘄𑘝 𑘄𑘝
Passed uta 𑘄𑘝 𑘄𑘝
Passed na-i 𑘡𑘃 𑘡𑘃
Passed naï 𑘡𑘃 𑘡𑘃
Passed a-ila 𑘀𑘃𑘩 𑘀𑘃𑘩
Passed aïla 𑘀𑘃𑘩 𑘀𑘃𑘩
Passed bhavai 𑘥𑘪𑘺 𑘥𑘪𑘺
Passed cauka 𑘓𑘼𑘎 𑘓𑘼𑘎
Passed ca-utha 𑘓𑘄𑘞 𑘓𑘄𑘞
Passed caütha 𑘓𑘄𑘞 𑘓𑘄𑘞
Passed a-ukSa 𑘀𑘄𑘎𑘿𑘬 𑘀𑘄𑘎𑘿𑘬
Passed a-ukṣa 𑘀𑘄𑘎𑘿𑘬 𑘀𑘄𑘎𑘿𑘬
Passed aükSa 𑘀𑘄𑘎𑘿𑘬 𑘀𑘄𑘎𑘿𑘬
Passed aükṣa 𑘀𑘄𑘎𑘿𑘬 𑘀𑘄𑘎𑘿𑘬
Passed AThoLI 𑘁𑘙𑘻𑘯𑘲 𑘁𑘙𑘻𑘯𑘲
Passed āṭhoḷī 𑘁𑘙𑘻𑘯𑘲 𑘁𑘙𑘻𑘯𑘲
Passed raMbhA 𑘨𑘽𑘥𑘰 𑘨𑘽𑘥𑘰
Passed raṃbhā 𑘨𑘽𑘥𑘰 𑘨𑘽𑘥𑘰
Passed hRdA 𑘮𑘵𑘟𑘰 𑘮𑘵𑘟𑘰
Passed hṛdā 𑘮𑘵𑘟𑘰 𑘮𑘵𑘟𑘰
Passed Rkha 𑘆𑘏 𑘆𑘏
Passed ṛkha 𑘆𑘏 𑘆𑘏
Passed SaDa 𑘬𑘚 𑘬𑘚
Passed ṣaḍa 𑘬𑘚 𑘬𑘚
Passed kSeNa 𑘎𑘿𑘬𑘹𑘜 𑘎𑘿𑘬𑘹𑘜
Passed kṣeṇa 𑘎𑘿𑘬𑘹𑘜 𑘎𑘿𑘬𑘹𑘜
Passed zobhaNe 𑘫𑘻𑘥𑘜𑘹 𑘫𑘻𑘥𑘜𑘹
Passed śobhaṇe 𑘫𑘻𑘥𑘜𑘹 𑘫𑘻𑘥𑘜𑘹
Passed arha 𑘀𑘨𑘿𑘮 𑘀𑘨𑘿𑘮
Passed mar_hATI 𑘦𑘨𑘿‍𑘮𑘰𑘘𑘲 𑘦𑘨𑘿‍𑘮𑘰𑘘𑘲
Passed maṟhāṭī 𑘦𑘨𑘿‍𑘮𑘰𑘘𑘲 𑘦𑘨𑘿‍𑘮𑘰𑘘𑘲
文字 預期 實際
test_Old_Marathi_tr:
Passed kuhA kuhā kuhā
Passed nibara nibara nibara
Passed nIbara nībara nībara
Passed Ai āi āi
Passed AI āī āī
Passed suta suta suta
Passed sUta suta suta
Passed uta uta uta
Passed Uta uta uta
Passed na-i na-i na-i
Passed naï naï naï
Passed a-ila a-ila a-ila
Passed aïla aïla aïla
Passed bhavai bhavai bhavai
Passed cauka cauka cauka
Passed ca-utha ca-utha ca-utha
Passed caütha caütha caütha
Passed a-ukSa a-ukṣa a-ukṣa
Passed aükSa aükṣa aükṣa
Passed AThoLI āṭhoḷī āṭhoḷī
Passed raMbhA raṃbhā raṃbhā
Passed hRdA hṛdā hṛdā
Passed Rkha ṛkha ṛkha
Passed SaDa ṣaḍa ṣaḍa
Passed kSeNa kṣeṇa kṣeṇa
Passed zobhaNe śobhaṇe śobhaṇe
Passed arha arha arha
Passed mar_hATI maṟhāṭī maṟhāṭī
文字 預期 實際
test_Old_Persian:
Passed aitiiy 𐎠𐎡𐎫𐎡𐎹 𐎠𐎡𐎫𐎡𐎹
Passed raucah 𐎼𐎢𐎨𐏃 𐎼𐎢𐎨𐏃
Passed ham 𐏃𐎶 𐏃𐎶
Passed jiva 𐎪𐎺 𐎪𐎺
Passed daraniyakara 𐎭𐎼𐎴𐎹𐎣𐎼 𐎭𐎼𐎴𐎹𐎣𐎼
Passed daragama 𐎭𐎼𐎥𐎶 𐎭𐎼𐎥𐎶
文字 預期 實際
test_Old_South_Arabian:
Passed s²ms¹ 𐩦𐩣𐩪 𐩦𐩣𐩪
文字 預期 實際
test_Ossetian:
Passed fynʒ фындз фындз
Passed æxsæv ӕхсӕв ӕхсӕв
Passed c’æx цъӕх цъӕх
Passed biræǧ бирӕгъ бирӕгъ
Passed Ræstʒinad Рӕстдзинад Рӕстдзинад
文字 預期 實際
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ǵʰ-
文字 預期 實際
test_Parthian:
Passed tšynd 𐫤𐫢𐫏𐫗𐫅 𐫤𐫢𐫏𐫗𐫅
Passed xʾrtʾg 𐫟𐫀𐫡𐫤𐫀𐫃 𐫟𐫀𐫡𐫤𐫀𐫃
Passed hʾmhyrz 𐫍𐫀𐫖𐫍𐫏𐫡𐫉 𐫍𐫀𐫖𐫍𐫏𐫡𐫉
Passed ʿšnwhr 𐫙𐫢𐫗𐫇𐫍𐫡 𐫙𐫢𐫗𐫇𐫍𐫡
Passed hʾwsʾr 𐫍𐫀𐫇𐫘𐫀𐫡 𐫍𐫀𐫇𐫘𐫀𐫡
文字 預期 實際
test_Persian:
Passed brAdr برادر برادر
文字 預期 實際
test_Sanskrit:
Passed saMskRta/ संस्कृत संस्कृत
Passed saṃskṛtá संस्कृत संस्कृत
Passed kSatri/ya क्षत्रिय क्षत्रिय
Passed kṣatríya क्षत्रिय क्षत्रिय
Passed rAja suprabuddha राज सुप्रबुद्ध राज सुप्रबुद्ध
Passed rāja suprabuddha राज सुप्रबुद्ध राज सुप्रबुद्ध
Passed zAkyamuni शाक्यमुनि शाक्यमुनि
Passed śākyamuni शाक्यमुनि शाक्यमुनि
Passed siMha सिंह सिंह
Passed siṃha सिंह सिंह
Passed nAman नामन् नामन्
Passed nāman नामन् नामन्
Passed anA/ अना अना
Passed anā́ अना अना
Passed ayuSmAn अयुष्मान् अयुष्मान्
Passed ayuṣmān अयुष्मान् अयुष्मान्
Passed ghatsyati घत्स्यति घत्स्यति
Passed tApa-i तापइ तापइ
Passed tāpa-i तापइ तापइ
Passed tApaï तापइ तापइ
Passed tāpaï तापइ तापइ
文字 預期 實際
test_Sanskrit_tr:
Passed saMskRta/ saṃskṛtá saṃskṛtá
Passed kSatri/ya kṣatríya kṣatríya
Passed rAja suprabuddha rāja suprabuddha rāja suprabuddha
Passed zAkyamuni śākyamuni śākyamuni
Passed siMha siṃha siṃha
Passed nAman nāman nāman
Passed anA/ anā́ anā́
Passed ayuSmAn ayuṣmān ayuṣmān
Passed ghatsyati ghatsyati ghatsyati
Passed tApa-i tāpa-i tāpa-i
Passed tApaï tāpaï tāpaï
文字 預期 實際
test_Saurashtra:
Passed pani ꢦꢥꢶ ꢦꢥꢶ
Passed vAg ꢮꢵꢔ꣄ ꢮꢵꢔ꣄
Passed ghoDo ꢕꣁꢞꣁ ꢕꣁꢞꣁ
Passed dukkar ꢣꢸꢒ꣄ꢒꢬ꣄ ꢣꢸꢒ꣄ꢒꢬ꣄
Passed l:ovo ꢭꢴꣁꢮꣁ ꢭꢴꣁꢮꣁ
文字 預期 實際
test_Siddham:
Passed kanta 𑖎𑖡𑖿𑖝 𑖎𑖡𑖿𑖝
Passed purAna 𑖢𑖲𑖨𑖯𑖡 𑖢𑖲𑖨𑖯𑖡
Passed Na-i 𑖜𑖂 𑖜𑖂
Passed kaNNa 𑖎𑖜𑖿𑖜 𑖎𑖜𑖿𑖜
Passed samAia 𑖭𑖦𑖯𑖂𑖀 𑖭𑖦𑖯𑖂𑖀
Passed tujjhu 𑖝𑖲𑖕𑖿𑖖𑖲 𑖝𑖲𑖕𑖿𑖖𑖲
Passed kahante 𑖎𑖮𑖡𑖿𑖝𑖸 𑖎𑖮𑖡𑖿𑖝𑖸
文字 預期 實際
test_Sindhi:
Passed siMdhī 𑋝𑋡𑋟𑋐𑋢 𑋝𑋡𑋟𑋐𑋢
Passed bhAGo 𑋖𑋠𑊿𑋧 𑋖𑋠𑊿𑋧
Passed mAlu 𑋗𑋠𑋚𑋣 𑋗𑋠𑋚𑋣
Passed jeko 𑋂𑋥𑊺𑋧 𑋂𑋥𑊺𑋧
Passed xabara 𑊻𑋩𑋔𑋙 𑊻𑋩𑋔𑋙
Passed muqAmu 𑋗𑋣𑊺𑋩𑋠𑋗𑋣 𑋗𑋣𑊺𑋩𑋠𑋗𑋣
Passed meM 𑋗𑋥𑋟 𑋗𑋥𑋟
Passed gunAhu 𑊼𑋣𑋑𑋠𑋞𑋣 𑊼𑋣𑋑𑋠𑋞𑋣
Passed _gh_araza 𑊼𑋩𑋙𑋂𑋩 𑊼𑋩𑋙𑋂𑋩
Passed _gh_ufA 𑊼𑋩𑋣𑋓𑋩𑋠 𑊼𑋩𑋣𑋓𑋩𑋠
Passed bA_gh_u 𑋔𑋠𑊼𑋩𑋣 𑋔𑋠𑊼𑋩𑋣
Passed ba_gh_adAdu 𑋔𑊼𑋩𑋏𑋠𑋏𑋣 𑋔𑊼𑋩𑋏𑋠𑋏𑋣
Passed ghaTaNu 𑊾𑋆𑋌𑋣 𑊾𑋆𑋌𑋣
文字 預期 實際
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 m_data = mw.loadData("Module:typing-aids/data")
local m_string_utils = require("Module:string utilities")
local reorderDiacritics = require("Module:grc-utilities").reorderDiacritics
local template_link = require("Module:template parser").templateLink
local listToSet = require("Module:table").listToSet

--[=[
	Other data modules:
-- [[Module:typing-aids/data/ar]]
-- [[Module:typing-aids/data/fa]]
-- [[Module:typing-aids/data/gmy]]
-- [[Module:typing-aids/data/grc]]
-- [[Module:typing-aids/data/hit]]
-- [[Module:typing-aids/data/hy]]
-- [[Module:typing-aids/data/sa]]
-- [[Module:typing-aids/data/sux]]
-- [[Module:typing-aids/data/got]]
-- [[Module:typing-aids/data/pra]]
--]=]

local U = m_string_utils.char
local gsub = m_string_utils.gsub
local find = m_string_utils.find
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD

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

local function load_or_nil(module_name)
	local success, module = pcall(mw.loadData, module_name)
	if success then
		return module
	end
end

-- Try to load a list of modules. Return the first successfully loaded module
-- and its name.
local function get_module_and_title(...)
	for i = 1, select("#", ...) do
		local module_name = select(i, ...)
		if module_name then
			local module = load_or_nil(module_name)
			if module then
				return module, module_name
			end
		end
	end
end

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
			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
-- compose Latin text, then decompose into sequences of letter and combining
-- accent, either partly or completely depending on the language.
local function compose_decompose(text, lang)
	if lang == "sa" or lang == "hy" or lang == "xcl" or lang == "kn" or lang == "inc-ash" or lang == "inc-kam" or lang == "inc-oaw" or lang == "pra" or lang == "omr" or lang == "mai" or lang == "saz" or lang == "sd" or lang == "mwr" or lang == "skr" or lang == "pra-Knda" or lang == "pra-Deva" or lang == "doi" or lang == "sa-Gujr" or lang == "sa-Modi" or lang == "sa-Shrd" or lang == "sa-Sidd" or lang == "omr-Deva" or lang == "bho" then
		acute_decomposer = acute_decomposer or m_data.acute_decomposer
		text = toNFC(text)
		text = gsub(text, ".", acute_decomposer)
	else
		text = toNFD(text)
	end
	return text
end

local function do_one_replacement(text, from, to, before, after)
	-- FIXME! These won't work properly if there are any captures in FROM.
	if before then
		from = "(" .. before .. ")" .. from
		to = "%1" .. to
	end
	if after then
		from = from .. "(" .. after .. ")"
		to = to .. (before and "%2" or "%1")
	end
	text = gsub(text, from, to) -- discard second retval
	return text
end

local function do_key_value_replacement_table(text, tab)
	for from, repl in pairs(tab) do
		local to, before, after
		if type(repl) == "string" then
			to = repl
		else
			to = repl[1]
			before = repl.before
			after = repl.after
		end
		text = do_one_replacement(text, from, to, before, after)
	end
	-- FIXME, why is this being done here after each table?
	text = mw.text.trim(text)

	return text
end


local function do_replacements(text, repls)
	if repls[1] and repls[1][1] then
		-- new-style list
		for _, from_to in ipairs(repls) do
			text = do_one_replacement(text, from_to[1], from_to[2], from_to.before, from_to.after)
		end
		text = mw.text.trim(text)
	elseif repls[1] then
		for _, repl_table in ipairs(repls) do
			text = do_key_value_replacement_table(text, repl_table)
		end
	else
		text = do_key_value_replacement_table(text, repls)
	end

	return text
end


local function get_replacements(lang, script)
	local module_data = m_data.modules[lang]
	local replacements_module
	if not module_data then
		replacements_module = m_data
	else
		local success
		local resolved_name = "Module:typing-aids/data/"
			.. (module_data[1] or module_data[script] or module_data.default)
		replacements_module = load_or_nil(resolved_name)
		if not replacements_module then
			error("Data module " .. resolved_name
				.. " specified in 'modules' table of [[Module:typing-aids/data]] does not exist.")
		end
	end
	
	local replacements
	if not module_data then
		if lang then
			replacements = replacements_module[lang]
		else
			replacements = replacements_module.all
		end
	elseif module_data[2] then
		replacements = replacements_module[module_data[2]]
	else
		replacements = replacements_module
	end
	
	return replacements
end

local function interpret_shortcuts(text, origlang, script, untouchedDiacritics, moduleName)
	if not text or type(text) ~= "string" then
		return nil
	end

	local lang = origlang
	if lang == "xcl" then lang = "hy" end
	local replacements = moduleName and load_or_nil("Module:typing-aids/data/" .. moduleName)
		or get_replacements(lang, script)
		or error("The language code \"" .. tostring(origlang) ..
			"\" does not have a set of replacements in Module:typing-aids/data or its submodules.")
	
	-- Hittite transliteration must operate on composed letters, because it adds
	-- diacritics to Basic Latin letters: s -> š, for instance.
	if lang ~= "hit-tr" then
		text = compose_decompose(text, lang)
	end
	
	if lang == "ae" or lang == "bho" or lang == "sa" or lang == "got" or lang == "hy" or lang == "xcl" or lang == "kn" or lang == "inc-ash" or lang == "inc-kam" or lang == "pra" or lang == "pal" or lang == "sog" or lang == "xpr" or lang == "omr" or lang == "mai" or lang == "saz" or lang == "sd" or lang == "mwr" or lang == "skr" or lang == "pra-Knda" or lang == "pra-Deva" or lang == "doi" or lang == "sa-Gujr" or lang == "sa-Modi" or lang == "sa-Shrd" or lang == "sa-Sidd" or lang == "inc-oaw" or lang == "omr-Deva" then
		local transliterationTable = get_replacements(lang .. "-tr")
			or script and get_replacements(script .. "-tr")
		
		if not transliterationTable then
			error("No transliteration table for " .. lang .. "-tr" .. (script and (" or " .. script .. "-tr") or " and no script has been provided"))
		end
		
		text = do_replacements(text, transliterationTable)
		
		text = compose_decompose(text, lang)
		
		text = do_replacements(text, replacements)
	else
		text = do_replacements(text, replacements)
		
		if lang == "grc" and not untouchedDiacritics then
			text = reorderDiacritics(text)
		end
	end
	
	return text
end

export.interpret_shortcuts = interpret_shortcuts

local function hyphen_separated_replacements(text, lang)
	local module = mw.loadData("Module:typing-aids/data/" .. lang)
	local replacements = module[lang] or module
	if not replacements then
		error("??")
	end
	
	text = text:gsub("<sup>(.-)</sup>%-?", "%1-")
	
	if replacements.pre then
		for k, v in pairs(replacements.pre) do
			text = gsub(text, k, v)
		end
	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 add_parameter(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 add_and_convert_parameter(list, args, key, altkey1, altkey2, trkey, lang, scriptKey)
	if altkey1 and args[altkey1] then
		add_and_convert_parameter(list, args, key, nil, nil, nil, lang, scriptKey)
		key = altkey1
	elseif altkey2 and args[altkey2] then
		add_and_convert_parameter(list, args, key, nil, nil, nil, lang, scriptKey)
		key = altkey2
	end
	local content = args[key]
	if trkey and args[trkey] then
		if not content then
			content = args[trkey]
			args[trkey] = nil
		else
			if args[trkey] ~= "-" then
				error("Can't specify manual translit " .. trkey .. "=" ..
					args[trkey] .. " along with parameter " .. key .. "=" .. content)
			end
		end
	end
	if not content then return false end
	local trcontent = nil
	-- If Sanskrit or Prakrit or Kannada 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" or lang == "kn" or lang == "inc-ash" or lang == "inc-kam" or lang == "pra" or lang == "omr" or lang == "mai" or lang == "saz" or lang == "sd" or lang == "mwr" or lang == "skr" or lang == "pra-Knda" or lang == "pra-Deva" or lang == "doi" or lang == "sa-Gujr" or lang == "sa-Modi" or lang == "sa-Shrd" or lang == "sa-Sidd" or lang == "inc-oaw" or lang == "omr-Deva" or lang == "bho" then
		local proposed_trcontent = interpret_shortcuts(content, lang .. "-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 = interpret_shortcuts(content, "got-tr")
		if find(proposed_trcontent, macron) then
			trcontent = proposed_trcontent
		end
	end
	
	--[[
	if lang == "gmy" then
		local proposed_trcontent = interpret_shortcuts(content, "gmy-tr")
		if find(proposed_trcontent, macron) then
			trcontent = proposed_trcontent
		end
	end
	--]]
	
	local converted_content
	if lang == "hit" or lang == "akk" then
		trcontent = interpret_shortcuts(content, lang .. "-tr")
		converted_content = hyphen_separated_replacements(content, lang)
	elseif lang == "sux" or lang == "gmy" then
		converted_content = hyphen_separated_replacements(content, lang)
	elseif lang == "pal" or lang == "sog" or lang == "xpr" then
		local script = args[scriptKey] or m_data.modules[lang].default
		local script_object = require "Module:scripts".getByCode(script)
		local proposed_trcontent = interpret_shortcuts(content, script .. "-tr")
		local auto_tr = (require "Module:languages".getByCode(lang)
			:transliterate(converted_content, script_object))
		if proposed_trcontent ~= auto_tr then
			trcontent = proposed_trcontent
		end
		converted_content = interpret_shortcuts(content, lang, script, nil, args.module)
	else
		converted_content = interpret_shortcuts(content, lang, args[scriptKey], nil, args.module)
	end
	
	add_parameter(list, args, key, converted_content)
	if trcontent then
		add_parameter(list, args, trkey, trcontent)
	end
	return true
end
	

local is_compound = listToSet{ "affix", "af", "compound", "com", "suffix", "suf", "prefix", "pre", "con", "confix", "surf" }
-- Technically lang, ux, and uxi aren't link templates, but they have many of the same parameters.
local is_link_template = listToSet{
	"m", "m+", "langname-mention", "l", "ll",
	"cog", "noncog", "cognate", "ncog", "nc", "noncognate", "cog+",
	"m-self", "l-self",
	"alter", "alt", "syn",
	"alt sp", "alt form",
	"alternative spelling of", "alternative form of",
	"desc", "desctree", "lang", "usex", "ux", "uxi"
}
local is_two_lang_link_template = listToSet{ "der", "inh", "bor", "slbor",  "lbor", "calque", "cal", "translit", "inh+", "bor+" }
local is_trans_template = listToSet{ "t", "t+", "t-check", "t+check" }

local function print_template(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
	
	add_parameter(result, parameters, 1)
	lang = parameters[2]
	add_parameter(result, parameters, 2)
	if is_link_template[template] then
		add_and_convert_parameter(result, parameters, 3, "alt", 4, "tr", lang, "sc")
		for _, param in ipairs({ 5, "gloss", "t" }) do
			add_parameter(result, parameters, param)
		end
	elseif is_two_lang_link_template[template] then
		lang = parameters[3]
		add_parameter(result, parameters, 3)
		add_and_convert_parameter(result, parameters, 4, "alt", 5, "tr", lang, "sc")
		for _, param in ipairs({ 6, "gloss", "t" }) do
			add_parameter(result, parameters, param)
		end
	elseif is_trans_template[template] then
		add_and_convert_parameter(result, parameters, 3, "alt", nil, "tr", lang, "sc")
		local i = 4
		while true do
			if not parameters[i] then
				break
			end
			add_parameter(result, parameters, i)
		end
	elseif is_compound[template] then
		local i = 1
		while true do
			local sawparam = add_and_convert_parameter(result, parameters, i + 2, "alt" .. i, nil, "tr" .. i, lang, "sc")
			if not sawparam then
				break
			end
			for _, param in ipairs({ "id", "lang", "sc", "t", "pos", "lit" }) do
				add_parameter(result, parameters, param .. i)
			end
			i = i + 1
		end
	else
		error("Unrecognized template name '" .. template .. "'")
	end
	-- Copy any remaining parameters
	for k in pairs(parameters) do
		add_parameter(result, parameters, k)
	end
	return "{{" .. table.concat(result, "|") .. "}}"
end

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

function export.replace(frame)
	local args = clone_args(frame)
	local text, lang
	
	if args[4] or args[3] or args.tr then
		return print_template(args)
	else
		if args[2] then
			lang, text = args[1], args[2]
		else
			lang, text = "all", args[1]
		end
	end
	
	if lang == "akk" or lang == "gmy" or lang == "hit" or lang == "sux" then
		return hyphen_separated_replacements(text, lang)
	else
		text = interpret_shortcuts(text, lang, args.sc, args.noreorder, args.module)
	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 = {
		lang ~= "all" and lang or textparam,
		lang ~= "all" and textparam or nil,
	}
	
	local output = { template_link("subst:chars", 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"
! 快捷方式 !! 结果
]]
	}
	
	local row = [[
|-
| 模板代码 || 结果
]]
	
	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 = {
			lang or textparam,
			lang and textparam,
		}
		
		local result = export.replace{lang, example}
		
		local content = {
			['模板代码'] = template_link("subst:chars", template),
			['结果'] = 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