Wikiorðabók
iswiktionary
https://is.wiktionary.org/wiki/Wikior%C3%B0ab%C3%B3k:Fors%C3%AD%C3%B0a
MediaWiki 1.47.0-wmf.23
case-sensitive
Miðill
Kerfissíða
Spjall
Notandi
Notandaspjall
Wikiorðabók
Wikiorðabókarspjall
Mynd
Myndaspjall
Melding
Meldingarspjall
Snið
Sniðaspjall
Hjálp
Hjálparspjall
Flokkur
Flokkaspjall
Viðauki
Viðaukaspjall
Samheitasafn
Samheitasafnsspjall
Skjátexti
Skjátextaspjall
Module
Module talk
Event
Event talk
Georgisch
0
3188
394134
234810
2026-10-12T18:56:35Z
~2026-54721-68
9780
394134
wikitext
text/x-wiki
=={{-nl-}}==
==={{-nl-nafnorð-}}===
'''Georgisch'''
#[[georgíska]]
{{-framburður-}}
*{{hljóðskrá|nl-Georgisch.ogg|Georgisch}}
{{2x----}}
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Georgisch'''
#[[georgíska]]
e4r2ymosk54504zhd9qtishhe0ubpnk
georgíska
0
3189
394135
321469
2026-10-12T19:00:19Z
~2026-54721-68
9780
394135
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|georgísk}}
'''georgíska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Georgía]]
{{-þýðingar-}}
{{þýðingar
|af= [[Georgies]]
|sq= [[Gjorgjian]]
|am= [[ጊዮርጊያኛ]]
|ar= [[جورجية]]
|hy= [[Վրացական]], [[Վրացերեն]]
|az= [[Ҝүрҹү]]
|eu= [[Georgiera]]
|be= [[Грузінская]]
|bg= [[Грузински]]
|zh= [[格鲁吉亚语]]
|hr= [[Gruzijski]]
|cs= [[Gruzínský]]
|da= [[Georgisk]]
|en= [[Georgian]]
|et= [[gruusia keel]]
|fo= [[Georgiskt]]
|fa= [[گرجستانى]]
|fi= [[georgia]]
|fr= [[géorgien]] ''m''
|ka= [[ქართული]]
|de= [[Georgisch]]
|el= [[Γεωργιανά]]
|gu= [[જ્યોર્જિયન]]
|he= [[גרוזינית]] (Gruzinit)
|hi= [[जिर्योजियन]]
|hu= [[Grúz]]
|it= [[georgiano]]
|id= [[Georgia]]
|ga= [[Georgiano]]
|ja= [[グルジア語]]
|ko= [[그루지안어]]
|lv= [[Gruzīnu]]
|lt= [[Gruziniškai]]
|mk= [[Грузиски]]
|ms= [[Georgia]]
|mt= [[Ġorġjan]]
|mr= [[जॉर्जियन]]
|mdf= [[Грузинань]]
|mn= [[Гvрж]]
|ne= [[जोरजियन]]
|nl= [[Georgisch]]
|no= [[georgisk]]
|pl= [[gruziński]]
|pt= [[georgiano]]
|ra= [[georgiano]]
|ro= [[gruzină]]
|ru= [[Грузинский]]
|sr= [[Ђорђијски]]
|sk= [[Georgijský]]
|es= [[georgiano]]
|sv= [[georgiska]]
|ta= [[ஜார்ஜியன்]]
|tt= [[Грузия]]
|th= [[ภาษาจอร์เจี่ยน]], [[ภาษาจอร์เจีย]]
|tr= [[Gürcüce]]
|uk= [[Грузинський]]
|ur= [[جارجي]]
|vi= [[Tiếng Geor-gi-an]]
|wa= [[Djeyordjyin]]
}}
{{-tilvísun-}}
{{Wikipedia|georgíska}}
ky9ou8remhprlykkfo50j6xzxbzyhou
víetnamska
0
3215
394153
366062
2026-10-12T20:46:00Z
~2026-54721-68
9780
394153
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 ö et|víetn|msk}}
'''víetnamska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Vietnam]]
{{-þýðingar-}}
{{þýðingar
|af= [[Vietnamees]]
|sq= [[Vietnamisht]]
|am= [[ቪትናምኛ]]
|ar= [[فيتنامية]]
|hy= [[Վիետնամերեն]]
|az= [[Вјетнам]]
|eu= [[Vietnamera]]
|be= [[Віетнамскай]], [[Віетнамская]]
|bg= [[Виетнамски]]
|ca= [[Vietnamita]]
|zh= [[越南语]]
|hr= [[Vijetnamski]]
|cs= [[vietnamský]]
|da= [[Vietnamesisk]] ?
|en= {{þýðing|en|Vietnamese}}
|et= [[Vietnami]]
|fo= [[Vietnamesiskt]] ?
|fa= [[ويتنامى]]
|fi= {{þýðing|fi|vietnamilainen}}
|fr= {{þýðing|fr|vietnamien}}
|fy= [[Fiëtnameesk]]
|ka= [[ვიეტნამური]]
|de= {{þýðing|de|Vietnamesisch}}
|el= [[Βιετναμέζικα]]
|he= [[וויאטנמית]]
|hi= [[वियेतनामी]]
|hu= [[Vietnami]]
|id= [[Vietnam]]
|ga= [[Vítneamais]]
|it= [[vietnamita]]
|ja= [[ベトナム語]]
|ko= [[베트남어]]
|lv= [[Vjetnamiešu]]
|lt= [[Vietnamiečių]], [[Vietnamietiškai]]
|mk= [[Виетнамски]]
|ms= [[Vietnam]]
|mt= [[Vjetnamiż]]
|mdf= [[Вьетнамонь]]
|mn= [[Вьетнам]], [[Ветнам]]
|nds= [[Vietnameessch]]
|ne= [[भियतनामी]]
|nl= {{þýðing|nl|Vietnamees}}
|no= {{þýðing|no|vietnamesisk}}
|oc= [[Vietnamin]]
|pl= [[wietnamski]]
|pt= [[Vietnamita]]
|ru= [[Вьетнамский]]
|sr= [[Вијетнамски]]
|sk= {{þýðing|sk|vietnamčina}}
|sl= [[Vietnamščina]]
|es= {{þýðing|es|vietnamita}}
|sw= [[Kivietnam]], [[Kivietinamu]]
|sv= {{þýðing|sv|vietnamesiska}}
|tl= [[Vietnamis]], [[Biyetnam]]
|ta= [[வியட்னாமீஸ்]]
|tt= [[Вьетнам]]
|th= [[ภาษาเวียดนาม]]
|tr= [[Vietnamca]]
|uk= [[В'єтнамський]]
|ur= [[ويتنامي]]
|vi= [[Tiếng Việt]]
|wa= [[Vietnamyin]]
|cy= [[Fietnameg]], [[Fietmin]]
}}
{{-tilvísun-}}
{{Wikipedia|víetnamska}}
lf8i96sr8z4s7girvwhrf2tfoyolujl
394154
394153
2026-10-12T20:46:57Z
~2026-54721-68
9780
394154
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 ö et|víetn|msk}}
'''víetnamska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Vietnam]]
{{-þýðingar-}}
{{þýðingar
|af= [[Vietnamees]]
|sq= [[Vietnamisht]]
|am= [[ቪትናምኛ]]
|ar= [[فيتنامية]]
|hy= [[Վիետնամերեն]]
|az= [[Вјетнам]]
|eu= [[Vietnamera]]
|be= [[Віетнамскай]], [[Віетнамская]]
|bg= [[Виетнамски]]
|ca= [[Vietnamita]]
|zh= [[越南语]]
|hr= [[Vijetnamski]]
|cs= [[vietnamský]]
|da= [[vietnamesisk]]
|en= {{þýðing|en|Vietnamese}}
|et= [[Vietnami]]
|fo= [[Vietnamesiskt]] ?
|fa= [[ويتنامى]]
|fi= {{þýðing|fi|vietnamilainen}}
|fr= {{þýðing|fr|vietnamien}}
|fy= [[Fiëtnameesk]]
|ka= [[ვიეტნამური]]
|de= {{þýðing|de|Vietnamesisch}}
|el= [[Βιετναμέζικα]]
|he= [[וויאטנמית]]
|hi= [[वियेतनामी]]
|hu= [[Vietnami]]
|id= [[Vietnam]]
|ga= [[Vítneamais]]
|it= [[vietnamita]]
|ja= [[ベトナム語]]
|ko= [[베트남어]]
|lv= [[Vjetnamiešu]]
|lt= [[Vietnamiečių]], [[Vietnamietiškai]]
|mk= [[Виетнамски]]
|ms= [[Vietnam]]
|mt= [[Vjetnamiż]]
|mdf= [[Вьетнамонь]]
|mn= [[Вьетнам]], [[Ветнам]]
|nds= [[Vietnameessch]]
|ne= [[भियतनामी]]
|nl= {{þýðing|nl|Vietnamees}}
|no= {{þýðing|no|vietnamesisk}}
|oc= [[Vietnamin]]
|pl= [[wietnamski]]
|pt= [[Vietnamita]]
|ru= [[Вьетнамский]]
|sr= [[Вијетнамски]]
|sk= {{þýðing|sk|vietnamčina}}
|sl= [[Vietnamščina]]
|es= {{þýðing|es|vietnamita}}
|sw= [[Kivietnam]], [[Kivietinamu]]
|sv= {{þýðing|sv|vietnamesiska}}
|tl= [[Vietnamis]], [[Biyetnam]]
|ta= [[வியட்னாமீஸ்]]
|tt= [[Вьетнам]]
|th= [[ภาษาเวียดนาม]]
|tr= [[Vietnamca]]
|uk= [[В'єтнамський]]
|ur= [[ويتنامي]]
|vi= [[Tiếng Việt]]
|wa= [[Vietnamyin]]
|cy= [[Fietnameg]], [[Fietmin]]
}}
{{-tilvísun-}}
{{Wikipedia|víetnamska}}
h44nhtolfkurlmlu9fjvo20b7rf3y0w
kóreska
0
3229
394150
242917
2026-10-12T20:43:15Z
~2026-54721-68
9780
394150
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|kóresk}}
'''kóreska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Kóreu]]
{{-þýðingar-}}
{{þýðingar
|af= [[Koreaans]]
|sq= [[Korean]]
|am= [[ኮሪያኛ]]
|ar= [[كورية]]
|hy= [[Կորեական]]
|az= [[Кореја]]
|eu= [[Koreera]], [[Korearra]]
|be= [[Карэйская]]
|br= [[Koreeg]]
|bg= [[Корейски]]
|ca= [[Coreà]]
|chr= [[ᎪᎵᎥ]]
|zh= [[朝鲜语]]
|hr= [[Korejski]]
|cs= [[korejský]]
|da= [[Koreansk]]
|en= [[Korean]]
|et= [[Korea]]
|fo= [[Koreanskt]]
|fa= [[کرهای]]
|fi= [[korea]]
|fr= [[coréen]] {{kk.}}
|fy= [[Koreaansk]]
|ka= [[კორეული]]
|de= [[Koreanisch]]
|el= [[Κορεατικά]]
|he= [[קוריאנית]]
|hi= [[कोरियन]]
|nl= [[Koreaans]]
|hu= [[Koreai]]
|is= [[kóreska]]
|id= [[Korea]]
|ga= [[Cóiréis]]
|it= [[coreano]]
|ja= [[韓国語]], [[朝鮮語]]
|km= [[ភាសាកូេរ៉]]
|ko= [[한국말]]
|lv= [[Korejiešu]]
|lt= [[Korėjiečių]], [[Korėjietiškai]]
|mk= [[Корејски]]
|ms= [[Korea]]
|mt= [[Korejan]]
|mr= [[कोरीयन]]
|mdf= [[Кореень]]
|mn= [[Солонгос]]
|nds= [[Koreaansch]]
|ne= [[कोरियाली]]
|nl= [[Koreaans]] {{hk.}}
|no= [[Koreansk]]
|oc= [[Corean]]
|pl= [[koreański]]
|pt= [[Coreano]]
|ro= [[coreană]]
|ru= [[Корейский]]
|sr= [[Корејски]]
|sk= [[Kórejský]]
|sl= [[Korejščina]]
|es= [[coreano]]
|sw= [[Kikorea]]
|sv= [[koreanska]]
|tl= [[Koreano]]
|ta= [[கோரியன்]]
|tt= [[Корея]]
|th= [[ภาษาเกาหลี]]
|tr= [[Korece]]
|uk= [[Корейський]]
|ur= [[کورين]]
|vi= [[Tiếng Triều tiên]]
|wa= [[Coreyin]]
|cy= [[Iaith Corea]]
}}
{{-tilvísun-}}
{{Wikipedia|kóreska}}
jceprgyfcm58ejjd20cahvqwlovmzt0
394151
394150
2026-10-12T20:43:49Z
~2026-54721-68
9780
394151
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|kóresk}}
'''kóreska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Kóreu]]
{{-þýðingar-}}
{{þýðingar
|af= [[Koreaans]]
|sq= [[Korean]]
|am= [[ኮሪያኛ]]
|ar= [[كورية]]
|hy= [[Կորեական]]
|az= [[Кореја]]
|eu= [[Koreera]], [[Korearra]]
|be= [[Карэйская]]
|br= [[Koreeg]]
|bg= [[Корейски]]
|ca= [[Coreà]]
|chr= [[ᎪᎵᎥ]]
|zh= [[朝鲜语]]
|hr= [[Korejski]]
|cs= [[korejský]]
|da= [[Koreansk]]
|en= [[Korean]]
|et= [[Korea]]
|fo= [[Koreanskt]]
|fa= [[کرهای]]
|fi= [[korea]]
|fr= [[coréen]] {{kk.}}
|fy= [[Koreaansk]]
|ka= [[კორეული]]
|de= [[Koreanisch]]
|el= [[Κορεατικά]]
|he= [[קוריאנית]]
|hi= [[कोरियन]]
|nl= [[Koreaans]]
|hu= [[Koreai]]
|id= [[Korea]]
|ga= [[Cóiréis]]
|it= [[coreano]]
|ja= [[韓国語]], [[朝鮮語]]
|km= [[ភាសាកូេរ៉]]
|ko= [[한국말]]
|lv= [[Korejiešu]]
|lt= [[Korėjiečių]], [[Korėjietiškai]]
|mk= [[Корејски]]
|ms= [[Korea]]
|mt= [[Korejan]]
|mr= [[कोरीयन]]
|mdf= [[Кореень]]
|mn= [[Солонгос]]
|nds= [[Koreaansch]]
|ne= [[कोरियाली]]
|nl= [[Koreaans]] {{hk.}}
|no= [[Koreansk]]
|oc= [[Corean]]
|pl= [[koreański]]
|pt= [[Coreano]]
|ro= [[coreană]]
|ru= [[Корейский]]
|sr= [[Корејски]]
|sk= [[Kórejský]]
|sl= [[Korejščina]]
|es= [[coreano]]
|sw= [[Kikorea]]
|sv= [[koreanska]]
|tl= [[Koreano]]
|ta= [[கோரியன்]]
|tt= [[Корея]]
|th= [[ภาษาเกาหลี]]
|tr= [[Korece]]
|uk= [[Корейський]]
|ur= [[کورين]]
|vi= [[Tiếng Triều tiên]]
|wa= [[Coreyin]]
|cy= [[Iaith Corea]]
}}
{{-tilvísun-}}
{{Wikipedia|kóreska}}
9a42is286cs43ocbrhg4j1qiaw2wlk7
Indonesisch
0
3231
394145
317278
2026-10-12T20:29:47Z
~2026-54721-68
9780
394145
wikitext
text/x-wiki
=={{-nl-}}==
==={{-nl-nafnorð-}}===
'''Indonesisch''' {{hk.}}
#[[indónesíska]]
{{-framburður-}}
*{{hljóðskrá|nl-Indonesisch.ogg|Indonesisch}}
=={{-nl-}}==
==={{-nl-lýsingarorð-}}===
'''Indonesisch'''
#[[indónesískur]]
{{-framburður-}}
*{{hljóðskrá|nl-Indonesisch.ogg|Indonesisch}}
{{2x----}}
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Indonesisch''' {{hk.}}
#[[indónesíska]]
6qm801rrazlq3mmdl1b5ewlqfh8z56w
indónesíska
0
3232
394146
242150
2026-10-12T20:31:11Z
~2026-54721-68
9780
394146
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|indónesísk}}
'''indónesíska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Indónesíu]]
{{-þýðingar-}}
{{þýðingar
|af= [[Indonesies]]
|sq= [[Indonezian]]
|am= [[እንዶኒሲኛ]]
|ar= [[إندونيسية]]
|hy= [[Ինդոնէզիան]]
|az= [[Индонезија]]
|eu= [[Indonesiera]]
|be= [[Інданэзійская]]
|bg= [[Индонезийски]]
|ca= [[indonesi]] {{kk.}}
|chr= [[ᎢᏅᏙᏂᏥ]]
|zh= [[印尼语]] or [[印度尼西亚语]]
|hr= [[Indonezijski]]
|cs= [[Indonéský]]
|da= [[Indonesisk]]
|en= [[Indonesian]]
|et= [[Indoneesia]]
|fo= [[Indonesiskt]]
|fa= [[اندونزى]]
|fi= [[indonesia]]
|fr= [[indonésien]] {{kk.}}
|fy= [[Yndonesysk]]
|ka= [[ინდონეზიური]]
|de= [[Indonesisch]] {{hk.}}
|el= [[Ινδονησιακά]]
|gu= [[ઇન્ડોનેશિયન]]
|he= [[אינדונזית]] (In'do'ne'zit)
|hi= [[इंडोनीशियन]]
|hu= [[Indonéz]]
|is= [[indónesísk mál]], [[indónesíska]]
|id= [[bahasa Indonesia]]
|ga= [[Indinéisis]]
|it= [[indonesiano]]
|ja= [[インドネシア語]] (indoneshia-go)
|ko= [[인도네시아어]]
|ku= [[Indonêzî]]
|lv= [[Indonēziešu]]
|lt= [[Indoneziečių]], [[Indoneziškai]]
|ms= [[Bahasa Indonesia]]
|mt= [[Indoneżjan]]
|mdf= [[Индонезиень]]
|mn= [[Инднез]]
|nds= [[Indoneessch]]
|ne= [[इन्डोनेसियाली]]
|nl= [[Indonesisch]]
|no= [[Indonesisk]]
|oc= [[Indonesian]]
|pl= [[indonezyjski]]
|pt= [[Indonésio]]
|ro= [[indoneziană]] {{kvk.}}
|ru= [[Индонезийский]]
|sr= [[индонески]], [[Индонески]], [[Индонежански]]
|sk= [[Indonézsky]]
|sl= [[Indonezijščina]]
|es= [[indonesio]] {{kk.}}
|sw= [[Kiindonesia]]
|sv= [[indonesiska]]
|tl= [[Indones]]
|ta= [[இந்தோனீசியன்]]
|tt= [[Индонезия]]
|th= [[ภาษาอินโดนีเซีย]]
|tr= [[Endonezce]]
|uk= [[Індонезійський]]
|ur= [[انڈونيثيائي]]
|vi= [[Tiếng In-đô-nê-xi-a]]
|wa= [[Indonezyin]]
|cy= [[Indonesieg]]
}}
{{-tilvísun-}}
{{Wikipedia|indónesíska}}
9z5l4xxo7pbhbs1nn3cbbqsc9j98ywt
394147
394146
2026-10-12T20:31:36Z
~2026-54721-68
9780
394147
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|indónesísk}}
'''indónesíska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Indónesíu]]
{{-þýðingar-}}
{{þýðingar
|af= [[Indonesies]]
|sq= [[Indonezian]]
|am= [[እንዶኒሲኛ]]
|ar= [[إندونيسية]]
|hy= [[Ինդոնէզիան]]
|az= [[Индонезија]]
|eu= [[Indonesiera]]
|be= [[Інданэзійская]]
|bg= [[Индонезийски]]
|ca= [[indonesi]] {{kk.}}
|chr= [[ᎢᏅᏙᏂᏥ]]
|zh= [[印尼语]] or [[印度尼西亚语]]
|hr= [[Indonezijski]]
|cs= [[Indonéský]]
|da= [[Indonesisk]]
|en= [[Indonesian]]
|et= [[Indoneesia]]
|fo= [[Indonesiskt]]
|fa= [[اندونزى]]
|fi= [[indonesia]]
|fr= [[indonésien]] {{kk.}}
|fy= [[Yndonesysk]]
|ka= [[ინდონეზიური]]
|de= [[Indonesisch]] {{hk.}}
|el= [[Ινδονησιακά]]
|gu= [[ઇન્ડોનેશિયન]]
|he= [[אינדונזית]] (In'do'ne'zit)
|hi= [[इंडोनीशियन]]
|hu= [[Indonéz]]
|id= [[bahasa Indonesia]]
|ga= [[Indinéisis]]
|it= [[indonesiano]]
|ja= [[インドネシア語]] (indoneshia-go)
|ko= [[인도네시아어]]
|ku= [[Indonêzî]]
|lv= [[Indonēziešu]]
|lt= [[Indoneziečių]], [[Indoneziškai]]
|ms= [[Bahasa Indonesia]]
|mt= [[Indoneżjan]]
|mdf= [[Индонезиень]]
|mn= [[Инднез]]
|nds= [[Indoneessch]]
|ne= [[इन्डोनेसियाली]]
|nl= [[Indonesisch]]
|no= [[Indonesisk]]
|oc= [[Indonesian]]
|pl= [[indonezyjski]]
|pt= [[Indonésio]]
|ro= [[indoneziană]] {{kvk.}}
|ru= [[Индонезийский]]
|sr= [[индонески]], [[Индонески]], [[Индонежански]]
|sk= [[Indonézsky]]
|sl= [[Indonezijščina]]
|es= [[indonesio]] {{kk.}}
|sw= [[Kiindonesia]]
|sv= [[indonesiska]]
|tl= [[Indones]]
|ta= [[இந்தோனீசியன்]]
|tt= [[Индонезия]]
|th= [[ภาษาอินโดนีเซีย]]
|tr= [[Endonezce]]
|uk= [[Індонезійський]]
|ur= [[انڈونيثيائي]]
|vi= [[Tiếng In-đô-nê-xi-a]]
|wa= [[Indonezyin]]
|cy= [[Indonesieg]]
}}
{{-tilvísun-}}
{{Wikipedia|indónesíska}}
9ycxjttgvhugafk2zyv0iri80lo8x74
katalónska
0
4835
394123
340910
2026-10-12T18:46:41Z
~2026-54721-68
9780
394123
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|katalónsk}}
'''katalónska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] [[tala|töluð]] á [[Katalóníu]]
{{-þýðingar-}}
{{þýðingar
|no= {{þýðing|no|katalansk}}
|en= {{þýðing|en|Catalan}}
|de= {{þýðing|de|Katalanisch}}
|es= {{þýðing|es|catalán}}
|ca= {{þýðing|ca|català}}
|fr= {{þýðing|fr|catalan}}
|nl= {{þýðing|nl|Catalaans}}
}}
{{-tilvísun-}}
{{Wikipedia|katalónska}}
3i3eh9z2r9i49dvmig8h0savhawy2bh
Laos
0
8016
394162
385845
2026-10-12T21:09:35Z
~2026-54721-68
9780
394162
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-örnefni-}}===
==={{-is-nafnorð-}}===
{{Fallbeyging hk vb örnefni|Laos}}
'''Laos''' {{hk.}}; {{no.v.b.}}
#land í suð-austur Asíu
{{-þýðingar-}}
{{þýðingar
|af= {{þýðing|af|Laos}}
|als= {{þýðing|als|Laos}}
|an= {{þýðing|an|Laos}}
|ar= {{þýðing|ar|لاوس}}
|arz= {{þýðing|arz|لاوس}}
|ast= {{þýðing|ast|Laos}}
|bat-smg= {{þýðing|bat-smg|Lauosos}}
|be= {{þýðing|be|Лаос}}
|be-x-old= {{þýðing|be-x-old|Лаос}}
|bg= {{þýðing|bg|Лаос}}
|bn= {{þýðing|bn|লাওস}}
|bo= {{þýðing|bo|ལ་འོ་གོ}}
|bpy= {{þýðing|bpy|লাওস}}
|br= {{þýðing|br|Laos}}
|bs= {{þýðing|bs|Laos}}
|ca= {{þýðing|ca|Laos}}
|ceb= {{þýðing|ceb|Laos}}
|crh= {{þýðing|crh|Laos}}
|cs= {{þýðing|cs|Laos}}
|csb= {{þýðing|csb|Laòs}}
|cv= {{þýðing|cv|Лаос}}
|cy= {{þýðing|cy|Laos}}
|da= {{þýðing|da|Laos}}
|de= {{þýðing|de|Laos}}
|diq= {{þýðing|diq|Laos}}
|dsb= {{þýðing|dsb|Laos}}
|el= {{þýðing|el|Λάος}}
|en= {{þýðing|en|Laos}}
|eo= {{þýðing|eo|Laoso}}
|es= {{þýðing|es|Laos}}
|et= {{þýðing|et|Laos}}
|eu= {{þýðing|eu|Laos}}
|fa= {{þýðing|fa|لائوس}}
|fi= {{þýðing|fi|Laos}}
|fr= {{þýðing|fr|Laos}}
|frp= {{þýðing|frp|Laos}}
|fy= {{þýðing|fy|Laos}}
|ga= {{þýðing|ga|Laos}}
|gan= {{þýðing|gan|老撾}}
|gd= {{þýðing|gd|Làthos}}
|gl= {{þýðing|gl|Laos}}
|gv= {{þýðing|gv|Yn Laos}}
|hak= {{þýðing|hak|Liàu-koet}}
|haw= {{þýðing|haw|Laosa}}
|he= {{þýðing|he|לאוס}}
|hi= {{þýðing|hi|लाओस}}
|hr= {{þýðing|hr|Laos}}
|hsb= {{þýðing|hsb|Laos}}
|ht= {{þýðing|ht|Laos}}
|hu= {{þýðing|hu|Laosz}}
|hy= {{þýðing|hy|Լաոս}} (Laos)
|id= {{þýðing|id|Laos}}
|ie= {{þýðing|ie|Laos}}
|ilo= {{þýðing|ilo|Laos}}
|io= {{þýðing|io|Laos}}
|it= {{þýðing|it|Laos}}
|ja= {{þýðing|ja|ラオス}} (raosu)
|jv= {{þýðing|jv|Laos}}
|ka= {{þýðing|ka|ლაოსი}}
|kk= {{þýðing|kk|Лаос}}
|km= {{þýðing|km|ឡាវ}}
|kn= {{þýðing|kn|ಲಾವೋಸ್}}
|ko= {{þýðing|ko|라오스}}
|ks= {{þýðing|ks|लाओस}}
|ku= {{þýðing|ku|Laos}}
|kv= {{þýðing|kv|Лаос}}
|kw= {{þýðing|kw|Pow Lao}}
|la= {{þýðing|la|Laotia}}, {{þýðing|la|Laonia}}
|lb= {{þýðing|lb|Laos}}
|li= {{þýðing|li|Laos}}
|lij= {{þýðing|lij|Laòs}}
|lmo= {{þýðing|lmo|Laos}}
|ln= {{þýðing|ln|Laos}}
|lo= {{þýðing|lo|ປະເທດລາວ}}, {{þýðing|lo|ລາວ}}
|lt= {{þýðing|lt|Laosas}}
|lv= {{þýðing|lv|Laosa}}
|mk= {{þýðing|mk|Лаос}}
|ml= {{þýðing|ml|ലാവോസ്}}
|mr= {{þýðing|mr|लाओस}}
|ms= {{þýðing|ms|Laos}}
|nah= {{þýðing|nah|Lao}}
|nap= {{þýðing|nap|Laos}}
|nds= {{þýðing|nds|Laos}}
|new= {{þýðing|new|लाओस}}
|nl= {{þýðing|nl|Laos}}
|nn= {{þýðing|nn|Laos}}
|no= {{þýðing|no|Laos}}
|nov= {{þýðing|nov|Laos}}
|oc= {{þýðing|oc|Laòs}}
|os= {{þýðing|os|Лаос}}
|pam= {{þýðing|pam|Laos}}
|pl= {{þýðing|pl|Laos}}
|pms= {{þýðing|pms|Làos}}
|ps= {{þýðing|ps|لاووس}}
|pt= {{þýðing|pt|Laos}}
|qu= {{þýðing|qu|Lawus}}
|ro= {{þýðing|ro|Laos}}
|ru= {{þýðing|ru|Лаос}}
|sa= {{þýðing|sa|लाओस}}
|sah= {{þýðing|sah|Лаос}}
|scn= {{þýðing|scn|Laos}}
|se= {{þýðing|se|Laos}}
|sh= {{þýðing|sh|Laos}}
|sk= {{þýðing|sk|Laos}}
|sl= {{þýðing|sl|Laos}}
|sq= {{þýðing|sq|Laosi}}
|sr= {{þýðing|sr|Лаос}}
|su= {{þýðing|su|Laos}}
|sv= {{þýðing|sv|Laos}}
|sw= {{þýðing|sw|Laos}}
|szl= {{þýðing|szl|Laos}}
|ta= {{þýðing|ta|லாவோஸ்}}
|te= {{þýðing|te|లావోస్}}
|tg= {{þýðing|tg|Лаос}}
|th= {{þýðing|th|ประเทศลาว}}, {{þýðing|th|ลาว}}
|tk= {{þýðing|tk|Laos}}
|tl= {{þýðing|tl|Laos}}
|tr= {{þýðing|tr|Laos}}
|udm= {{þýðing|udm|Лаос}}
|ug= {{þýðing|ug|لائوس}}
|uk= {{þýðing|uk|Лаос}}
|ur= {{þýðing|ur|لاؤس}}
|vi= {{þýðing|vi|Lào}}
|vo= {{þýðing|vo|Laoän}}
|war= {{þýðing|war|Laos}}
|wo= {{þýðing|wo|Réewum Lawos}}
|wuu= {{þýðing|wuu|老挝}}
|yue= {{þýðing|yue|寮國}}
|zh= {{þýðing|zh|老挝}} (Lǎowō)
|zh-min-nan= {{þýðing|zh-min-nan|Lao-kok}}
}}
{{-tilvísun-}}
{{Wikipedia|Laos}}
=={{-af-}}==
==={{-af-nafnorð-}}===
==={{-af-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|af:Laos|Laos}}
=={{-an-}}==
==={{-an-nafnorð-}}===
==={{-an-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|an:Laos|Laos}}
==={{-ast-}}===
=={{-ast-nafnorð-}}==
=={{-ast-örnefni-}}==
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|ast:Laos|Laos}}
=={{-eu-}}==
==={{-eu-nafnorð-}}===
==={{-eu-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|eu:Laos|Laos}}
{{-bs-}}
{{-bs-nafnorð-}}
{{-bs-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|bs:Laos|Laos}}
{{-br-}}
{{-br-nafnorð-}}
{{-br-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|br:Laos|Laos}}
{{-ceb-}}
{{-ceb-nafnorð-}}
{{-ceb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ceb:Laos|Laos}}
{{-da-}}
{{-da-nafnorð-}}
{{-da-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|da:Laos|Laos}}
{{-et-}}
{{-et-nafnorð-}}
{{-et-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|et:Laos|Laos}}
{{-en-}}
{{-en-nafnorð-}}
{{-en-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|en:Laos|Laos}}
{{-fi-}}
{{-fi-nafnorð-}}
{{-fi-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|fi:Laos|Laos}}
=={{-fo-}}==
==={{-fo-nafnorð-}}===
'''Laos''' {{hk.}}
#[[#íslenska|Laos]]
{{-framburður-|fo}}
*{{hljóðskrá|fo-Laos.ogg}}
{{-tilvísun-}}
*{{Wikipedia|fo:Laos|Laos}}
=={{-fr-}}==
==={{-fr-nafnorð-}}===
==={{-fr-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|fr:Laos|Laos}}
{{-fy-}}
{{-fy-nafnorð-}}
{{-fy-örnefni-}}
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|fy:Laos|Laos}}
{{-gl-}}
{{-gl-nafnorð-}}
{{-gl-örnefni-}}
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|gl:Laos|Laos}}
=={{-nl-}}==
==={{-nl-nafnorð-}}===
==={{-nl-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|nl:Laos|Laos}}
{{-id-}}
{{-id-nafnorð-}}
{{-id-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|id:Laos|Laos}}
{{-ie-}}
{{-ie-nafnorð-}}
{{-ie-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ie:Laos|Laos}}
{{-io-}}
{{-io-nafnorð-}}
{{-io-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|io:Laos|Laos}}
{{-ga-}}
{{-ga-nafnorð-}}
{{-ga-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ga:Laos|Laos}}
=={{-it-}}==
==={{-it-nafnorð-}}===
==={{-it-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|it:Laos|Laos}}
{{-jv-}}
{{-jv-nafnorð-}}
{{-jv-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|jv:Laos|Laos}}
=={{-ca-}}==
==={{-ca-nafnorð-}}===
==={{-ca-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|ca:Laos|Laos}}
{{-crh-}}
{{-crh-nafnorð-}}
{{-crh-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|crh:Laos|Laos}}
{{-hr-}}
{{-hr-nafnorð-}}
{{-hr-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|hr:Laos|Laos}}
{{-ku-}}
{{-ku-nafnorð-}}
{{-ku-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ku:Laos|Laos}}
{{-nds-}}
{{-nds-nafnorð-}}
{{-nds-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|nds:Laos|Laos}}
{{-li-}}
{{-li-nafnorð-}}
{{-li-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|li:Laos|Laos}}
{{-ln-}}
{{-ln-nafnorð-}}
{{-ln-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ln:Laos|Laos}}
{{-lb-}}
{{-lb-nafnorð-}}
{{-lb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|lb:Laos|Laos}}
{{-ms-}}
{{-ms-nafnorð-}}
{{-ms-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ms:Laos|Laos}}
=={{-no-}}==
==={{-no-nafnorð-}}===
==={{-no-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|no:Laos|Laos}}
=={{-nn-}}==
==={{-nn-nafnorð-}}===
==={{-nn-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|nn:Laos|Laos}}
{{-pt-}}
{{-pt-nafnorð-}}
{{-pt-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|pt:Laos|Laos}}
{{-pl-}}
{{-pl-nafnorð-}}
{{-pl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|pl:Laos|Laos}}
{{-ro-}}
{{-ro-nafnorð-}}
{{-ro-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ro:Laos|Laos}}
{{-se-}}
{{-se-nafnorð-}}
{{-se-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|se:Laos|Laos}}
{{-sh-}}
{{-sh-nafnorð-}}
{{-sh-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sh:Laos|Laos}}
{{-scn-}}
{{-scn-nafnorð-}}
{{-scn-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|scn:Laos|Laos}}
{{-sk-}}
{{-sk-nafnorð-}}
{{-sk-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sk:Laos|Laos}}
{{-sl-}}
{{-sl-nafnorð-}}
{{-sl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sl:Laos|Laos}}
{{-dsb-}}
{{-dsb-nafnorð-}}
{{-dsb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|dsb:Laos|Laos}}
{{-hsb-}}
{{-hsb-nafnorð-}}
{{-hsb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|hsb:Laos|Laos}}
=={{-es-}}==
==={{-es-nafnorð-}}===
==={{-es-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|es:Laos|Laos}}
{{-su-}}
{{-su-nafnorð-}}
{{-su-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|su:Laos|Laos}}
=={{-sv-}}==
==={{-sv-nafnorð-}}===
==={{-sv-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|sv:Laos|Laos}}
{{-sw-}}
{{-sw-nafnorð-}}
{{-sw-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sw:Laos|Laos}}
{{-tl-}}
{{-tl-nafnorð-}}
{{-tl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tl:Laos|Laos}}
{{-cs-}}
{{-cs-nafnorð-}}
{{-cs-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|cs:Laos|Laos}}
{{-tk-}}
{{-tk-nafnorð-}}
{{-tk-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tk:Laos|Laos}}
{{-tr-}}
{{-tr-nafnorð-}}
{{-tr-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tr:Laos|Laos}}
{{-cy-}}
{{-cy-nafnorð-}}
{{-cy-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|cy:Laos|Laos}}
{{-war-}}
{{-war-nafnorð-}}
{{-war-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|war:Laos|Laos}}
{{-diq-}}
{{-diq-nafnorð-}}
{{-diq-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|diq:Laos|Laos}}
=={{-de-}}==
==={{-de-nafnorð-}}===
==={{-de-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|de:Laos|Laos}}
49ozqhvglvgck8zp47p38ydcl093ae4
394163
394162
2026-10-12T21:12:08Z
~2026-54721-68
9780
394163
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-örnefni-}}===
==={{-is-nafnorð-}}===
{{Fallbeyging hk vb örnefni|Laos}}
'''Laos''' {{hk.}}; {{no.v.b.}}
#land í suð-austur Asíu
{{-þýðingar-}}
{{þýðingar
|af= {{þýðing|af|Laos}}
|als= {{þýðing|als|Laos}}
|an= {{þýðing|an|Laos}}
|ar= {{þýðing|ar|لاوس}}
|arz= {{þýðing|arz|لاوس}}
|ast= {{þýðing|ast|Laos}}
|bat-smg= {{þýðing|bat-smg|Lauosos}}
|be= {{þýðing|be|Лаос}}
|be-x-old= {{þýðing|be-x-old|Лаос}}
|bg= {{þýðing|bg|Лаос}}
|bn= {{þýðing|bn|লাওস}}
|bo= {{þýðing|bo|ལ་འོ་གོ}}
|bpy= {{þýðing|bpy|লাওস}}
|br= {{þýðing|br|Laos}}
|bs= {{þýðing|bs|Laos}}
|ca= {{þýðing|ca|Laos}}
|ceb= {{þýðing|ceb|Laos}}
|crh= {{þýðing|crh|Laos}}
|cs= {{þýðing|cs|Laos}}
|csb= {{þýðing|csb|Laòs}}
|cv= {{þýðing|cv|Лаос}}
|cy= {{þýðing|cy|Laos}}
|da= {{þýðing|da|Laos}}
|de= {{þýðing|de|Laos}}
|diq= {{þýðing|diq|Laos}}
|dsb= {{þýðing|dsb|Laos}}
|el= {{þýðing|el|Λάος}}
|en= {{þýðing|en|Laos}}
|eo= {{þýðing|eo|Laoso}}
|es= {{þýðing|es|Laos}}
|et= {{þýðing|et|Laos}}
|eu= {{þýðing|eu|Laos}}
|fa= {{þýðing|fa|لائوس}}
|fi= {{þýðing|fi|Laos}}
|fr= {{þýðing|fr|Laos}}
|frp= {{þýðing|frp|Laos}}
|fy= {{þýðing|fy|Laos}}
|ga= {{þýðing|ga|Laos}}
|gan= {{þýðing|gan|老撾}}
|gd= {{þýðing|gd|Làthos}}
|gl= {{þýðing|gl|Laos}}
|gv= {{þýðing|gv|Yn Laos}}
|hak= {{þýðing|hak|Liàu-koet}}
|haw= {{þýðing|haw|Laosa}}
|he= {{þýðing|he|לאוס}}
|hi= {{þýðing|hi|लाओस}}
|hr= {{þýðing|hr|Laos}}
|hsb= {{þýðing|hsb|Laos}}
|ht= {{þýðing|ht|Laos}}
|hu= {{þýðing|hu|Laosz}}
|hy= {{þýðing|hy|Լաոս}} (Laos)
|id= {{þýðing|id|Laos}}
|ie= {{þýðing|ie|Laos}}
|ilo= {{þýðing|ilo|Laos}}
|io= {{þýðing|io|Laos}}
|it= {{þýðing|it|Laos}}
|ja= {{þýðing|ja|ラオス}} (raosu)
|jv= {{þýðing|jv|Laos}}
|ka= {{þýðing|ka|ლაოსი}}
|kk= {{þýðing|kk|Лаос}}
|km= {{þýðing|km|ឡាវ}}
|kn= {{þýðing|kn|ಲಾವೋಸ್}}
|ko= {{þýðing|ko|라오스}}
|ks= {{þýðing|ks|लाओस}}
|ku= {{þýðing|ku|Laos}}
|kv= {{þýðing|kv|Лаос}}
|kw= {{þýðing|kw|Pow Lao}}
|la= {{þýðing|la|Laotia}}, {{þýðing|la|Laonia}}
|lb= {{þýðing|lb|Laos}}
|li= {{þýðing|li|Laos}}
|lij= {{þýðing|lij|Laòs}}
|lmo= {{þýðing|lmo|Laos}}
|ln= {{þýðing|ln|Laos}}
|lo= {{þýðing|lo|ປະເທດລາວ}}, {{þýðing|lo|ລາວ}}
|lt= {{þýðing|lt|Laosas}}
|lv= {{þýðing|lv|Laosa}}
|mk= {{þýðing|mk|Лаос}}
|ml= {{þýðing|ml|ലാവോസ്}}
|mr= {{þýðing|mr|लाओस}}
|ms= {{þýðing|ms|Laos}}
|nah= {{þýðing|nah|Lao}}
|nap= {{þýðing|nap|Laos}}
|nds= {{þýðing|nds|Laos}}
|new= {{þýðing|new|लाओस}}
|nl= {{þýðing|nl|Laos}}
|nn= {{þýðing|nn|Laos}}
|no= {{þýðing|no|Laos}}
|nov= {{þýðing|nov|Laos}}
|oc= {{þýðing|oc|Laòs}}
|os= {{þýðing|os|Лаос}}
|pam= {{þýðing|pam|Laos}}
|pl= {{þýðing|pl|Laos}}
|pms= {{þýðing|pms|Làos}}
|ps= {{þýðing|ps|لاووس}}
|pt= {{þýðing|pt|Laos}}
|qu= {{þýðing|qu|Lawus}}
|ro= {{þýðing|ro|Laos}}
|ru= {{þýðing|ru|Лаос}}
|sa= {{þýðing|sa|लाओस}}
|sah= {{þýðing|sah|Лаос}}
|scn= {{þýðing|scn|Laos}}
|se= {{þýðing|se|Laos}}
|sh= {{þýðing|sh|Laos}}
|sk= {{þýðing|sk|Laos}}
|sl= {{þýðing|sl|Laos}}
|sq= {{þýðing|sq|Laosi}}
|sr= {{þýðing|sr|Лаос}}
|su= {{þýðing|su|Laos}}
|sv= {{þýðing|sv|Laos}}
|sw= {{þýðing|sw|Laos}}
|szl= {{þýðing|szl|Laos}}
|ta= {{þýðing|ta|லாவோஸ்}}
|te= {{þýðing|te|లావోస్}}
|tg= {{þýðing|tg|Лаос}}
|th= {{þýðing|th|ประเทศลาว}}, {{þýðing|th|ลาว}}
|tk= {{þýðing|tk|Laos}}
|tl= {{þýðing|tl|Laos}}
|tr= {{þýðing|tr|Laos}}
|udm= {{þýðing|udm|Лаос}}
|ug= {{þýðing|ug|لائوس}}
|uk= {{þýðing|uk|Лаос}}
|ur= {{þýðing|ur|لاؤس}}
|vi= {{þýðing|vi|Lào}}
|vo= {{þýðing|vo|Laoän}}
|war= {{þýðing|war|Laos}}
|wo= {{þýðing|wo|Réewum Lawos}}
|wuu= {{þýðing|wuu|老挝}}
|yue= {{þýðing|yue|寮國}}
|zh= {{þýðing|zh|老挝}} (Lǎowō)
|zh-min-nan= {{þýðing|zh-min-nan|Lao-kok}}
}}
{{-tilvísun-}}
{{Wikipedia|Laos}}
=={{-af-}}==
==={{-af-nafnorð-}}===
==={{-af-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|af:Laos|Laos}}
=={{-an-}}==
==={{-an-nafnorð-}}===
==={{-an-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|an:Laos|Laos}}
==={{-ast-}}===
=={{-ast-nafnorð-}}==
=={{-ast-örnefni-}}==
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|ast:Laos|Laos}}
=={{-eu-}}==
==={{-eu-nafnorð-}}===
==={{-eu-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|eu:Laos|Laos}}
{{-bs-}}
{{-bs-nafnorð-}}
{{-bs-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|bs:Laos|Laos}}
{{-br-}}
{{-br-nafnorð-}}
{{-br-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|br:Laos|Laos}}
{{-ceb-}}
{{-ceb-nafnorð-}}
{{-ceb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ceb:Laos|Laos}}
=={{-da-}}==
==={{-da-nafnorð-}}===
==={{-da-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|da:Laos|Laos}}
{{-et-}}
{{-et-nafnorð-}}
{{-et-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|et:Laos|Laos}}
=={{-en-}}==
==={{-en-nafnorð-}}===
==={{-en-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|en:Laos|Laos}}
{{-fi-}}
{{-fi-nafnorð-}}
{{-fi-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|fi:Laos|Laos}}
=={{-fo-}}==
==={{-fo-nafnorð-}}===
'''Laos''' {{hk.}}
#[[#íslenska|Laos]]
{{-framburður-|fo}}
*{{hljóðskrá|fo-Laos.ogg}}
{{-tilvísun-}}
*{{Wikipedia|fo:Laos|Laos}}
=={{-fr-}}==
==={{-fr-nafnorð-}}===
==={{-fr-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|fr:Laos|Laos}}
{{-fy-}}
{{-fy-nafnorð-}}
{{-fy-örnefni-}}
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|fy:Laos|Laos}}
{{-gl-}}
{{-gl-nafnorð-}}
{{-gl-örnefni-}}
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|gl:Laos|Laos}}
=={{-nl-}}==
==={{-nl-nafnorð-}}===
==={{-nl-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|nl:Laos|Laos}}
{{-id-}}
{{-id-nafnorð-}}
{{-id-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|id:Laos|Laos}}
{{-ie-}}
{{-ie-nafnorð-}}
{{-ie-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ie:Laos|Laos}}
{{-io-}}
{{-io-nafnorð-}}
{{-io-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|io:Laos|Laos}}
{{-ga-}}
{{-ga-nafnorð-}}
{{-ga-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ga:Laos|Laos}}
=={{-it-}}==
==={{-it-nafnorð-}}===
==={{-it-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|it:Laos|Laos}}
{{-jv-}}
{{-jv-nafnorð-}}
{{-jv-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|jv:Laos|Laos}}
=={{-ca-}}==
==={{-ca-nafnorð-}}===
==={{-ca-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|ca:Laos|Laos}}
{{-crh-}}
{{-crh-nafnorð-}}
{{-crh-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|crh:Laos|Laos}}
{{-hr-}}
{{-hr-nafnorð-}}
{{-hr-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|hr:Laos|Laos}}
{{-ku-}}
{{-ku-nafnorð-}}
{{-ku-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ku:Laos|Laos}}
{{-nds-}}
{{-nds-nafnorð-}}
{{-nds-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|nds:Laos|Laos}}
{{-li-}}
{{-li-nafnorð-}}
{{-li-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|li:Laos|Laos}}
{{-ln-}}
{{-ln-nafnorð-}}
{{-ln-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ln:Laos|Laos}}
{{-lb-}}
{{-lb-nafnorð-}}
{{-lb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|lb:Laos|Laos}}
{{-ms-}}
{{-ms-nafnorð-}}
{{-ms-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ms:Laos|Laos}}
=={{-no-}}==
==={{-no-nafnorð-}}===
==={{-no-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|no:Laos|Laos}}
=={{-nn-}}==
==={{-nn-nafnorð-}}===
==={{-nn-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|nn:Laos|Laos}}
{{-pt-}}
{{-pt-nafnorð-}}
{{-pt-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|pt:Laos|Laos}}
{{-pl-}}
{{-pl-nafnorð-}}
{{-pl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|pl:Laos|Laos}}
{{-ro-}}
{{-ro-nafnorð-}}
{{-ro-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|ro:Laos|Laos}}
{{-se-}}
{{-se-nafnorð-}}
{{-se-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|se:Laos|Laos}}
{{-sh-}}
{{-sh-nafnorð-}}
{{-sh-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sh:Laos|Laos}}
{{-scn-}}
{{-scn-nafnorð-}}
{{-scn-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|scn:Laos|Laos}}
{{-sk-}}
{{-sk-nafnorð-}}
{{-sk-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sk:Laos|Laos}}
{{-sl-}}
{{-sl-nafnorð-}}
{{-sl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sl:Laos|Laos}}
{{-dsb-}}
{{-dsb-nafnorð-}}
{{-dsb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|dsb:Laos|Laos}}
{{-hsb-}}
{{-hsb-nafnorð-}}
{{-hsb-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|hsb:Laos|Laos}}
=={{-es-}}==
==={{-es-nafnorð-}}===
==={{-es-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|es:Laos|Laos}}
{{-su-}}
{{-su-nafnorð-}}
{{-su-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|su:Laos|Laos}}
=={{-sv-}}==
==={{-sv-nafnorð-}}===
==={{-sv-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|sv:Laos|Laos}}
{{-sw-}}
{{-sw-nafnorð-}}
{{-sw-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|sw:Laos|Laos}}
{{-tl-}}
{{-tl-nafnorð-}}
{{-tl-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tl:Laos|Laos}}
{{-cs-}}
{{-cs-nafnorð-}}
{{-cs-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|cs:Laos|Laos}}
{{-tk-}}
{{-tk-nafnorð-}}
{{-tk-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tk:Laos|Laos}}
{{-tr-}}
{{-tr-nafnorð-}}
{{-tr-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|tr:Laos|Laos}}
{{-cy-}}
{{-cy-nafnorð-}}
{{-cy-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|cy:Laos|Laos}}
{{-war-}}
{{-war-nafnorð-}}
{{-war-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|war:Laos|Laos}}
{{-diq-}}
{{-diq-nafnorð-}}
{{-diq-örnefni-}}
'''Laos'''
:[[#Isländska|Laos]]
{{-tilvísun-}}
{{Wikipedia|diq:Laos|Laos}}
=={{-de-}}==
==={{-de-nafnorð-}}===
==={{-de-örnefni-}}===
'''Laos'''
#[[#Isländska|Laos]]
{{-tilvísun-}}
*{{Wikipedia|de:Laos|Laos}}
p5zc9ne8whii1md2167g74snwwm626k
astúríska
0
12409
394129
332546
2026-10-12T18:52:13Z
~2026-54721-68
9780
394129
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
{{Fallbeyging kvk vb 01 et|astúrísk}}
'''astúríska''' {{kvk.}}; {{no.v.b.}}
#[[tungumál]] í [[Astúría]]
{{-þýðingar-}}
{{þýðingar
|ast= {{þýðing|ast|asturianu}}
|en= {{þýðing|en|Asturian}}
|nl= {{þýðing|nl|Asturisch}}
|es= {{þýðing|es|asturiano}}
|de= {{þýðing|de|Asturisch}}
}}
{{-tilvísun-}}
{{Wikipedia|astúríska}}
jc1e4blhqrwp7zhmfgjn1znmrc9gwfd
laó
0
12552
394161
110424
2026-10-12T20:58:53Z
~2026-54721-68
9780
394161
wikitext
text/x-wiki
=={{-is-}}==
{{Stubbur}}
==={{-is-nafnorð-}}===
'''laó'''
#[[tungumál]] í [[Laos]]
{{-þýðingar-}}
{{þýðingar|sjá [[laoska]]}}
{{-tilvísun-}}
{{Wikipedia|laó}}
bew48iotdbha74sya2t57rtegax2lzx
mandarín
0
12573
394141
258876
2026-10-12T20:24:27Z
~2026-54721-68
9780
394141
wikitext
text/x-wiki
{{-is-}}
{{Stubbur}}
{{-is-nafnorð-}}
'''mandarín'''
#[[tungumál]] í [[Kína]]
{{-þýðingar-}}
{{þýðingar
|da= {{þýðing|da|mandarin}}
|en= {{þýðing|en|Mandarin}}
|de= {{þýðing|de|Mandarin}}
}}
{{-tilvísun-}}
*{{Wikipedia|mandarín}}
gma8uiuqlenam7yq1e5r9hg2f4xf4kl
394142
394141
2026-10-12T20:25:00Z
~2026-54721-68
9780
394142
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
'''mandarín'''
#[[tungumál]] í [[Kína]]
{{-þýðingar-}}
{{þýðingar
|da= {{þýðing|da|mandarin}}
|en= {{þýðing|en|Mandarin}}
|de= {{þýðing|de|Mandarin}}
}}
{{-tilvísun-}}
*{{Wikipedia|mandarín}}
i9ubhat4anndt90u5sqgnaui4v5k411
Melding:Gadgets-definition
8
17935
394116
393901
2026-10-12T17:52:37Z
Ladsgroup
3199
Remove deprecated option ([[phab:T298199]])
394116
wikitext
text/x-wiki
== skil ==
* UTCLiveClock[dependencies=mediawiki.util]|UTCLiveClock.js
* LiveClock[dependencies=mediawiki.util]|LiveClock.js
* contribsrange|contribsrange.js
* Palette [hidden |default] |Palette.css
* PagePreviews[default|dependencies=site,mediawiki.api,mediawiki.util,mediawiki.Title|skins=vector,vector-2022,monobook,timeless,modern,cologneblue]|PagePreviews.js
<!--
== admin-gadgets ==
* EnhancedUndelete|EnhancedUndelete.js
-->
ai3lt9cieh5b45hu7adbia9xjg5l64h
Rumänisch
0
44159
394132
384523
2026-10-12T18:54:35Z
~2026-54721-68
9780
394132
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Rumänisch''' {{hvk.}}
#[[rúmenska]]
{{-orðsifjafræði-}}
*{{orðhlutar|Ru|mä|nisch}}
{{-framburður-|de}}
*{{IPA|[ʁuˈmɛːnɪʃ]}}
*{{hljóðskrá|De-Rumänisch2.ogg}}
*{{hljóðskrá|De-Rumänisch.ogg}}
jqwr81iwnjzjo9q8gqp2d1ywjznphov
Bulgarisch
0
44160
394131
339201
2026-10-12T18:53:54Z
~2026-54721-68
9780
394131
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Bulgarisch''' {{hvk.}}
#[[búlgarska]]; [[tungumál]] [[tala|töluð]] í [[Búlgaríu]]
{{-orðsifjafræði-}}
*{{orðhlutar|Bul|ga|risch}}
{{-framburður-|de}}
*{{hljóðskrá|De-Bulgarisch.ogg}}
{{-tilvísun-}}
*{{Wikipedia|de:Bulgarisch|Bulgarisch}}
t9w0fetljyq2wphmh8w38ftwmxi4b5n
Koreanisch
0
44241
394149
288501
2026-10-12T20:40:31Z
~2026-54721-68
9780
394149
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Koreanisch''' {{hvk.}}
#[[kóreska]]
==={{-framburður-|de}}===
*{{hljóðskrá|De-Koreanisch.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|de:Koreanisch|Koreanisch}}
*{{Ref-Duden|Koreanisch}}
*{{til:de:DWDS|sótt=12. oktober 2026}}
hpwmzmol09kmen6v597c84hdymcw4t5
grönländisch
0
51992
394130
298260
2026-10-12T18:53:08Z
~2026-54721-68
9780
394130
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-lýsingarorð-}}===
'''grönländisch'''
#[[grænlenskur]]
n2hgb6dcuun66q8pqn99qbswjf1fzos
laotisch
0
52113
394160
298389
2026-10-12T20:55:33Z
~2026-54721-68
9780
394160
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-lýsingarorð-}}===
'''laotisch'''
#[[laoskur]]
8uablm1ho0ayfpekd0ic8a5t7pnw0gv
kambodschanisch
0
52114
394157
298390
2026-10-12T20:52:57Z
~2026-54721-68
9780
394157
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-lýsingarorð-}}===
'''kambodschanisch'''
#[[kambódískur]]
8cyszvk97qluko2leysosvg6b0370q1
japansk
0
64563
394138
336498
2026-10-12T20:15:40Z
~2026-54721-68
9780
394138
wikitext
text/x-wiki
=={{-da-}}==
==={{-da-lýsingarorð-}}===
'''japansk'''
#[[japanskur]]
=={{-no-}}==
==={{-no-lýsingarorð-}}===
'''japansk'''
#[[japanskur]]
=={{-nn-}}==
==={{-nn-lýsingarorð-}}===
'''japansk'''
#[[japanskur]]
atalhnffj036wix1nxpbdwa5j8ul085
vietnamesisk
0
64573
394155
336500
2026-10-12T20:48:23Z
~2026-54721-68
9780
394155
wikitext
text/x-wiki
=={{-da-}}==
==={{-da-lýsingarorð-}}===
'''vietnamesisk'''
#[[víetnamskur]]
=={{-no-}}==
==={{-no-lýsingarorð-}}===
'''vietnamesisk'''
#[[víetnamskur]]
=={{-no-}}==
==={{-no-nafnorð-}}===
'''vietnamesisk'''
#[[víetnamska]]
=={{-nn-}}==
==={{-nn-lýsingarorð-}}===
'''vietnamesisk'''
#[[vietnamskur]]
0z83u2zzpia8l9bzy3ger8ii37nrf3p
Belgisch
0
64780
394133
317220
2026-10-12T18:55:23Z
~2026-54721-68
9780
394133
wikitext
text/x-wiki
=={{-nl-}}==
==={{-nl-lýsingarorð-}}===
'''Belgisch'''
#[[belgískur]]
crnj5b6a9wjytngv448lz2n7wm6m3yn
europäisch
0
66896
394115
320163
2026-10-12T13:58:01Z
Jeuwre
5922
framburður
394115
wikitext
text/x-wiki
{{-de-}}
{{-de-lýsingarorð-}}
'''europäisch'''
:[[evrópskur]]
===={{-framburður-|de}}====
: {{IPA|[ɔɪ̯ʁoˈpɛːɪʃ]}}
: {{hljóðskrá|De-europäisch.ogg}}
: {{orðhlutar|eu|ro|pä|isch}}
rv5nbrn3ypjy24ewyjw1u3b0rp6kavp
mandarin
0
67340
394143
383943
2026-10-12T20:27:13Z
~2026-54721-68
9780
394143
wikitext
text/x-wiki
=={{-da-}}==
==={{-da-nafnorð-}}===
'''mandarin'''
#[[mandarín]]
{{-framburður-|fo}}
*{{hljóðskrá|fo-mandarin.ogg}}
=={{-fo-}}==
==={{-fo-nafnorð-}}===
'''mandarin'''
#[[mandarína]]; ''Citrus nobilis''
{{-framburður-|fo}}
*{{hljóðskrá|fo-mandarin.ogg}}
{{-tilvísun-}}
*{{Wikipedia|fo:mandarin|mandarin}}
*{{Ref-Sprotin|mandarin}}
{{-no-}}
==={{-no-nafnorð-}}===
'''mandarin''' {{kk.}}
#ávöxtur: [[mandarína]], ''Citrus reticulata''
r1fflumd9cndd03fk2ut8y5dfwewyqs
394144
394143
2026-10-12T20:27:34Z
~2026-54721-68
9780
394144
wikitext
text/x-wiki
=={{-da-}}==
==={{-da-nafnorð-}}===
'''mandarin'''
#[[mandarín]]
{{-framburður-|fo}}
*{{hljóðskrá|fo-mandarin.ogg}}
=={{-fo-}}==
==={{-fo-nafnorð-}}===
'''mandarin'''
#[[mandarína]]; ''Citrus nobilis''
{{-framburður-|fo}}
*{{hljóðskrá|fo-mandarin.ogg}}
{{-tilvísun-}}
*{{Wikipedia|fo:mandarin|mandarin}}
*{{Ref-Sprotin|mandarin}}
=={{-no-}}==
==={{-no-nafnorð-}}===
'''mandarin''' {{kk.}}
#ávöxtur: [[mandarína]], ''Citrus reticulata''
npsaukdg2lwy01o5r9fe85uaafe17vd
Asturisch
0
67619
394126
321383
2026-10-12T18:50:01Z
~2026-54721-68
9780
394126
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Asturisch''' {{hk.}}
#[[astúríska]]
{{-orðsifjafræði-}}
*{{orðhlutar|As|tu|risch}}
{{-framburður-|de}}
*{{hljóðskrá|De-Asturisch.ogg}}
=={{-nl-}}==
==={{-nl-nafnorð-}}===
'''Asturisch'''
#[[astúríska]]
nlf90n3q87igr5whpxut75m5ng572jc
asturiano
0
67620
394127
321384
2026-10-12T18:50:57Z
~2026-54721-68
9780
394127
wikitext
text/x-wiki
=={{-pt-}}==
==={{-pt-nafnorð-}}===
'''asturiano''' {{kk.}}
#[[astúríska]]
=={{-es-}}==
==={{-es-nafnorð-}}===
'''asturiano''' {{kk.}}
#[[astúríska]]
47srv6nealqazuyl4egqb0vv33ufdcb
aragonais
0
67625
394119
321391
2026-10-12T18:43:54Z
~2026-54721-68
9780
394119
wikitext
text/x-wiki
=={{-fr-}}==
==={{-fr-nafnorð-}}===
'''aragonais''' {{kk.}}
#[[aragónska]]
=={{-fr-}}==
==={{-fr-lýsingarorð-}}==
'''aragonais'''
#[[aragónska]]
nbw6fzu6oar9pridi9losryv9ys7hwt
394120
394119
2026-10-12T18:44:08Z
~2026-54721-68
9780
394120
wikitext
text/x-wiki
=={{-fr-}}==
==={{-fr-nafnorð-}}===
'''aragonais''' {{kk.}}
#[[aragónska]]
=={{-fr-}}==
==={{-fr-lýsingarorð-}}===
'''aragonais'''
#[[aragónska]]
8lul9l86tpgntnoegxr20pnecet4lef
aragonés
0
67626
394118
321392
2026-10-12T18:42:51Z
~2026-54721-68
9780
394118
wikitext
text/x-wiki
=={{-es-}}==
==={{-es-nafnorð-}}===
'''aragonés'''
#[[aragónska]]
55urryu404yzf5hrmkxmutdril443av
Asturian
0
73890
394128
332547
2026-10-12T18:51:28Z
~2026-54721-68
9780
394128
wikitext
text/x-wiki
=={{-en-}}==
==={{-en-nafnorð-}}===
'''Asturian'''
#[[astúríska]]
99aohnkd40y57bhxrymm4y0w8kcjfq1
catalán
0
78158
394122
339122
2026-10-12T18:45:38Z
~2026-54721-68
9780
394122
wikitext
text/x-wiki
=={{-es-}}==
==={{-es-nafnorð-}}===
'''catalán'''
#[[katalónska]]
j071zjlvpv6pzlxnf3ni48v3bfxupci
Katalanisch
0
78159
394121
339182
2026-10-12T18:45:05Z
~2026-54721-68
9780
394121
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Katalanisch''' {{hk.}}
#[[katalónska]]
{{-orðsifjafræði-}}
*{{orðhlutar|Ka|ta|la|nisch}}
{{-framburður-|de}}
*{{hljóðskrá|De-Katalanisch.ogg}}
{{-tilvísun-}}
*{{Wikipedia|de:Katalanisch|Katalanisch}}
bzx5h3m5eglzpobldf3ipklnnaawf8k
katalansk
0
78211
394124
339184
2026-10-12T18:48:07Z
~2026-54721-68
9780
394124
wikitext
text/x-wiki
=={{-no-}}==
==={{-no-nafnorð-}}===
'''katalansk'''
#[[tungumál]] [[tala|töluð]] á [[Katalóníu]]
=={{-no-}}==
==={{-no-lýsingarorð-}}===
'''katalansk'''
#[[katalónskur]]
0vp7ccha9gbg6bp2rc799s3ul3merps
katalónskur
0
78212
394125
339185
2026-10-12T18:48:36Z
~2026-54721-68
9780
394125
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-lýsingarorð-}}===
'''katalónskur'''
#[[katalansk]]
tfr3e353yqq6mq6rtsaljt8v92pbg6n
Vietnamesisch
0
86566
394152
349969
2026-10-12T20:45:02Z
~2026-54721-68
9780
394152
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Vietnamesisch''' {{hk.}}
#[[víetnamska]]
bh9eoh0humy4n4zgaoai36of8i69c09
mandrin
0
95476
394139
360847
2026-10-12T20:18:27Z
~2026-54721-68
9780
394139
wikitext
text/x-wiki
=={{-fr-}}==
==={{-fr-nafnorð-}}===
'''mandrin''' {{kk.}}
#[[patróna]]
8gbic3zldondcpmv2bfgylkb8imjp26
Mandarin
0
97077
394140
362787
2026-10-12T20:21:00Z
~2026-54721-68
9780
394140
wikitext
text/x-wiki
=={{-en-}}==
==={{-en-nafnorð-}}===
'''Mandarin'''
#[[mandarín]]
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Mandarin''' {{hk.}}
#[[mandarín]]
==={{-framburður-|de}}===
*{{hljóðskrá|De-Mandarin.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|de:Mandarin|Mandarin}}
*{{Ref-Duden|Mandarin}}
*{{til:de:DWDS|sótt=12. oktober 2026}}
knicb948l4oghr2z71hii4btp776h3w
kambódískur
0
104090
394158
385009
2026-10-12T20:53:54Z
~2026-54721-68
9780
394158
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-lýsingarorð-}}===
'''kambódískur'''
#sem [[tilheyrir]] [[Kambódíu]], kemur frá Kambódíu
#á tungumálið [[kambódíska]] almennilegur
{{-þýðingar-}}
{{þýðingar
|en= {{þýðing|en|}}
|fo= {{þýðing|fo|kambodiskur}}
|sv= {{þýðing|sv|}}
|de= {{þýðing|de|kambodschanisch}}
}}
{{-tilvísun-}}
{{Ref-IcelandicOnlineDictionary|kambódískur}}
{{Ref-Orðabók Háskólans|kambódískur}}
rm0vnc0exfutrgwadpstwip2ov4of49
394159
394158
2026-10-12T20:54:09Z
~2026-54721-68
9780
394159
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-lýsingarorð-}}===
'''kambódískur'''
#sem [[tilheyrir]] [[Kambódíu]], kemur frá Kambódíu
#á tungumálið [[kambódíska]] almennilegur
{{-þýðingar-}}
{{þýðingar
|en= {{þýðing|en|}}
|fo= {{þýðing|fo|kambodiskur}}
|sv= {{þýðing|sv|}}
|de= {{þýðing|de|kambodschanisch}}
}}
{{-tilvísun-}}
*{{Ref-IcelandicOnlineDictionary|kambódískur}}
*{{Ref-Orðabók Háskólans|kambódískur}}
kescf5brcbpwvg4cgqdqgl7hq655eeu
Khmer
0
106085
394156
374558
2026-10-12T20:51:58Z
~2026-54721-68
9780
394156
wikitext
text/x-wiki
=={{-nl-}}==
==={{-nl-nafnorð-}}===
'''Khmer'''
#[[kambódíska]], [[kmeríska]]
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Khmer'''
#[[kambódíska]], [[kmeríska]]
==={{-orðsifjafræði-}}===
*{{orðhlutar|Khmer}}
==={{-framburður-|de}}===
*{{hljóðskrá|De-Khmer.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|de:Khmer|Khmer}}
*{{Ref-Duden|Khmer}}
*{{til:de:DWDS|sótt=12. oktober 2026}}
2jqdzyc7slv1gu2gt99ktyk54yas6s3
Module:string utilities
828
114965
394113
386703
2026-10-12T13:23:02Z
Ow! That Hurts!
8952
394113
Scribunto
text/plain
local export = {}
local function_module = "Module:fun"
local load_module = "Module:load"
local memoize_module = "Module:memoize"
local string_char_module = "Module:string/char"
local string_charset_escape_module = "Module:string/charsetEscape"
local mw = mw
local string = string
local table = table
local ustring = mw.ustring
local byte = string.byte
local char = string.char
local concat = table.concat
local find = string.find
local format = string.format
local gmatch = string.gmatch
local gsub = string.gsub
local insert = table.insert
local len = string.len
local lower = string.lower
local match = string.match
local next = next
local require = require
local reverse = string.reverse
local select = select
local sort = table.sort
local sub = string.sub
local tonumber = tonumber
local tostring = tostring
local type = type
local ucodepoint = ustring.codepoint
local ufind = ustring.find
local ugcodepoint = ustring.gcodepoint
local ugmatch = ustring.gmatch
local ugsub = ustring.gsub
local ulower = ustring.lower
local umatch = ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local upper = string.upper
local usub = ustring.sub
local uupper = ustring.upper
local memoize = require(memoize_module)
-- Defined below.
local codepoint
local explode_utf8
local format_fun
local get_charset
local gsplit
local pattern_escape
local pattern_simplifier
local replacement_escape
local title_case
local trim
local ucfirst
local ulen
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures
modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no
overhead after the first call, since the target functions are called directly in any subsequent calls.
]==]
local function charset_escape(...)
charset_escape = require(string_charset_escape_module)
return charset_escape(...)
end
local function is_callable(...)
is_callable = require(function_module).is_callable
return is_callable(...)
end
local function load_data(...)
load_data = require(load_module).load_data
return load_data(...)
end
local function u(...)
u = require(strengur_char_module)
return u(...)
end
local function prepare_iter(str, pattern, str_lib, plain)
local callable = is_callable(pattern)
if str_lib or plain then
return pattern, #str, string, callable
elseif not callable then
local simple = pattern_simplifier(pattern)
if simple then
return simple, #str, string, false
end
end
return pattern, ulen(str), ustring, callable
end
--[==[
Returns {nil} if the input value is the empty string, or otherwise the same value.
If the input is a string and `do_trim` is set, the input value will be trimmed before returning; if the trimmed value is
the empty string, returns {nil}.
If `quote_delimiters` is set, then any outer pair of quotation marks ({' '} or {" "}) surrounding the rest of the input
string will be stripped, if present. The string will not be trimmed again, converted to {nil}, or have further quotation
marks stripped, as it exists as a way to embed spaces or the empty string in an input. Genuine quotation marks may also
be embedded this way (e.g. {"''foo''"} returns {"'foo'"}).
]==]
function export.is_not_empty(str, do_trim, quote_delimiters)
if str == "" then
return nil
elseif not (str and type(str) == "string") then
return str
elseif do_trim then
str = trim(str)
if str == "" then
return nil
end
end
return quote_delimiters and gsub(str, "^(['\"])(.*)%1$", "%2") or str
end
--[==[
Explodes a string into an array of UTF-8 characters. '''Warning''': this function assumes that the input is valid UTF-8
in order to optimize speed and memory use. Passing in an input containing non-UTF-8 byte sequences could result in
unexpected behaviour.
]==]
function export.explode_utf8(str)
local text, i = {}, 0
for ch in gmatch(str, ".[\128-\191]*") do
i = i + 1
text[i] = ch
end
return text
end
explode_utf8 = export.explode_utf8
--[==[
Returns {true} if `str` is a valid UTF-8 string. This is true if, for each character, all of the following are true:
* It has the expected number of bytes, which is determined by value of the leading byte: 1-byte characters are `0x00` to
`0x7F`, 2-byte characters start with `0xC2` to `0xDF`, 3-byte characters start with `0xE0` to `0xEF`, and 4-byte
characters start with `0xF0` to `0xF4`.
* The leading byte must not fall outside of the above ranges.
* The trailing byte(s) (if any), must be between `0x80` to `0xBF`.
* The character's codepoint must be between U+0000 (`0x00`) and U+10FFFF (`0xF4 0x8F 0xBF 0xBF`).
* The character cannot have an overlong encoding: for each byte length, the lowest theoretical encoding is equivalent to
U+0000 (e.g. `0xE0 0x80 0x80`, the lowest theoretical 3-byte encoding, is exactly equivalent to U+0000). Encodings
that use more than the minimum number of bytes are not considered valid, meaning that the first valid 3-byte
character is `0xE0 0xA0 0x80` (U+0800), and the first valid 4-byte character is `0xF0 0x90 0x80 0x80` (U+10000).
Formally, 2-byte characters have leading bytes ranging from `0xC0` to `0xDF` (rather than `0xC2` to `0xDF`), but
`0xC0 0x80` to `0xC1 0xBF` are overlong encodings, so it is simpler to say that the 2-byte range begins at `0xC2`.
If `allow_surrogates` is set, surrogates (U+D800 to U+DFFF) will be treated as valid UTF-8. Surrogates are used in
UTF-16, which encodes codepoints U+0000 to U+FFFF with 2 bytes, and codepoints from U+10000 upwards using a pair of
surrogates, which are taken together as a 4-byte unit. Since surrogates have no use in UTF-8, as it encodes higher
codepoints in a different way, they are not considered valid in UTF-8 text. However, there are limited circumstances
where they may be necessary: for instance, JSON escapes characters using the format `\u0000`, which must contain exactly
4 hexadecimal digits; under the scheme, codepoints above U+FFFF must be escaped as the equivalent pair of surrogates,
even though the text itself must be encoded in UTF-8 (e.g. U+10000 becomes `\uD800\uDC00`).
]==]
function export.isutf8(str, allow_surrogates)
for ch in gmatch(str, "[\128-\255][\128-\191]*") do
if #ch > 4 then
return false
end
local b1, b2, b3, b4 = byte(ch, 1, 4)
if not (b2 and b2 >= 0x80 and b2 <= 0xBF) then
return false -- 1-byte is always invalid, as gmatch excludes 0x00 to 0x7F
elseif not b3 then -- 2-byte
if not (b1 >= 0xC2 and b1 <= 0xDF) then -- b1 == 0xC0 or b1 == 0xC1 is overlong
return false
end
elseif not (b3 >= 0x80 and b3 <= 0xBF) then -- trailing byte
return false
elseif not b4 then -- 3-byte
if b1 > 0xEF then
return false
elseif b2 < 0xA0 then
if b1 < 0xE1 then -- b1 == 0xE0 and b2 < 0xA0 is overlong
return false
end
elseif b1 < 0xE0 or (b1 == 0xED and not allow_surrogates) then -- b1 == 0xED and b2 >= 0xA0 is a surrogate
return false
end
elseif not (b4 >= 0x80 and b4 <= 0xBF) then -- 4-byte
return false
elseif b2 < 0x90 then
if not (b1 >= 0xF1 and b1 <= 0xF4) then -- b1 == 0xF0 and b2 < 0x90 is overlong
return false
end
elseif not (b1 >= 0xF0 and b1 <= 0xF3) then -- b1 == 0xF4 and b2 >= 0x90 is too high
return false
end
end
return true
end
do
local charset_chars = {
["\0"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^"
}
charset_chars.__index = charset_chars
local chars = setmetatable({
["$"] = "%$", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+",
["."] = "%.", ["?"] = "%?", ["["] = "%["
}, charset_chars)
--[==[
Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]] (Lua's
version of regular expressions): {$%()*+-.?[]^}, and converts the null character to {%z}. For example,
{"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving
arbitrary text (e.g. from user input).
]==]
function export.pattern_escape(str)
return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars))
end
pattern_escape = export.pattern_escape
--[==[
Escapes only {%}, which is the only magic character used in replacement
[[mw:Extension:Scribunto/Lua reference manual#Patterns|patterns]] with string.gsub and mw.ustring.gsub.
]==]
function export.replacement_escape(str)
return (gsub(str, "%%", "%%%%"))
end
replacement_escape = export.replacement_escape
local function case_insensitive_char(ch)
local upper_ch = uupper(ch)
if upper_ch == ch then
ch = ulower(ch)
if ch == upper_ch then
return chars[ch] or ch
end
end
return "[" .. (charset_chars[upper_ch] or upper_ch) .. (charset_chars[ch] or ch) .. "]"
end
local function iterate(str, str_len, text, n, start, _gsub, _sub, loc1, loc2)
if not (loc1 and start <= str_len) then
-- Add final chunk and return.
n = n + 1
text[n] = _gsub(_sub(str, start), ".", chars)
return
elseif loc2 < loc1 then
if _sub == sub then
local b = byte(str, loc1)
if b and b >= 128 then
loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3)
end
end
n = n + 1
text[n] = _gsub(_sub(str, start, loc1), ".", chars)
start = loc1 + 1
if start > str_len then
return
end
else
-- Add chunk up to the current match.
n = n + 1
text[n] = _gsub(_sub(str, start, loc1 - 1), ".", chars)
-- Add current match.
n = n + 1
text[n] = _gsub(_sub(str, loc1, loc2), ".", case_insensitive_char)
start = loc2 + 1
end
return n, start
end
--[==[
Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]], and makes
all characters case-insensitive. An optional pattern or find function (see {split}) may be supplied as the second
argument, the third argument (`str_lib`) forces use of the string library, while the fourth argument (`plain`) turns
any pattern matching facilities off in the optional pattern supplied.
]==]
function export.case_insensitive_pattern(str, pattern_or_func, str_lib, plain)
if pattern_or_func == nil then
return (gsub(str, str_lib and "[^\128-\255]" or ".[\128-\191]*", case_insensitive_char))
end
local text, n, start, str_len, _string, callable = {}, 0, 1
pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain)
local _find, _gsub, _sub = _string.find, _string.gsub, _string.sub
if callable then
repeat
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, pattern_or_func(str, start))
until not start
-- Special case if the pattern is anchored to the start: "^" always
-- anchors to the start position, not the start of the string, so get
-- around this by only attempting one match with the pattern, then match
-- the end of the string.
elseif byte(pattern_or_func) == 0x5E then -- ^
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain))
if start ~= nil then
iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, "$", start, plain))
end
else
repeat
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain))
until not start
end
return concat(text)
end
end
do
local character_classes
local function get_character_classes()
character_classes, get_character_classes = {
[0x41] = true, [0x61] = true, -- Aa
[0x43] = true, [0x63] = true, -- Cc
[0x44] = true, [0x64] = true, -- Dd
[0x4C] = true, [0x6C] = true, -- Ll
[0x50] = true, [0x70] = true, -- Pp
[0x53] = true, [0x73] = true, -- Ss
[0x55] = true, [0x75] = true, -- Uu
[0x57] = true, [0x77] = true, -- Ww
[0x58] = true, [0x78] = true, -- Xx
[0x5A] = true, -- z dealt with separately.
}, nil
return character_classes
end
local function check_sets_equal(set1, set2)
local k2
for k1, v1 in next, set1 do
local v2 = set2[k1]
if v1 ~= v2 and (v2 == nil or not check_sets_equal(v1, v2)) then
return false
end
k2 = next(set2, k2)
end
return next(set2, k2) == nil
end
local function check_sets(bytes)
local key, set1, set = next(bytes)
if set1 == true then
return true
elseif not check_sets(set1) then
return false
end
while true do
key, set = next(bytes, key)
if not key then
return true
elseif not check_sets_equal(set, set1) then
return false
end
end
end
local function make_charset(range)
if #range == 1 then
return char(range[1])
end
sort(range)
local compressed, n, start = {}, 0, range[1]
for i = 1, #range do
local this, nxt = range[i], range[i + 1]
if nxt ~= this + 1 then
n = n + 1
compressed[n] = this == start and char(this) or
char(start) .. "-" .. char(this)
start = nxt
end
end
return "[" .. concat(compressed) .. "]"
end
local function parse_1_byte_charset(pattern, pos)
local ch
while true do
pos, ch = match(pattern, "()([%%%]\192-\255])", pos)
if ch == "%" then
local nxt = byte(pattern, pos + 1)
if not nxt or nxt >= 128 or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWXZ, but not z
return false
end
pos = pos + 2
elseif ch == "]" then
pos = pos + 1
return pos
else
return false
end
end
end
--[==[
Parses `pattern`, a ustring library pattern, and attempts to convert it into a string library pattern. If conversion
isn't possible, returns false.
]==]
function pattern_simplifier(pattern)
if type(pattern) == "number" then
return tostring(pattern)
end
local pos, capture_groups, start, n, output, ch, nxt_pos = 1, 0, 1, 0
while true do
-- FIXME: use "()([%%(.[\128-\255])[\128-\191]?[\128-\191]?[\128-\191]?()" and ensure non-UTF8 always fails.
pos, ch, nxt_pos = match(pattern, "()([%%(.[\192-\255])[\128-\191]*()", pos)
if not ch then
break
end
local nxt = byte(pattern, nxt_pos)
if ch == "%" then
if nxt == 0x62 then -- b
local nxt2, nxt3 = byte(pattern, pos + 2, pos + 3)
if not (nxt2 and nxt2 < 128 and nxt3 and nxt3 < 128) then
return false
end
pos = pos + 4
elseif nxt == 0x66 then -- f
nxt_pos = nxt_pos + 2
local nxt2, nxt3 = byte(pattern, nxt_pos - 1, nxt_pos)
-- Only possible to convert a positive %f charset which is
-- all ASCII, so use parse_1_byte_charset.
if not (nxt2 == 0x5B and nxt3 and nxt3 ~= 0x5E and nxt3 < 128) then -- [^
return false
elseif nxt3 == 0x5D then -- Initial ] is non-magic.
nxt_pos = nxt_pos + 1
end
pos = parse_1_byte_charset(pattern, nxt_pos)
if not pos then
return false
end
elseif nxt == 0x5A then -- Z
nxt = byte(pattern, nxt_pos + 1)
if nxt == 0x2A or nxt == 0x2D then -- *-
pos = pos + 3
else
if output == nil then
output = {}
end
local ins = sub(pattern, start, pos - 1) .. "[\1-\127\192-\255]"
n = n + 1
if nxt == 0x2B then -- +
output[n] = ins .. "%Z*"
pos = pos + 3
elseif nxt == 0x3F then -- ?
output[n] = ins .. "?[\128-\191]*"
pos = pos + 3
else
output[n] = ins .. "[\128-\191]*"
pos = pos + 2
end
start = pos
end
elseif not nxt or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWX, but not Zz
return false
-- Skip the next character if it's ASCII. Otherwise, we will
-- still need to do length checks.
else
pos = pos + (nxt < 128 and 2 or 1)
end
elseif ch == "(" then
if nxt == 0x29 or capture_groups == 32 then -- )
return false
end
capture_groups = capture_groups + 1
pos = pos + 1
elseif ch == "." then
if nxt == 0x2A or nxt == 0x2D then -- *-
pos = pos + 2
else
if output == nil then
output = {}
end
local ins = sub(pattern, start, pos - 1) .. "[^\128-\191]"
n = n + 1
if nxt == 0x2B then -- +
output[n] = ins .. ".*"
pos = pos + 2
elseif nxt == 0x3F then -- ?
output[n] = ins .. "?[\128-\191]*"
pos = pos + 2
else
output[n] = ins .. "[\128-\191]*"
pos = pos + 1
end
start = pos
end
elseif ch == "[" then
-- Fail negative charsets. TODO: 1-byte charsets should be safe.
if nxt == 0x5E then -- ^
return false
-- If the first character is "%", ch_len is determined by the
-- next one instead.
elseif nxt == 0x25 then -- %
nxt = byte(pattern, nxt_pos + 1)
elseif nxt == 0x5D then -- Initial ] is non-magic.
nxt_pos = nxt_pos + 1
end
if not nxt then
return false
end
local ch_len = nxt < 128 and 1 or nxt < 224 and 2 or nxt < 240 and 3 or 4
if ch_len == 1 then -- Single-byte charset.
pos = parse_1_byte_charset(pattern, nxt_pos)
if not pos then
return false
end
else -- Multibyte charset.
-- TODO: 1-byte chars should be safe to mix with multibyte chars. CONFIRM THIS FIRST.
local charset_pos, bytes = pos
pos = pos + 1
while true do -- TODO: non-ASCII charset ranges.
pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", pos)
-- If escaped, get the next character. No need to
-- distinguish magic characters or character classes,
-- as they'll all fail for having the wrong length
-- anyway.
if ch == "%" then
pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", nxt_pos)
elseif ch == "]" then
pos = nxt_pos
break
end
if not (ch and nxt_pos - pos == ch_len) then
return false
elseif bytes == nil then
bytes = {}
end
local bytes, last = bytes, nxt_pos - 1
for i = pos, last - 1 do
local b = byte(pattern, i)
local bytes_b = bytes[b]
if bytes_b == nil then
bytes_b = {}
bytes[b] = bytes_b
end
bytes[b], bytes = bytes_b, bytes_b
end
bytes[byte(pattern, last)] = true
pos = nxt_pos
end
if not pos then
return false
end
nxt = byte(pattern, pos)
if (
(nxt == 0x2A or nxt == 0x2D or nxt == 0x3F) or -- *-?
(nxt == 0x2B and ch_len > 2) or -- +
not check_sets(bytes)
) then
return false
end
local ranges, b, key, next_byte = {}, 0
repeat
key, next_byte = next(bytes)
local range, n = {key}, 1
-- Loop starts on the second iteration.
for key in next, bytes, key do
n = n + 1
range[n] = key
end
b = b + 1
ranges[b] = range
bytes = next_byte
until next_byte == true
if nxt == 0x2B then -- +
local range1, range2 = ranges[1], ranges[2]
ranges[1], ranges[3] = make_charset(range1), make_charset(range2)
local n = #range2
for i = 1, #range1 do
n = n + 1
range2[n] = range1[i]
end
ranges[2] = make_charset(range2) .. "*"
pos = pos + 1
else
for i = 1, #ranges do
ranges[i] = make_charset(ranges[i])
end
end
if output == nil then
output = {}
end
nxt = byte(pattern, pos)
n = n + 1
output[n] = sub(pattern, start, charset_pos - 1) .. concat(ranges) ..
((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped
start = pos
end
elseif not nxt then
break
elseif nxt == 0x2B then -- +
if nxt_pos - pos ~= 2 then
return false
elseif output == nil then
output = {}
end
pos, nxt_pos = pos + 1, nxt_pos + 1
nxt = byte(pattern, nxt_pos)
local ch2 = sub(pattern, pos, pos)
n = n + 1
output[n] = sub(pattern, start, pos - 1) .. "[" .. ch .. ch2 .. "]*" .. ch2 ..
((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped
pos, start = nxt_pos, nxt_pos
elseif nxt == 0x2A or nxt == 0x2D or nxt == 0x3F then -- *-?
return false
else
pos = nxt_pos
end
end
if start == 1 then
return pattern
end
return concat(output) .. sub(pattern, start)
end
pattern_simplifier = memoize(pattern_simplifier, true)
export.pattern_simplifier = pattern_simplifier
end
--[==[
Parses `charset`, the interior of a string or ustring library character set, and normalizes it into a string or ustring
library pattern (e.g. {"abcd-g"} becomes {"[abcd-g]"}, and {"[]"} becomes {"[[%]]"}).
The negative (`^`), range (`-`) and literal (`%`) magic characters work as normal, and character classes may be used
(e.g. `%d` and `%w`), but opening and closing square brackets are sanitized so that they behave like ordinary
characters.
]==]
function get_charset(charset)
if type(charset) == "number" then
return tostring(charset)
end
local pos, start, n, output = 1, 1, 0
if byte(charset) == 0x5E then -- ^
pos = pos + 1
end
-- FIXME: "]" is non-magic if it's the first character in a charset.
local nxt_pos, nxt
while true do
local new_pos, ch = match(charset, "()([%%%-%]])", pos)
if not ch then
break
-- Skip percent escapes. Ranges can't start with them, either.
elseif ch == "%" then
pos = new_pos + 2
else
-- If `ch` is a hyphen, get the character before iff it's at or ahead of `pos`.
if ch == "-" and new_pos > pos then
pos, nxt_pos, nxt = new_pos - 1, new_pos, ch
ch = sub(charset, pos, pos)
else
pos, nxt_pos = new_pos, new_pos + 1
nxt = sub(charset, nxt_pos, nxt_pos)
end
-- Range.
if nxt == "-" then
if output == nil then
output = {}
end
n = n + 1
output[n] = sub(charset, start, pos - 1)
nxt_pos = nxt_pos + 1
nxt = sub(charset, nxt_pos, nxt_pos)
-- Ranges fail if they end with a percent escape, so escape the hyphen to avoid undefined behaviour.
if nxt == "" or nxt == "%" then
n = n + 1
output[n] = (ch == "]" and "%]" or ch) .. "%-"
start = nxt_pos
nxt_pos = nxt_pos + 2
-- Since ranges can't contain "%]", since it's escaped, range inputs like "]-z" or "a-]" must be
-- adjusted to the character before or after, plus "%]" (e.g. "%]^-z" or "a-\\%]"). The escaped "%]" is
-- omitted if the range would be empty (i.e. if the first byte is greater than the second).
else
n = n + 1
output[n] = (ch == "]" and (byte(nxt) >= 0x5D and "%]^" or "^") or ch) .. "-" ..
(nxt == "]" and (byte(ch) <= 0x5D and "\\%]" or "\\") or nxt)
nxt_pos = nxt_pos + 1
start = nxt_pos
end
elseif ch == "-" or ch == "]" then
if output == nil then
output = {}
end
n = n + 1
output[n] = sub(charset, start, pos - 1) .. "%" .. ch
start = nxt_pos
end
pos = nxt_pos
end
end
if start == 1 then
return "[" .. charset .. "]"
end
return "[" .. concat(output) .. sub(charset, start) .. "]"
end
get_charset = memoize(get_charset, true)
export.get_charset = get_charset
function export.len(str)
return type(str) == "number" and len(str) or
#str - #gsub(str, "[^\128-\191]+", "")
end
ulen = export.len
function export.sub(str, i, j)
str, i = type(str) == "number" and tostring(str) or str, i or 1
if i < 0 or j and j < 0 then
return usub(str, i, j)
elseif j and i > j or i > #str then
return ""
end
local n, new_i = 0
for loc1, loc2 in gmatch(str, "()[^\128-\191]+()[\128-\191]*") do
n = n + loc2 - loc1
if not new_i and n >= i then
new_i = loc2 - (n - i) - 1
if not j then
return sub(str, new_i)
end
end
if j and n > j then
return sub(str, new_i, loc2 - (n - j) - 1)
end
end
return new_i and sub(str, new_i) or ""
end
do
local function _find(str, loc1, loc2, ...)
if loc1 and not match(str, "^()[^\128-\255]*$") then
-- Use raw values of loc1 and loc2 to get loc1 and the length of the match.
loc1, loc2 = ulen(sub(str, 1, loc1)), ulen(sub(str, loc1, loc2))
-- Offset length with loc1 to get loc2.
loc2 = loc1 + loc2 - 1
end
return loc1, loc2, ...
end
--[==[A version of find which uses string.find when possible, but otherwise uses mw.ustring.find.]==]
function export.find(str, pattern, init, plain)
init = init or 1
if init ~= 1 and not match(str, "^()[^\128-\255]*$") then
return ufind(str, pattern, init, plain)
elseif plain then
return _find(str, find(str, pattern, init, true))
end
local simple = pattern_simplifier(pattern)
if simple then
return _find(str, find(str, simple, init))
end
return ufind(str, pattern, init)
end
end
--[==[A version of match which uses string.match when possible, but otherwise uses mw.ustring.match.]==]
function export.match(str, pattern, init)
init = init or 1
if init ~= 1 and not match(str, "^()[^\128-\255]*$") then
return umatch(str, pattern, init)
end
local simple = pattern_simplifier(pattern)
if simple then
return match(str, simple, init)
end
return umatch(str, pattern, init)
end
--[==[A version of gmatch which uses string.gmatch when possible, but otherwise uses mw.ustring.gmatch.]==]
function export.gmatch(str, pattern)
local simple = pattern_simplifier(pattern)
if simple then
return gmatch(str, simple)
end
return ugmatch(str, pattern)
end
--[==[A version of gsub which uses string.gsub when possible, but otherwise uses mw.ustring.gsub.]==]
function export.gsub(str, pattern, repl, n)
local simple = pattern_simplifier(pattern)
if simple then
return gsub(str, simple, repl, n)
end
return ugsub(str, pattern, repl, n)
end
--[==[
Like gsub, but pattern-matching facilities are turned off, so `pattern` and `repl` (if a string) are treated as literal.
]==]
function export.plain_gsub(str, pattern, repl, n)
return gsub(str, pattern_escape(pattern), type(repl) == "string" and replacement_escape(repl) or repl, n)
end
--[==[
Reverses a UTF-8 string; equivalent to string.reverse.
]==]
function export.reverse(str)
return reverse((gsub(str, "[\192-\255][\128-\191]*", reverse)))
end
function export.char(...) -- To be moved to [[Module:string/char]].
return u(...)
end
do
local function utf8_err(func_name)
error(format("bad argument #1 to '%s' (string is not UTF-8)", func_name), 4)
end
local function get_codepoint(func_name, b1, b2, b3, b4)
if b1 <= 0x7F then
return b1, 1
elseif not (b2 and b2 >= 0x80 and b2 <= 0xBF) then
utf8_err(func_name)
elseif b1 <= 0xDF then
local cp = 0x40 * b1 + b2 - 0x3080
return cp >= 0x80 and cp or utf8_err(func_name), 2
elseif not (b3 and b3 >= 0x80 and b3 <= 0xBF) then
utf8_err(func_name)
elseif b1 <= 0xEF then
local cp = 0x1000 * b1 + 0x40 * b2 + b3 - 0xE2080
return cp >= 0x800 and cp or utf8_err(func_name), 3
elseif not (b4 and b4 >= 0x80 and b4 <= 0xBF) then
utf8_err(func_name)
end
local cp = 0x40000 * b1 + 0x1000 * b2 + 0x40 * b3 + b4 - 0x3C82080
return cp >= 0x10000 and cp <= 0x10FFFF and cp or utf8_err(func_name), 4
end
function export.codepoint(str, i, j)
if str == "" then
return -- return nothing
elseif type(str) == "number" then
return byte(str, i, j)
end
i, j = i or 1, j == -1 and #str or i or 1
if i == 1 and j == 1 then
return (get_codepoint("codepoint", byte(str, 1, 4)))
elseif i < 0 or j < 0 then
return ucodepoint(str, i, j) -- FIXME
end
local n, nb, ret, nr = 0, 1, {}, 0
while n < j do
n = n + 1
if n < i then
local b = byte(str, nb)
nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4)
else
local b1, b2, b3, b4 = byte(str, nb, nb + 3)
if not b1 then
break
end
nr = nr + 1
local add
ret[nr], add = get_codepoint("codepoint", b1, b2, b3, b4)
nb = nb + add
end
end
return unpack(ret)
end
codepoint = export.codepoint
function export.gcodepoint(str, i, j)
i, j = i or 1, j ~= -1 and j or nil
if i < 0 or j and j < 0 then
return ugcodepoint(str, i, j) -- FIXME
end
local n, nb = 1, 1
while n < i do
local b = byte(str, nb)
if not b then
break
end
nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4)
n = n + 1
end
return function()
if j and n > j then
return nil
end
n = n + 1
local b1, b2, b3, b4 = byte(str, nb, nb + 3)
if not b1 then
return nil
end
local ret, add = get_codepoint("gcodepoint", b1, b2, b3, b4)
nb = nb + add
return ret
end
end
end
do
local _ulower = ulower
--[==[A version of lower which uses string.lower when possible, but otherwise uses mw.ustring.lower.]==]
function export.lower(str)
return (match(str, "^()[^\128-\255]*$") and lower or _ulower)(str)
end
end
do
local _uupper = uupper
--[==[A version of upper which uses string.upper when possible, but otherwise uses mw.ustring.upper.]==]
function export.upper(str)
return (match(str, "^()[^\128-\255]*$") and upper or _uupper)(str)
end
end
do
local function add_captures(t, n, ...)
if ... == nil then
return
end
-- Insert any captures from the splitting pattern.
local offset, capture = n - 1, ...
while capture do
n = n + 1
t[n] = capture
capture = select(n - offset, ...)
end
return n
end
--[==[
Reimplementation of mw.text.split() that includes any capturing groups in the splitting pattern. This works like
Python's re.split() function, except that it has Lua's behavior when the split pattern is empty (i.e. advancing by
one character at a time; Python returns the whole remainder of the string). When possible, it will use the string
library, but otherwise uses the ustring library. There are two optional parameters: `str_lib` forces use of the
string library, while `plain` turns any pattern matching facilities off, treating `pattern` as literal.
In addition, `pattern` may be a custom find function (or callable table), which takes the input string and start
index as its two arguments, and must return the start and end index of the match, plus any optional captures, or nil
if there are no further matches. By default, the start index will be calculated using the ustring library, unless
`str_lib` or `plain` is set.
]==]
function export.split(str, pattern_or_func, str_lib, plain)
local iter, t, n = gsplit(str, pattern_or_func, str_lib, plain), {}, 0
repeat
n = add_captures(t, n, iter())
until n == nil
return t
end
export.capturing_split = export.split -- To be removed.
end
--[==[
Returns an iterator function, which iterates over the substrings returned by {split}. The first value returned is the
string up the splitting pattern, with any capture groups being returned as additional values on that iteration.
]==]
function export.gsplit(str, pattern_or_func, str_lib, plain)
local start, final, str_len, _string, callable = 1
pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain)
local _find, _sub = _string.find, _string.sub
local function iter(loc1, loc2, ...)
-- If no match, or there is but we're past the end of the string
-- (which happens when the match is the empty string), then return
-- the final chunk.
if not loc1 then
final = true
return _sub(str, start)
end
-- Special case: If we match the empty string, then eat the
-- next character; this avoids an infinite loop, and makes
-- splitting by the empty string work the way mw.text.gsplit() does
-- (including non-adjacent empty string matches with %f). If we
-- reach the end of the string this way, set `final` to true, so we
-- don't get stuck matching the empty string at the end.
local chunk
if loc2 < loc1 then
-- If using the string library, we need to make sure we advance
-- by one UTF-8 character.
if _sub == sub then
local b = byte(str, loc1)
if b and b >= 128 then
loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3)
end
end
chunk = _sub(str, start, loc1)
if loc1 >= str_len then
final = true
else
start = loc1 + 1
end
-- Eat chunk up to the current match.
else
chunk = _sub(str, start, loc1 - 1)
start = loc2 + 1
end
return chunk, ...
end
if callable then
return function()
if not final then
return iter(pattern_or_func(str, start))
end
end
-- Special case if the pattern is anchored to the start: "^" always
-- anchors to the start position, not the start of the string, so get
-- around this by only attempting one match with the pattern, then match
-- the end of the string.
elseif byte(pattern_or_func) == 0x5E then -- ^
local returned
return function()
if not returned then
returned = true
return iter(_find(str, pattern_or_func, start, plain))
elseif not final then
return iter(_find(str, "$", start, plain))
end
end
end
return function()
if not final then
return iter(_find(str, pattern_or_func, start, plain))
end
end
end
gsplit = export.gsplit
function export.count(str, pattern, plain)
if plain then
return select(2, gsub(str, pattern_escape(pattern), ""))
end
local simple = pattern_simplifier(pattern)
if simple then
return select(2, gsub(str, pattern, ""))
end
return select(2, ugsub(str, pattern, ""))
end
function export.trim(str, charset, str_lib, plain)
if charset == nil then
-- "^.*%S" is the fastest trim algorithm except when strings only consist of characters to be trimmed, which are
-- very slow due to catastrophic backtracking. gsub with "^%s*" gets around this by trimming such strings to ""
-- first.
return match(gsub(str, "^%s*", ""), "^.*%S") or ""
elseif charset == "" then
return str
end
charset = plain and ("[" .. charset_escape(charset) .. "]") or get_charset(charset)
-- The pattern uses a non-greedy quantifier instead of the algorithm used for %s, because negative character sets
-- are non-trivial to compute (e.g. "[^^-z]" becomes "[%^_-z]"). Plus, if the ustring library has to be used, there
-- would be two callbacks into PHP, which is slower.
local pattern = "^" .. charset .. "*(.-)" .. charset .. "*$"
if not str_lib then
local simple = pattern_simplifier(pattern)
if not simple then
return umatch(str, pattern)
end
pattern = simple
end
return match(str, pattern)
end
trim = export.trim
do
local entities
local function get_entities()
entities, get_entities = load_data("Module:data/entities"), nil
return entities
end
local function decode_entity(hash, x, code)
if hash == "" then
return (entities or get_entities())[x .. code]
end
local cp
if x == "" then
cp = match(code, "^()%d+$") and tonumber(code)
else
cp = match(code, "^()%x+$") and tonumber(code, 16)
end
return cp and (cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF) and u(cp) or nil
end
-- Non-ASCII characters aren't valid in proper HTML named entities, but MediaWiki uses them in some custom aliases
-- which have also been included in [[Module:data/entities]].
function export.decode_entities(str)
local amp = find(str, "&", nil, true)
return amp and find(str, ";", amp, true) and gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str
end
end
do
local entities
local function get_entities()
-- Memoized HTML entities (taken from mw.text.lua).
entities, get_entities = {
["\""] = """,
["&"] = "&",
["'"] = "'",
["<"] = "<",
[">"] = ">",
["\194\160"] = " ",
}, nil
return entities
end
local function encode_entity(ch)
local entity = (entities or get_entities())[ch]
if entity == nil then
local cp = codepoint(ch)
-- U+D800 to U+DFFF are surrogates, so can't be encoded as entities.
entity = cp and (cp <= 0xD7FF or cp >= 0xE000) and format("&#%d;", cp) or false
entities[ch] = entity
end
return entity or nil
end
function export.encode_entities(str, charset, str_lib, plain)
if charset == nil then
return (gsub(str, "[\"&'<>\194]\160?", entities or get_entities()))
elseif charset == "" then
return str
end
local pattern = plain and ("[" .. charset_escape(charset) .. "]") or charset == "." and charset or get_charset(charset)
if not str_lib then
local simple = pattern_simplifier(pattern)
if not simple then
return (ugsub(str, pattern, encode_entity))
end
pattern = simple
end
return (gsub(str, pattern, encode_entity))
end
end
do
local function decode_path(code)
return char(tonumber(code, 16))
end
local function decode(lead, trail)
if lead == "+" or lead == "_" then
return " " .. trail
elseif #trail == 2 then
return decode_path(trail)
end
return lead .. trail
end
function export.decode_uri(str, enctype)
enctype = enctype and upper(enctype) or "QUERY"
if enctype == "PATH" then
return find(str, "%", nil, true) and gsub(str, "%%(%x%x)", decode_path) or str
elseif enctype == "QUERY" then
return (find(str, "%", nil, true) or find(str, "+", nil, true)) and gsub(str, "([%%%+])(%x?%x?)", decode) or str
elseif enctype == "WIKI" then
return (find(str, "%", nil, true) or find(str, "_", nil, true)) and gsub(str, "([%%_])(%x?%x?)", decode) or str
end
error("bad argument #2 to 'decode_uri' (expected QUERY, PATH, or WIKI)", 2)
end
end
do
local function _remove_comments(str, pre)
local head = find(str, "<!--", nil, true)
if not head then
return str
end
local ret, n = {sub(str, 1, head - 1)}, 1
while true do
local loc = find(str, "-->", head + 4, true)
if not loc then
return pre and concat(ret) or
concat(ret) .. sub(str, head)
end
head = loc + 3
loc = find(str, "<!--", head, true)
if not loc then
return concat(ret) .. sub(str, head)
end
n = n + 1
ret[n] = sub(str, head, loc - 1)
head = loc
end
end
--[==[
Removes any HTML comments from the input text. `stage` can be one of three options:
* {"PRE"} (default) applies the method used by MediaWiki's preprocessor: all
{{code|html|<nowiki><!-- ... --></nowiki>}} pairs are removed, as well as any text after an unclosed
{{code|html|<nowiki><!--</nowiki>}}. This is generally suitable when parsing raw template or
[[mw:Parser extension tags|parser extension tag]] code. (Note, however, that the actual method used by the
preprocessor is considerably more complex and differs under certain conditions (e.g. comments inside nowiki tags);
if full accuracy is absolutely necessary, use [[Module:template parser]] instead).
* {"POST"} applies the method used to generate the final page output once all templates have been expanded: it loops
over the text, removing any {{code|html|<nowiki><!-- ... --></nowiki>}} pairs until no more are found (e.g.
{{code|html|<nowiki><!-<!-- ... -->- ... --></nowiki>}} would be fully removed), but any unclosed
{{code|html|<nowiki><!--</nowiki>}} is ignored. This is suitable for handling links embedded in template inputs,
where the {"PRE"} method will have already been applied by the native parser.
* {"BOTH"} applies {"PRE"} then {"POST"}.
]==]
function export.remove_comments(str, stage)
if not stage or stage == "PRE" then
return _remove_comments(str, true)
end
local processed = stage == "POST" and _remove_comments(str) or
stage == "BOTH" and _remove_comments(str, true) or
error("bad argument #2 to 'remove_comments' (expected PRE, POST, or BOTH)", 2)
while processed ~= str do
str = processed
processed = _remove_comments(str)
end
return str
end
end
do
local byte_escapes
local function get_byte_escapes()
byte_escapes, get_byte_escapes = load_data("Module:string utilities/data").byte_escapes, nil
return byte_escapes
end
local function escape_byte(b)
return (byte_escapes or get_byte_escapes())[b] or format("\\%03d", byte(b))
end
function export.escape_bytes(str)
return (gsub(str, ".", escape_byte))
end
end
function export.format_fun(str, fun)
return (gsub(str, "{(\\?)((\\?)[^{}]*)}", function(p1, name, p2)
if #p1 + #p2 == 1 then
return name == "op" and "{" or
name == "cl" and "}" or
error(mw.getCurrentFrame():getTitle() .. " format: unrecognized escape sequence '{\\" .. name .. "}'")
elseif fun(name) and type(fun(name)) ~= "string" then
error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" is a " .. type(fun(name)) .. ", not a string")
end
return fun(name) or error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" not found in table")
end))
end
format_fun = export.format_fun
--[==[
This function, unlike {string.format} and {mw.ustring.format}, takes just two parameters, a format string and a table,
and replaces all instances of { {param_name} } in the format string with the table's entry for {param_name}. The opening
and closing brace characters can be escaped with { {\op} } and { {\cl} }, respectively. A table entry beginning with a
slash can be escaped by doubling the initial slash.
====Examples====
* {string_utilities.format("{foo} fish, {bar} fish, {baz} fish, {quux} fish", {["foo"]="one", ["bar"]="two", ["baz"]="red", ["quux"]="blue"}) }
*: produces: {"one fish, two fish, red fish, blue fish"}
* {string_utilities.format("The set {\\op}1, 2, 3{\\cl} contains {\\\\hello} elements.", {["\\hello"]="three"})}
*: produces: {"The set {1, 2, 3} contains three elements."}
*:* Note that the single and double backslashes should be entered as double and quadruple backslashes when quoted in a literal string.
]==]
function export.format(str, tbl)
return format_fun(str, function(key)
return tbl[key]
end)
end
do
local function do_uclcfirst(str, case_func)
-- Re-case the first letter.
local first, remainder = match(str, "^(.[\128-\191]*)(.*)")
return first and (case_func(first) .. remainder) or ""
end
local function uclcfirst(str, case_func)
-- Strip off any HTML tags at the beginning. This currently does not handle comments or <ref>...</ref>
-- correctly; it's intended for text wrapped in <span> or the like, as happens when passing text through
-- [[Module:links]].
local html_at_beginning = nil
if str:match("^<") then
while true do
local html_tag, rest = str:match("^(<.->)(.*)$")
if not html_tag then
break
end
if not html_at_beginning then
html_at_beginning = {}
end
insert(html_at_beginning, html_tag)
str = rest
end
end
-- If there's a link at the beginning, re-case the first letter of the
-- link text. This pattern matches both piped and unpiped links.
-- If the link is not piped, the second capture (linktext) will be empty.
local link, linktext, remainder = match(str, "^%[%[([^|%]]+)%|?(.-)%]%](.*)$")
local retval
if link then
retval = "[[" .. link .. "|" .. do_uclcfirst(linktext ~= "" and linktext or link, case_func) .. "]]" .. remainder
else
retval = do_uclcfirst(str, case_func)
end
if html_at_beginning then
retval = concat(html_at_beginning) .. retval
end
return retval
end
--[==[
Uppercase the first character of the input string, correctly handling one-part and two-part links, optionally
surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly
uppercase the first character of text that may include links that have been passed through `full_link()` in
[[Module:links]] or a similar function.
]==]
function export.ucfirst(str)
return uclcfirst(str, uupper)
end
ucfirst = export.ucfirst
--[==[
Lowercase the first character of the input string, correctly handling one-part and two-part links, optionally
surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly
lowercase the first character of text that may include links that have been passed through `full_link()` in
[[Module:links]] or a similar function.
]==]
function export.lcfirst(str)
return uclcfirst(str, ulower)
end
--[==[Capitalizes each word of the input string. WARNING: May be broken in the presence of multiword links.]==]
function export.capitalize(str)
-- Capitalize multi-word that is separated by spaces
-- by uppercasing the first letter of each part.
return (ugsub(str, "%w+", ucfirst))
end
local function do_title_case(first, remainder)
first = uupper(first)
return remainder == "" and first or (first .. ulower(remainder))
end
--[==[
Capitalizes each word of the input string, with any further letters in each word being converted to lowercase.
]==]
function export.title_case(str)
return str == "" and "" or ugsub(str, "(%w)(%w*)", do_title_case)
end
title_case = export.title_case
--[==[
Converts the input string to {{w|Camel case|CamelCase}}. Any non-word characters are treated as breaks between
words. If `lower_first` is set, then the first character of the string will be lowercase (e.g. camelCase).
]==]
function export.camel_case(str, lower_first)
str = ugsub(str, "%W*(%w*)", title_case)
return lower_first and do_uclcfirst(str, ulower) or str
end
end
do
local function do_snake_case(nonword, word)
return nonword == "" and word or "_" .. word
end
--[==[
Converts the input string to {{w|Snake case|snake_case}}. Any non-word characters are treated as breaks between
words.
]==]
function export.snake_case(str)
return (ugsub(str, "(%W*)(%w*)", do_snake_case))
end
end
return export
e6miribg0itqnem57pj8nvg9ynee056
394114
394113
2026-10-12T13:23:31Z
Ow! That Hurts!
8952
394114
Scribunto
text/plain
local export = {}
local function_module = "Module:fun"
local load_module = "Module:load"
local memoize_module = "Module:memoize"
local string_char_module = "Module:strengur/char"
local string_charset_escape_module = "Module:string/charsetEscape"
local mw = mw
local string = string
local table = table
local ustring = mw.ustring
local byte = string.byte
local char = string.char
local concat = table.concat
local find = string.find
local format = string.format
local gmatch = string.gmatch
local gsub = string.gsub
local insert = table.insert
local len = string.len
local lower = string.lower
local match = string.match
local next = next
local require = require
local reverse = string.reverse
local select = select
local sort = table.sort
local sub = string.sub
local tonumber = tonumber
local tostring = tostring
local type = type
local ucodepoint = ustring.codepoint
local ufind = ustring.find
local ugcodepoint = ustring.gcodepoint
local ugmatch = ustring.gmatch
local ugsub = ustring.gsub
local ulower = ustring.lower
local umatch = ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local upper = string.upper
local usub = ustring.sub
local uupper = ustring.upper
local memoize = require(memoize_module)
-- Defined below.
local codepoint
local explode_utf8
local format_fun
local get_charset
local gsplit
local pattern_escape
local pattern_simplifier
local replacement_escape
local title_case
local trim
local ucfirst
local ulen
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures
modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no
overhead after the first call, since the target functions are called directly in any subsequent calls.
]==]
local function charset_escape(...)
charset_escape = require(string_charset_escape_module)
return charset_escape(...)
end
local function is_callable(...)
is_callable = require(function_module).is_callable
return is_callable(...)
end
local function load_data(...)
load_data = require(load_module).load_data
return load_data(...)
end
local function u(...)
u = require(string_char_module)
return u(...)
end
local function prepare_iter(str, pattern, str_lib, plain)
local callable = is_callable(pattern)
if str_lib or plain then
return pattern, #str, string, callable
elseif not callable then
local simple = pattern_simplifier(pattern)
if simple then
return simple, #str, string, false
end
end
return pattern, ulen(str), ustring, callable
end
--[==[
Returns {nil} if the input value is the empty string, or otherwise the same value.
If the input is a string and `do_trim` is set, the input value will be trimmed before returning; if the trimmed value is
the empty string, returns {nil}.
If `quote_delimiters` is set, then any outer pair of quotation marks ({' '} or {" "}) surrounding the rest of the input
string will be stripped, if present. The string will not be trimmed again, converted to {nil}, or have further quotation
marks stripped, as it exists as a way to embed spaces or the empty string in an input. Genuine quotation marks may also
be embedded this way (e.g. {"''foo''"} returns {"'foo'"}).
]==]
function export.is_not_empty(str, do_trim, quote_delimiters)
if str == "" then
return nil
elseif not (str and type(str) == "string") then
return str
elseif do_trim then
str = trim(str)
if str == "" then
return nil
end
end
return quote_delimiters and gsub(str, "^(['\"])(.*)%1$", "%2") or str
end
--[==[
Explodes a string into an array of UTF-8 characters. '''Warning''': this function assumes that the input is valid UTF-8
in order to optimize speed and memory use. Passing in an input containing non-UTF-8 byte sequences could result in
unexpected behaviour.
]==]
function export.explode_utf8(str)
local text, i = {}, 0
for ch in gmatch(str, ".[\128-\191]*") do
i = i + 1
text[i] = ch
end
return text
end
explode_utf8 = export.explode_utf8
--[==[
Returns {true} if `str` is a valid UTF-8 string. This is true if, for each character, all of the following are true:
* It has the expected number of bytes, which is determined by value of the leading byte: 1-byte characters are `0x00` to
`0x7F`, 2-byte characters start with `0xC2` to `0xDF`, 3-byte characters start with `0xE0` to `0xEF`, and 4-byte
characters start with `0xF0` to `0xF4`.
* The leading byte must not fall outside of the above ranges.
* The trailing byte(s) (if any), must be between `0x80` to `0xBF`.
* The character's codepoint must be between U+0000 (`0x00`) and U+10FFFF (`0xF4 0x8F 0xBF 0xBF`).
* The character cannot have an overlong encoding: for each byte length, the lowest theoretical encoding is equivalent to
U+0000 (e.g. `0xE0 0x80 0x80`, the lowest theoretical 3-byte encoding, is exactly equivalent to U+0000). Encodings
that use more than the minimum number of bytes are not considered valid, meaning that the first valid 3-byte
character is `0xE0 0xA0 0x80` (U+0800), and the first valid 4-byte character is `0xF0 0x90 0x80 0x80` (U+10000).
Formally, 2-byte characters have leading bytes ranging from `0xC0` to `0xDF` (rather than `0xC2` to `0xDF`), but
`0xC0 0x80` to `0xC1 0xBF` are overlong encodings, so it is simpler to say that the 2-byte range begins at `0xC2`.
If `allow_surrogates` is set, surrogates (U+D800 to U+DFFF) will be treated as valid UTF-8. Surrogates are used in
UTF-16, which encodes codepoints U+0000 to U+FFFF with 2 bytes, and codepoints from U+10000 upwards using a pair of
surrogates, which are taken together as a 4-byte unit. Since surrogates have no use in UTF-8, as it encodes higher
codepoints in a different way, they are not considered valid in UTF-8 text. However, there are limited circumstances
where they may be necessary: for instance, JSON escapes characters using the format `\u0000`, which must contain exactly
4 hexadecimal digits; under the scheme, codepoints above U+FFFF must be escaped as the equivalent pair of surrogates,
even though the text itself must be encoded in UTF-8 (e.g. U+10000 becomes `\uD800\uDC00`).
]==]
function export.isutf8(str, allow_surrogates)
for ch in gmatch(str, "[\128-\255][\128-\191]*") do
if #ch > 4 then
return false
end
local b1, b2, b3, b4 = byte(ch, 1, 4)
if not (b2 and b2 >= 0x80 and b2 <= 0xBF) then
return false -- 1-byte is always invalid, as gmatch excludes 0x00 to 0x7F
elseif not b3 then -- 2-byte
if not (b1 >= 0xC2 and b1 <= 0xDF) then -- b1 == 0xC0 or b1 == 0xC1 is overlong
return false
end
elseif not (b3 >= 0x80 and b3 <= 0xBF) then -- trailing byte
return false
elseif not b4 then -- 3-byte
if b1 > 0xEF then
return false
elseif b2 < 0xA0 then
if b1 < 0xE1 then -- b1 == 0xE0 and b2 < 0xA0 is overlong
return false
end
elseif b1 < 0xE0 or (b1 == 0xED and not allow_surrogates) then -- b1 == 0xED and b2 >= 0xA0 is a surrogate
return false
end
elseif not (b4 >= 0x80 and b4 <= 0xBF) then -- 4-byte
return false
elseif b2 < 0x90 then
if not (b1 >= 0xF1 and b1 <= 0xF4) then -- b1 == 0xF0 and b2 < 0x90 is overlong
return false
end
elseif not (b1 >= 0xF0 and b1 <= 0xF3) then -- b1 == 0xF4 and b2 >= 0x90 is too high
return false
end
end
return true
end
do
local charset_chars = {
["\0"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^"
}
charset_chars.__index = charset_chars
local chars = setmetatable({
["$"] = "%$", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+",
["."] = "%.", ["?"] = "%?", ["["] = "%["
}, charset_chars)
--[==[
Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]] (Lua's
version of regular expressions): {$%()*+-.?[]^}, and converts the null character to {%z}. For example,
{"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving
arbitrary text (e.g. from user input).
]==]
function export.pattern_escape(str)
return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars))
end
pattern_escape = export.pattern_escape
--[==[
Escapes only {%}, which is the only magic character used in replacement
[[mw:Extension:Scribunto/Lua reference manual#Patterns|patterns]] with string.gsub and mw.ustring.gsub.
]==]
function export.replacement_escape(str)
return (gsub(str, "%%", "%%%%"))
end
replacement_escape = export.replacement_escape
local function case_insensitive_char(ch)
local upper_ch = uupper(ch)
if upper_ch == ch then
ch = ulower(ch)
if ch == upper_ch then
return chars[ch] or ch
end
end
return "[" .. (charset_chars[upper_ch] or upper_ch) .. (charset_chars[ch] or ch) .. "]"
end
local function iterate(str, str_len, text, n, start, _gsub, _sub, loc1, loc2)
if not (loc1 and start <= str_len) then
-- Add final chunk and return.
n = n + 1
text[n] = _gsub(_sub(str, start), ".", chars)
return
elseif loc2 < loc1 then
if _sub == sub then
local b = byte(str, loc1)
if b and b >= 128 then
loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3)
end
end
n = n + 1
text[n] = _gsub(_sub(str, start, loc1), ".", chars)
start = loc1 + 1
if start > str_len then
return
end
else
-- Add chunk up to the current match.
n = n + 1
text[n] = _gsub(_sub(str, start, loc1 - 1), ".", chars)
-- Add current match.
n = n + 1
text[n] = _gsub(_sub(str, loc1, loc2), ".", case_insensitive_char)
start = loc2 + 1
end
return n, start
end
--[==[
Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]], and makes
all characters case-insensitive. An optional pattern or find function (see {split}) may be supplied as the second
argument, the third argument (`str_lib`) forces use of the string library, while the fourth argument (`plain`) turns
any pattern matching facilities off in the optional pattern supplied.
]==]
function export.case_insensitive_pattern(str, pattern_or_func, str_lib, plain)
if pattern_or_func == nil then
return (gsub(str, str_lib and "[^\128-\255]" or ".[\128-\191]*", case_insensitive_char))
end
local text, n, start, str_len, _string, callable = {}, 0, 1
pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain)
local _find, _gsub, _sub = _string.find, _string.gsub, _string.sub
if callable then
repeat
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, pattern_or_func(str, start))
until not start
-- Special case if the pattern is anchored to the start: "^" always
-- anchors to the start position, not the start of the string, so get
-- around this by only attempting one match with the pattern, then match
-- the end of the string.
elseif byte(pattern_or_func) == 0x5E then -- ^
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain))
if start ~= nil then
iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, "$", start, plain))
end
else
repeat
n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain))
until not start
end
return concat(text)
end
end
do
local character_classes
local function get_character_classes()
character_classes, get_character_classes = {
[0x41] = true, [0x61] = true, -- Aa
[0x43] = true, [0x63] = true, -- Cc
[0x44] = true, [0x64] = true, -- Dd
[0x4C] = true, [0x6C] = true, -- Ll
[0x50] = true, [0x70] = true, -- Pp
[0x53] = true, [0x73] = true, -- Ss
[0x55] = true, [0x75] = true, -- Uu
[0x57] = true, [0x77] = true, -- Ww
[0x58] = true, [0x78] = true, -- Xx
[0x5A] = true, -- z dealt with separately.
}, nil
return character_classes
end
local function check_sets_equal(set1, set2)
local k2
for k1, v1 in next, set1 do
local v2 = set2[k1]
if v1 ~= v2 and (v2 == nil or not check_sets_equal(v1, v2)) then
return false
end
k2 = next(set2, k2)
end
return next(set2, k2) == nil
end
local function check_sets(bytes)
local key, set1, set = next(bytes)
if set1 == true then
return true
elseif not check_sets(set1) then
return false
end
while true do
key, set = next(bytes, key)
if not key then
return true
elseif not check_sets_equal(set, set1) then
return false
end
end
end
local function make_charset(range)
if #range == 1 then
return char(range[1])
end
sort(range)
local compressed, n, start = {}, 0, range[1]
for i = 1, #range do
local this, nxt = range[i], range[i + 1]
if nxt ~= this + 1 then
n = n + 1
compressed[n] = this == start and char(this) or
char(start) .. "-" .. char(this)
start = nxt
end
end
return "[" .. concat(compressed) .. "]"
end
local function parse_1_byte_charset(pattern, pos)
local ch
while true do
pos, ch = match(pattern, "()([%%%]\192-\255])", pos)
if ch == "%" then
local nxt = byte(pattern, pos + 1)
if not nxt or nxt >= 128 or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWXZ, but not z
return false
end
pos = pos + 2
elseif ch == "]" then
pos = pos + 1
return pos
else
return false
end
end
end
--[==[
Parses `pattern`, a ustring library pattern, and attempts to convert it into a string library pattern. If conversion
isn't possible, returns false.
]==]
function pattern_simplifier(pattern)
if type(pattern) == "number" then
return tostring(pattern)
end
local pos, capture_groups, start, n, output, ch, nxt_pos = 1, 0, 1, 0
while true do
-- FIXME: use "()([%%(.[\128-\255])[\128-\191]?[\128-\191]?[\128-\191]?()" and ensure non-UTF8 always fails.
pos, ch, nxt_pos = match(pattern, "()([%%(.[\192-\255])[\128-\191]*()", pos)
if not ch then
break
end
local nxt = byte(pattern, nxt_pos)
if ch == "%" then
if nxt == 0x62 then -- b
local nxt2, nxt3 = byte(pattern, pos + 2, pos + 3)
if not (nxt2 and nxt2 < 128 and nxt3 and nxt3 < 128) then
return false
end
pos = pos + 4
elseif nxt == 0x66 then -- f
nxt_pos = nxt_pos + 2
local nxt2, nxt3 = byte(pattern, nxt_pos - 1, nxt_pos)
-- Only possible to convert a positive %f charset which is
-- all ASCII, so use parse_1_byte_charset.
if not (nxt2 == 0x5B and nxt3 and nxt3 ~= 0x5E and nxt3 < 128) then -- [^
return false
elseif nxt3 == 0x5D then -- Initial ] is non-magic.
nxt_pos = nxt_pos + 1
end
pos = parse_1_byte_charset(pattern, nxt_pos)
if not pos then
return false
end
elseif nxt == 0x5A then -- Z
nxt = byte(pattern, nxt_pos + 1)
if nxt == 0x2A or nxt == 0x2D then -- *-
pos = pos + 3
else
if output == nil then
output = {}
end
local ins = sub(pattern, start, pos - 1) .. "[\1-\127\192-\255]"
n = n + 1
if nxt == 0x2B then -- +
output[n] = ins .. "%Z*"
pos = pos + 3
elseif nxt == 0x3F then -- ?
output[n] = ins .. "?[\128-\191]*"
pos = pos + 3
else
output[n] = ins .. "[\128-\191]*"
pos = pos + 2
end
start = pos
end
elseif not nxt or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWX, but not Zz
return false
-- Skip the next character if it's ASCII. Otherwise, we will
-- still need to do length checks.
else
pos = pos + (nxt < 128 and 2 or 1)
end
elseif ch == "(" then
if nxt == 0x29 or capture_groups == 32 then -- )
return false
end
capture_groups = capture_groups + 1
pos = pos + 1
elseif ch == "." then
if nxt == 0x2A or nxt == 0x2D then -- *-
pos = pos + 2
else
if output == nil then
output = {}
end
local ins = sub(pattern, start, pos - 1) .. "[^\128-\191]"
n = n + 1
if nxt == 0x2B then -- +
output[n] = ins .. ".*"
pos = pos + 2
elseif nxt == 0x3F then -- ?
output[n] = ins .. "?[\128-\191]*"
pos = pos + 2
else
output[n] = ins .. "[\128-\191]*"
pos = pos + 1
end
start = pos
end
elseif ch == "[" then
-- Fail negative charsets. TODO: 1-byte charsets should be safe.
if nxt == 0x5E then -- ^
return false
-- If the first character is "%", ch_len is determined by the
-- next one instead.
elseif nxt == 0x25 then -- %
nxt = byte(pattern, nxt_pos + 1)
elseif nxt == 0x5D then -- Initial ] is non-magic.
nxt_pos = nxt_pos + 1
end
if not nxt then
return false
end
local ch_len = nxt < 128 and 1 or nxt < 224 and 2 or nxt < 240 and 3 or 4
if ch_len == 1 then -- Single-byte charset.
pos = parse_1_byte_charset(pattern, nxt_pos)
if not pos then
return false
end
else -- Multibyte charset.
-- TODO: 1-byte chars should be safe to mix with multibyte chars. CONFIRM THIS FIRST.
local charset_pos, bytes = pos
pos = pos + 1
while true do -- TODO: non-ASCII charset ranges.
pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", pos)
-- If escaped, get the next character. No need to
-- distinguish magic characters or character classes,
-- as they'll all fail for having the wrong length
-- anyway.
if ch == "%" then
pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", nxt_pos)
elseif ch == "]" then
pos = nxt_pos
break
end
if not (ch and nxt_pos - pos == ch_len) then
return false
elseif bytes == nil then
bytes = {}
end
local bytes, last = bytes, nxt_pos - 1
for i = pos, last - 1 do
local b = byte(pattern, i)
local bytes_b = bytes[b]
if bytes_b == nil then
bytes_b = {}
bytes[b] = bytes_b
end
bytes[b], bytes = bytes_b, bytes_b
end
bytes[byte(pattern, last)] = true
pos = nxt_pos
end
if not pos then
return false
end
nxt = byte(pattern, pos)
if (
(nxt == 0x2A or nxt == 0x2D or nxt == 0x3F) or -- *-?
(nxt == 0x2B and ch_len > 2) or -- +
not check_sets(bytes)
) then
return false
end
local ranges, b, key, next_byte = {}, 0
repeat
key, next_byte = next(bytes)
local range, n = {key}, 1
-- Loop starts on the second iteration.
for key in next, bytes, key do
n = n + 1
range[n] = key
end
b = b + 1
ranges[b] = range
bytes = next_byte
until next_byte == true
if nxt == 0x2B then -- +
local range1, range2 = ranges[1], ranges[2]
ranges[1], ranges[3] = make_charset(range1), make_charset(range2)
local n = #range2
for i = 1, #range1 do
n = n + 1
range2[n] = range1[i]
end
ranges[2] = make_charset(range2) .. "*"
pos = pos + 1
else
for i = 1, #ranges do
ranges[i] = make_charset(ranges[i])
end
end
if output == nil then
output = {}
end
nxt = byte(pattern, pos)
n = n + 1
output[n] = sub(pattern, start, charset_pos - 1) .. concat(ranges) ..
((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped
start = pos
end
elseif not nxt then
break
elseif nxt == 0x2B then -- +
if nxt_pos - pos ~= 2 then
return false
elseif output == nil then
output = {}
end
pos, nxt_pos = pos + 1, nxt_pos + 1
nxt = byte(pattern, nxt_pos)
local ch2 = sub(pattern, pos, pos)
n = n + 1
output[n] = sub(pattern, start, pos - 1) .. "[" .. ch .. ch2 .. "]*" .. ch2 ..
((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped
pos, start = nxt_pos, nxt_pos
elseif nxt == 0x2A or nxt == 0x2D or nxt == 0x3F then -- *-?
return false
else
pos = nxt_pos
end
end
if start == 1 then
return pattern
end
return concat(output) .. sub(pattern, start)
end
pattern_simplifier = memoize(pattern_simplifier, true)
export.pattern_simplifier = pattern_simplifier
end
--[==[
Parses `charset`, the interior of a string or ustring library character set, and normalizes it into a string or ustring
library pattern (e.g. {"abcd-g"} becomes {"[abcd-g]"}, and {"[]"} becomes {"[[%]]"}).
The negative (`^`), range (`-`) and literal (`%`) magic characters work as normal, and character classes may be used
(e.g. `%d` and `%w`), but opening and closing square brackets are sanitized so that they behave like ordinary
characters.
]==]
function get_charset(charset)
if type(charset) == "number" then
return tostring(charset)
end
local pos, start, n, output = 1, 1, 0
if byte(charset) == 0x5E then -- ^
pos = pos + 1
end
-- FIXME: "]" is non-magic if it's the first character in a charset.
local nxt_pos, nxt
while true do
local new_pos, ch = match(charset, "()([%%%-%]])", pos)
if not ch then
break
-- Skip percent escapes. Ranges can't start with them, either.
elseif ch == "%" then
pos = new_pos + 2
else
-- If `ch` is a hyphen, get the character before iff it's at or ahead of `pos`.
if ch == "-" and new_pos > pos then
pos, nxt_pos, nxt = new_pos - 1, new_pos, ch
ch = sub(charset, pos, pos)
else
pos, nxt_pos = new_pos, new_pos + 1
nxt = sub(charset, nxt_pos, nxt_pos)
end
-- Range.
if nxt == "-" then
if output == nil then
output = {}
end
n = n + 1
output[n] = sub(charset, start, pos - 1)
nxt_pos = nxt_pos + 1
nxt = sub(charset, nxt_pos, nxt_pos)
-- Ranges fail if they end with a percent escape, so escape the hyphen to avoid undefined behaviour.
if nxt == "" or nxt == "%" then
n = n + 1
output[n] = (ch == "]" and "%]" or ch) .. "%-"
start = nxt_pos
nxt_pos = nxt_pos + 2
-- Since ranges can't contain "%]", since it's escaped, range inputs like "]-z" or "a-]" must be
-- adjusted to the character before or after, plus "%]" (e.g. "%]^-z" or "a-\\%]"). The escaped "%]" is
-- omitted if the range would be empty (i.e. if the first byte is greater than the second).
else
n = n + 1
output[n] = (ch == "]" and (byte(nxt) >= 0x5D and "%]^" or "^") or ch) .. "-" ..
(nxt == "]" and (byte(ch) <= 0x5D and "\\%]" or "\\") or nxt)
nxt_pos = nxt_pos + 1
start = nxt_pos
end
elseif ch == "-" or ch == "]" then
if output == nil then
output = {}
end
n = n + 1
output[n] = sub(charset, start, pos - 1) .. "%" .. ch
start = nxt_pos
end
pos = nxt_pos
end
end
if start == 1 then
return "[" .. charset .. "]"
end
return "[" .. concat(output) .. sub(charset, start) .. "]"
end
get_charset = memoize(get_charset, true)
export.get_charset = get_charset
function export.len(str)
return type(str) == "number" and len(str) or
#str - #gsub(str, "[^\128-\191]+", "")
end
ulen = export.len
function export.sub(str, i, j)
str, i = type(str) == "number" and tostring(str) or str, i or 1
if i < 0 or j and j < 0 then
return usub(str, i, j)
elseif j and i > j or i > #str then
return ""
end
local n, new_i = 0
for loc1, loc2 in gmatch(str, "()[^\128-\191]+()[\128-\191]*") do
n = n + loc2 - loc1
if not new_i and n >= i then
new_i = loc2 - (n - i) - 1
if not j then
return sub(str, new_i)
end
end
if j and n > j then
return sub(str, new_i, loc2 - (n - j) - 1)
end
end
return new_i and sub(str, new_i) or ""
end
do
local function _find(str, loc1, loc2, ...)
if loc1 and not match(str, "^()[^\128-\255]*$") then
-- Use raw values of loc1 and loc2 to get loc1 and the length of the match.
loc1, loc2 = ulen(sub(str, 1, loc1)), ulen(sub(str, loc1, loc2))
-- Offset length with loc1 to get loc2.
loc2 = loc1 + loc2 - 1
end
return loc1, loc2, ...
end
--[==[A version of find which uses string.find when possible, but otherwise uses mw.ustring.find.]==]
function export.find(str, pattern, init, plain)
init = init or 1
if init ~= 1 and not match(str, "^()[^\128-\255]*$") then
return ufind(str, pattern, init, plain)
elseif plain then
return _find(str, find(str, pattern, init, true))
end
local simple = pattern_simplifier(pattern)
if simple then
return _find(str, find(str, simple, init))
end
return ufind(str, pattern, init)
end
end
--[==[A version of match which uses string.match when possible, but otherwise uses mw.ustring.match.]==]
function export.match(str, pattern, init)
init = init or 1
if init ~= 1 and not match(str, "^()[^\128-\255]*$") then
return umatch(str, pattern, init)
end
local simple = pattern_simplifier(pattern)
if simple then
return match(str, simple, init)
end
return umatch(str, pattern, init)
end
--[==[A version of gmatch which uses string.gmatch when possible, but otherwise uses mw.ustring.gmatch.]==]
function export.gmatch(str, pattern)
local simple = pattern_simplifier(pattern)
if simple then
return gmatch(str, simple)
end
return ugmatch(str, pattern)
end
--[==[A version of gsub which uses string.gsub when possible, but otherwise uses mw.ustring.gsub.]==]
function export.gsub(str, pattern, repl, n)
local simple = pattern_simplifier(pattern)
if simple then
return gsub(str, simple, repl, n)
end
return ugsub(str, pattern, repl, n)
end
--[==[
Like gsub, but pattern-matching facilities are turned off, so `pattern` and `repl` (if a string) are treated as literal.
]==]
function export.plain_gsub(str, pattern, repl, n)
return gsub(str, pattern_escape(pattern), type(repl) == "string" and replacement_escape(repl) or repl, n)
end
--[==[
Reverses a UTF-8 string; equivalent to string.reverse.
]==]
function export.reverse(str)
return reverse((gsub(str, "[\192-\255][\128-\191]*", reverse)))
end
function export.char(...) -- To be moved to [[Module:string/char]].
return u(...)
end
do
local function utf8_err(func_name)
error(format("bad argument #1 to '%s' (string is not UTF-8)", func_name), 4)
end
local function get_codepoint(func_name, b1, b2, b3, b4)
if b1 <= 0x7F then
return b1, 1
elseif not (b2 and b2 >= 0x80 and b2 <= 0xBF) then
utf8_err(func_name)
elseif b1 <= 0xDF then
local cp = 0x40 * b1 + b2 - 0x3080
return cp >= 0x80 and cp or utf8_err(func_name), 2
elseif not (b3 and b3 >= 0x80 and b3 <= 0xBF) then
utf8_err(func_name)
elseif b1 <= 0xEF then
local cp = 0x1000 * b1 + 0x40 * b2 + b3 - 0xE2080
return cp >= 0x800 and cp or utf8_err(func_name), 3
elseif not (b4 and b4 >= 0x80 and b4 <= 0xBF) then
utf8_err(func_name)
end
local cp = 0x40000 * b1 + 0x1000 * b2 + 0x40 * b3 + b4 - 0x3C82080
return cp >= 0x10000 and cp <= 0x10FFFF and cp or utf8_err(func_name), 4
end
function export.codepoint(str, i, j)
if str == "" then
return -- return nothing
elseif type(str) == "number" then
return byte(str, i, j)
end
i, j = i or 1, j == -1 and #str or i or 1
if i == 1 and j == 1 then
return (get_codepoint("codepoint", byte(str, 1, 4)))
elseif i < 0 or j < 0 then
return ucodepoint(str, i, j) -- FIXME
end
local n, nb, ret, nr = 0, 1, {}, 0
while n < j do
n = n + 1
if n < i then
local b = byte(str, nb)
nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4)
else
local b1, b2, b3, b4 = byte(str, nb, nb + 3)
if not b1 then
break
end
nr = nr + 1
local add
ret[nr], add = get_codepoint("codepoint", b1, b2, b3, b4)
nb = nb + add
end
end
return unpack(ret)
end
codepoint = export.codepoint
function export.gcodepoint(str, i, j)
i, j = i or 1, j ~= -1 and j or nil
if i < 0 or j and j < 0 then
return ugcodepoint(str, i, j) -- FIXME
end
local n, nb = 1, 1
while n < i do
local b = byte(str, nb)
if not b then
break
end
nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4)
n = n + 1
end
return function()
if j and n > j then
return nil
end
n = n + 1
local b1, b2, b3, b4 = byte(str, nb, nb + 3)
if not b1 then
return nil
end
local ret, add = get_codepoint("gcodepoint", b1, b2, b3, b4)
nb = nb + add
return ret
end
end
end
do
local _ulower = ulower
--[==[A version of lower which uses string.lower when possible, but otherwise uses mw.ustring.lower.]==]
function export.lower(str)
return (match(str, "^()[^\128-\255]*$") and lower or _ulower)(str)
end
end
do
local _uupper = uupper
--[==[A version of upper which uses string.upper when possible, but otherwise uses mw.ustring.upper.]==]
function export.upper(str)
return (match(str, "^()[^\128-\255]*$") and upper or _uupper)(str)
end
end
do
local function add_captures(t, n, ...)
if ... == nil then
return
end
-- Insert any captures from the splitting pattern.
local offset, capture = n - 1, ...
while capture do
n = n + 1
t[n] = capture
capture = select(n - offset, ...)
end
return n
end
--[==[
Reimplementation of mw.text.split() that includes any capturing groups in the splitting pattern. This works like
Python's re.split() function, except that it has Lua's behavior when the split pattern is empty (i.e. advancing by
one character at a time; Python returns the whole remainder of the string). When possible, it will use the string
library, but otherwise uses the ustring library. There are two optional parameters: `str_lib` forces use of the
string library, while `plain` turns any pattern matching facilities off, treating `pattern` as literal.
In addition, `pattern` may be a custom find function (or callable table), which takes the input string and start
index as its two arguments, and must return the start and end index of the match, plus any optional captures, or nil
if there are no further matches. By default, the start index will be calculated using the ustring library, unless
`str_lib` or `plain` is set.
]==]
function export.split(str, pattern_or_func, str_lib, plain)
local iter, t, n = gsplit(str, pattern_or_func, str_lib, plain), {}, 0
repeat
n = add_captures(t, n, iter())
until n == nil
return t
end
export.capturing_split = export.split -- To be removed.
end
--[==[
Returns an iterator function, which iterates over the substrings returned by {split}. The first value returned is the
string up the splitting pattern, with any capture groups being returned as additional values on that iteration.
]==]
function export.gsplit(str, pattern_or_func, str_lib, plain)
local start, final, str_len, _string, callable = 1
pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain)
local _find, _sub = _string.find, _string.sub
local function iter(loc1, loc2, ...)
-- If no match, or there is but we're past the end of the string
-- (which happens when the match is the empty string), then return
-- the final chunk.
if not loc1 then
final = true
return _sub(str, start)
end
-- Special case: If we match the empty string, then eat the
-- next character; this avoids an infinite loop, and makes
-- splitting by the empty string work the way mw.text.gsplit() does
-- (including non-adjacent empty string matches with %f). If we
-- reach the end of the string this way, set `final` to true, so we
-- don't get stuck matching the empty string at the end.
local chunk
if loc2 < loc1 then
-- If using the string library, we need to make sure we advance
-- by one UTF-8 character.
if _sub == sub then
local b = byte(str, loc1)
if b and b >= 128 then
loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3)
end
end
chunk = _sub(str, start, loc1)
if loc1 >= str_len then
final = true
else
start = loc1 + 1
end
-- Eat chunk up to the current match.
else
chunk = _sub(str, start, loc1 - 1)
start = loc2 + 1
end
return chunk, ...
end
if callable then
return function()
if not final then
return iter(pattern_or_func(str, start))
end
end
-- Special case if the pattern is anchored to the start: "^" always
-- anchors to the start position, not the start of the string, so get
-- around this by only attempting one match with the pattern, then match
-- the end of the string.
elseif byte(pattern_or_func) == 0x5E then -- ^
local returned
return function()
if not returned then
returned = true
return iter(_find(str, pattern_or_func, start, plain))
elseif not final then
return iter(_find(str, "$", start, plain))
end
end
end
return function()
if not final then
return iter(_find(str, pattern_or_func, start, plain))
end
end
end
gsplit = export.gsplit
function export.count(str, pattern, plain)
if plain then
return select(2, gsub(str, pattern_escape(pattern), ""))
end
local simple = pattern_simplifier(pattern)
if simple then
return select(2, gsub(str, pattern, ""))
end
return select(2, ugsub(str, pattern, ""))
end
function export.trim(str, charset, str_lib, plain)
if charset == nil then
-- "^.*%S" is the fastest trim algorithm except when strings only consist of characters to be trimmed, which are
-- very slow due to catastrophic backtracking. gsub with "^%s*" gets around this by trimming such strings to ""
-- first.
return match(gsub(str, "^%s*", ""), "^.*%S") or ""
elseif charset == "" then
return str
end
charset = plain and ("[" .. charset_escape(charset) .. "]") or get_charset(charset)
-- The pattern uses a non-greedy quantifier instead of the algorithm used for %s, because negative character sets
-- are non-trivial to compute (e.g. "[^^-z]" becomes "[%^_-z]"). Plus, if the ustring library has to be used, there
-- would be two callbacks into PHP, which is slower.
local pattern = "^" .. charset .. "*(.-)" .. charset .. "*$"
if not str_lib then
local simple = pattern_simplifier(pattern)
if not simple then
return umatch(str, pattern)
end
pattern = simple
end
return match(str, pattern)
end
trim = export.trim
do
local entities
local function get_entities()
entities, get_entities = load_data("Module:data/entities"), nil
return entities
end
local function decode_entity(hash, x, code)
if hash == "" then
return (entities or get_entities())[x .. code]
end
local cp
if x == "" then
cp = match(code, "^()%d+$") and tonumber(code)
else
cp = match(code, "^()%x+$") and tonumber(code, 16)
end
return cp and (cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF) and u(cp) or nil
end
-- Non-ASCII characters aren't valid in proper HTML named entities, but MediaWiki uses them in some custom aliases
-- which have also been included in [[Module:data/entities]].
function export.decode_entities(str)
local amp = find(str, "&", nil, true)
return amp and find(str, ";", amp, true) and gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str
end
end
do
local entities
local function get_entities()
-- Memoized HTML entities (taken from mw.text.lua).
entities, get_entities = {
["\""] = """,
["&"] = "&",
["'"] = "'",
["<"] = "<",
[">"] = ">",
["\194\160"] = " ",
}, nil
return entities
end
local function encode_entity(ch)
local entity = (entities or get_entities())[ch]
if entity == nil then
local cp = codepoint(ch)
-- U+D800 to U+DFFF are surrogates, so can't be encoded as entities.
entity = cp and (cp <= 0xD7FF or cp >= 0xE000) and format("&#%d;", cp) or false
entities[ch] = entity
end
return entity or nil
end
function export.encode_entities(str, charset, str_lib, plain)
if charset == nil then
return (gsub(str, "[\"&'<>\194]\160?", entities or get_entities()))
elseif charset == "" then
return str
end
local pattern = plain and ("[" .. charset_escape(charset) .. "]") or charset == "." and charset or get_charset(charset)
if not str_lib then
local simple = pattern_simplifier(pattern)
if not simple then
return (ugsub(str, pattern, encode_entity))
end
pattern = simple
end
return (gsub(str, pattern, encode_entity))
end
end
do
local function decode_path(code)
return char(tonumber(code, 16))
end
local function decode(lead, trail)
if lead == "+" or lead == "_" then
return " " .. trail
elseif #trail == 2 then
return decode_path(trail)
end
return lead .. trail
end
function export.decode_uri(str, enctype)
enctype = enctype and upper(enctype) or "QUERY"
if enctype == "PATH" then
return find(str, "%", nil, true) and gsub(str, "%%(%x%x)", decode_path) or str
elseif enctype == "QUERY" then
return (find(str, "%", nil, true) or find(str, "+", nil, true)) and gsub(str, "([%%%+])(%x?%x?)", decode) or str
elseif enctype == "WIKI" then
return (find(str, "%", nil, true) or find(str, "_", nil, true)) and gsub(str, "([%%_])(%x?%x?)", decode) or str
end
error("bad argument #2 to 'decode_uri' (expected QUERY, PATH, or WIKI)", 2)
end
end
do
local function _remove_comments(str, pre)
local head = find(str, "<!--", nil, true)
if not head then
return str
end
local ret, n = {sub(str, 1, head - 1)}, 1
while true do
local loc = find(str, "-->", head + 4, true)
if not loc then
return pre and concat(ret) or
concat(ret) .. sub(str, head)
end
head = loc + 3
loc = find(str, "<!--", head, true)
if not loc then
return concat(ret) .. sub(str, head)
end
n = n + 1
ret[n] = sub(str, head, loc - 1)
head = loc
end
end
--[==[
Removes any HTML comments from the input text. `stage` can be one of three options:
* {"PRE"} (default) applies the method used by MediaWiki's preprocessor: all
{{code|html|<nowiki><!-- ... --></nowiki>}} pairs are removed, as well as any text after an unclosed
{{code|html|<nowiki><!--</nowiki>}}. This is generally suitable when parsing raw template or
[[mw:Parser extension tags|parser extension tag]] code. (Note, however, that the actual method used by the
preprocessor is considerably more complex and differs under certain conditions (e.g. comments inside nowiki tags);
if full accuracy is absolutely necessary, use [[Module:template parser]] instead).
* {"POST"} applies the method used to generate the final page output once all templates have been expanded: it loops
over the text, removing any {{code|html|<nowiki><!-- ... --></nowiki>}} pairs until no more are found (e.g.
{{code|html|<nowiki><!-<!-- ... -->- ... --></nowiki>}} would be fully removed), but any unclosed
{{code|html|<nowiki><!--</nowiki>}} is ignored. This is suitable for handling links embedded in template inputs,
where the {"PRE"} method will have already been applied by the native parser.
* {"BOTH"} applies {"PRE"} then {"POST"}.
]==]
function export.remove_comments(str, stage)
if not stage or stage == "PRE" then
return _remove_comments(str, true)
end
local processed = stage == "POST" and _remove_comments(str) or
stage == "BOTH" and _remove_comments(str, true) or
error("bad argument #2 to 'remove_comments' (expected PRE, POST, or BOTH)", 2)
while processed ~= str do
str = processed
processed = _remove_comments(str)
end
return str
end
end
do
local byte_escapes
local function get_byte_escapes()
byte_escapes, get_byte_escapes = load_data("Module:string utilities/data").byte_escapes, nil
return byte_escapes
end
local function escape_byte(b)
return (byte_escapes or get_byte_escapes())[b] or format("\\%03d", byte(b))
end
function export.escape_bytes(str)
return (gsub(str, ".", escape_byte))
end
end
function export.format_fun(str, fun)
return (gsub(str, "{(\\?)((\\?)[^{}]*)}", function(p1, name, p2)
if #p1 + #p2 == 1 then
return name == "op" and "{" or
name == "cl" and "}" or
error(mw.getCurrentFrame():getTitle() .. " format: unrecognized escape sequence '{\\" .. name .. "}'")
elseif fun(name) and type(fun(name)) ~= "string" then
error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" is a " .. type(fun(name)) .. ", not a string")
end
return fun(name) or error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" not found in table")
end))
end
format_fun = export.format_fun
--[==[
This function, unlike {string.format} and {mw.ustring.format}, takes just two parameters, a format string and a table,
and replaces all instances of { {param_name} } in the format string with the table's entry for {param_name}. The opening
and closing brace characters can be escaped with { {\op} } and { {\cl} }, respectively. A table entry beginning with a
slash can be escaped by doubling the initial slash.
====Examples====
* {string_utilities.format("{foo} fish, {bar} fish, {baz} fish, {quux} fish", {["foo"]="one", ["bar"]="two", ["baz"]="red", ["quux"]="blue"}) }
*: produces: {"one fish, two fish, red fish, blue fish"}
* {string_utilities.format("The set {\\op}1, 2, 3{\\cl} contains {\\\\hello} elements.", {["\\hello"]="three"})}
*: produces: {"The set {1, 2, 3} contains three elements."}
*:* Note that the single and double backslashes should be entered as double and quadruple backslashes when quoted in a literal string.
]==]
function export.format(str, tbl)
return format_fun(str, function(key)
return tbl[key]
end)
end
do
local function do_uclcfirst(str, case_func)
-- Re-case the first letter.
local first, remainder = match(str, "^(.[\128-\191]*)(.*)")
return first and (case_func(first) .. remainder) or ""
end
local function uclcfirst(str, case_func)
-- Strip off any HTML tags at the beginning. This currently does not handle comments or <ref>...</ref>
-- correctly; it's intended for text wrapped in <span> or the like, as happens when passing text through
-- [[Module:links]].
local html_at_beginning = nil
if str:match("^<") then
while true do
local html_tag, rest = str:match("^(<.->)(.*)$")
if not html_tag then
break
end
if not html_at_beginning then
html_at_beginning = {}
end
insert(html_at_beginning, html_tag)
str = rest
end
end
-- If there's a link at the beginning, re-case the first letter of the
-- link text. This pattern matches both piped and unpiped links.
-- If the link is not piped, the second capture (linktext) will be empty.
local link, linktext, remainder = match(str, "^%[%[([^|%]]+)%|?(.-)%]%](.*)$")
local retval
if link then
retval = "[[" .. link .. "|" .. do_uclcfirst(linktext ~= "" and linktext or link, case_func) .. "]]" .. remainder
else
retval = do_uclcfirst(str, case_func)
end
if html_at_beginning then
retval = concat(html_at_beginning) .. retval
end
return retval
end
--[==[
Uppercase the first character of the input string, correctly handling one-part and two-part links, optionally
surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly
uppercase the first character of text that may include links that have been passed through `full_link()` in
[[Module:links]] or a similar function.
]==]
function export.ucfirst(str)
return uclcfirst(str, uupper)
end
ucfirst = export.ucfirst
--[==[
Lowercase the first character of the input string, correctly handling one-part and two-part links, optionally
surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly
lowercase the first character of text that may include links that have been passed through `full_link()` in
[[Module:links]] or a similar function.
]==]
function export.lcfirst(str)
return uclcfirst(str, ulower)
end
--[==[Capitalizes each word of the input string. WARNING: May be broken in the presence of multiword links.]==]
function export.capitalize(str)
-- Capitalize multi-word that is separated by spaces
-- by uppercasing the first letter of each part.
return (ugsub(str, "%w+", ucfirst))
end
local function do_title_case(first, remainder)
first = uupper(first)
return remainder == "" and first or (first .. ulower(remainder))
end
--[==[
Capitalizes each word of the input string, with any further letters in each word being converted to lowercase.
]==]
function export.title_case(str)
return str == "" and "" or ugsub(str, "(%w)(%w*)", do_title_case)
end
title_case = export.title_case
--[==[
Converts the input string to {{w|Camel case|CamelCase}}. Any non-word characters are treated as breaks between
words. If `lower_first` is set, then the first character of the string will be lowercase (e.g. camelCase).
]==]
function export.camel_case(str, lower_first)
str = ugsub(str, "%W*(%w*)", title_case)
return lower_first and do_uclcfirst(str, ulower) or str
end
end
do
local function do_snake_case(nonword, word)
return nonword == "" and word or "_" .. word
end
--[==[
Converts the input string to {{w|Snake case|snake_case}}. Any non-word characters are treated as breaks between
words.
]==]
function export.snake_case(str)
return (ugsub(str, "(%W*)(%w*)", do_snake_case))
end
end
return export
fn24cxaalpvu0atd5b0gn3w2a16p2kn
Aragon
0
119391
394117
394107
2026-10-12T18:41:04Z
~2026-54721-68
9780
394117
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
'''Aragon''' {{hk.}}
#sjálfstjórnarsvæði á Spáni
===={{-þýðingar-}}====
{{þýðingar
|an= {{þýðing|an|Aragón}}
|ca= {{þýðing|ca|Aragó}}
|da= {{þýðing|da|Aragonien}}
|en= {{þýðing|en|Aragon}}
|fo= {{þýðing|fo|}}
|fr= {{þýðing|fr|Aragon}}
|nl= {{þýðing|nl|Aragón}}
|it= {{þýðing|it|Aragona}}
|la= {{þýðing|la|Aragonia}}
|no= {{þýðing|no|Aragón}}
|pt= {{þýðing|pt|Aragão}}
|es= {{þýðing|es|Aragón}}
|sv= {{þýðing|sv|Aragonien}}
|de= {{þýðing|de|Aragon}}, {{þýðing|de|Aragonien}}
|vec= {{þýðing|vec|Aragona}}
}}
==={{-framburður-|is}}===
*{{hljóðskrá|is-Aragon.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|is:Aragon|Aragon}}
=={{-en-}}==
==={{-en-nafnorð-}}===
'''Aragon'''
#[[#íslenska|Aragon]]
==={{-framburður-|en}}===
*{{hljóðskrá|en-Aragon.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|en:Aragon|Aragon}}
=={{-fr-}}==
==={{-fr-nafnorð-}}===
'''Aragon'''
#[[#íslenska|Aragon]]
==={{-framburður-|en}}===
*{{hljóðskrá|fr-Aragon.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|fr:Aragon|Aragon}}
m65mqcnpnbxojkrxa023xhrcbu1lk7b
Japanisch
0
119397
394136
2026-10-12T19:41:33Z
~2026-54721-68
9780
Bjó til síðu með „=={{-de-}}== ==={{-de-nafnorð-}}=== '''Japanisch''' {{hk.}} #[[Japanska]] ==={{-framburður-|de}}=== *{{hljóðskrá|De-Japanisch.ogg}} ==={{-tilvísun-}}=== *{{Wikipedia|de:Japanisch|Japanisch}} *{{Ref-Duden|Japanisch}} *{{til:de:DWDS|sótt=12. oktober 2026}}“
394136
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Japanisch''' {{hk.}}
#[[Japanska]]
==={{-framburður-|de}}===
*{{hljóðskrá|De-Japanisch.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|de:Japanisch|Japanisch}}
*{{Ref-Duden|Japanisch}}
*{{til:de:DWDS|sótt=12. oktober 2026}}
9pirjjgha6i24by8cd9srpbrd99iji0
Japanska
0
119398
394137
2026-10-12T20:13:51Z
~2026-54721-68
9780
Bjó til síðu með „=={{-is-}}== ==={{-is-nafnorð-}}=== '''Japanska''' {{hk.}}; {{no.s.b.}} #[[tungumál]] í [[Japan]] ===={{-þýðingar-}}==== {{þýðingar |af= {{þýðing|af|Japannees}} |als= {{þýðing|als|Japanisch}} |an= {{þýðing|an|chaponés}} |ast= {{þýðing|ast|xaponés}} |br= {{þýðing|br|japaneg}} |bar= {{þýðing|bar|Japanisch}} |da= {{þýðing|da|japansk}} |en= {{þýðing|en|Japanese}} |ext= {{þýðing|ext|japonés}} |fo= {{þýðing|fo|Japanskt}} |fr=...“
394137
wikitext
text/x-wiki
=={{-is-}}==
==={{-is-nafnorð-}}===
'''Japanska''' {{hk.}}; {{no.s.b.}}
#[[tungumál]] í [[Japan]]
===={{-þýðingar-}}====
{{þýðingar
|af= {{þýðing|af|Japannees}}
|als= {{þýðing|als|Japanisch}}
|an= {{þýðing|an|chaponés}}
|ast= {{þýðing|ast|xaponés}}
|br= {{þýðing|br|japaneg}}
|bar= {{þýðing|bar|Japanisch}}
|da= {{þýðing|da|japansk}}
|en= {{þýðing|en|Japanese}}
|ext= {{þýðing|ext|japonés}}
|fo= {{þýðing|fo|Japanskt}}
|fr= {{þýðing|fr|japonais}}
|frp= {{þýðing|frp|japonês}}
|nl= {{þýðing|nl|Japans}}
|it= {{þýðing|it|giapponese}}
|la= {{þýðing|la|}}
|no= {{þýðing|no|Japansk}}
|pt= {{þýðing|pt|}}
|es= {{þýðing|es|japonés}}
|sv= {{þýðing|sv|japanska}}
|de= {{þýðing|de|Japanisch}}
}}
===={{-tilvísun-}}====
*{{Wikipedia|is:Japanska|Japanska}}
*{{Ref-IcelandicOnlineDictionary|Japanska}}
*{{Ref-Orðabók Háskólans|Japanska}}
e1xx9wq6fxyokqkkjy9r71tcx0l8ibt
Indonesian
0
119399
394148
2026-10-12T20:37:57Z
~2026-54721-68
9780
Bjó til síðu með „=={{-en-}}== ==={{-en-nafnorð-}}=== '''Indonesian''' #[[Indónesíska]] ==={{-framburður-|en}}=== *{{hljóðskrá|en-Indonesian.ogg}} ==={{-tilvísun-}}=== *{{Wikipedia|en:Indonesian|Indonesian}} =={{-oc-}}== ==={{-oc-nafnorð-}}=== '''Indonesian''' #[[Indónesíska]] ==={{-framburður-|oc}}=== *{{hljóðskrá|oc-Indonesian.ogg}} ==={{-tilvísun-}}=== *{{Wikipedia|oc:Indonesian|Indonesian}}“
394148
wikitext
text/x-wiki
=={{-en-}}==
==={{-en-nafnorð-}}===
'''Indonesian'''
#[[Indónesíska]]
==={{-framburður-|en}}===
*{{hljóðskrá|en-Indonesian.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|en:Indonesian|Indonesian}}
=={{-oc-}}==
==={{-oc-nafnorð-}}===
'''Indonesian'''
#[[Indónesíska]]
==={{-framburður-|oc}}===
*{{hljóðskrá|oc-Indonesian.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|oc:Indonesian|Indonesian}}
a32e641x4bth6wim2jfz4dg2wekyykj
Laotisch
0
119400
394164
2026-10-12T21:16:53Z
~2026-54721-68
9780
Bjó til síðu með „=={{-de-}}== ==={{-de-nafnorð-}}=== '''Laotisch''' #[[laoska]], [[lao]] ==={{-framburður-|de}}=== *{{hljóðskrá|De-Laotisch.ogg}} ==={{-tilvísun-}}=== *{{Wikipedia|de:Laotisch|Laotisch}} *{{Ref-Duden|Laotisch}} *{{til:de:DWDS|sótt=12. oktober 2026}}“
394164
wikitext
text/x-wiki
=={{-de-}}==
==={{-de-nafnorð-}}===
'''Laotisch'''
#[[laoska]], [[lao]]
==={{-framburður-|de}}===
*{{hljóðskrá|De-Laotisch.ogg}}
==={{-tilvísun-}}===
*{{Wikipedia|de:Laotisch|Laotisch}}
*{{Ref-Duden|Laotisch}}
*{{til:de:DWDS|sótt=12. oktober 2026}}
58k995yd9n63v29jot6a47z2pmerbm6