Wikikamus
mswiktionary
https://ms.wiktionary.org/wiki/Wikikamus:Laman_Utama
MediaWiki 1.47.0-wmf.21
case-sensitive
Media
Khas
Perbincangan
Pengguna
Perbincangan pengguna
Wikikamus
Perbincangan Wikikamus
Fail
Perbincangan fail
MediaWiki
Perbincangan MediaWiki
Templat
Perbincangan templat
Bantuan
Perbincangan bantuan
Kategori
Perbincangan kategori
Lampiran
Perbincangan lampiran
Rima
Perbincangan rima
Tesaurus
Perbincangan tesaurus
Indeks
Perbincangan indeks
Petikan
Perbincangan petikan
Rekonstruksi
Perbincangan rekonstruksi
Padanan isyarat
Perbincangan padanan isyarat
Konkordans
Perbincangan konkordans
TimedText
TimedText talk
Modul
Perbincangan modul
Acara
Perbincangan acara
Wikikamus:Kedai Kopi
4
890
375871
373883
2026-09-25T12:48:35Z
MediaWiki message delivery
2382
/* Your feedback wanted: Remove (Language link added:) and similar edits from Special:RecentChanges */ bahagian baru
375871
wikitext
text/x-wiki
{{KedaiKopi}}
__NEWSECTIONLINK__
== Thank You for Last Year – Join Wiki Loves Ramadan 2026 ==
Dear Wikimedia communities,
We hope you are doing well, and we wish you a happy New Year.
''Last year, we captured light. This year, we’ll capture legacy.''
In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects.
We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community.
📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]]
If you have questions about the project, please refer to the FAQs:
* [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]]
* [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]]
''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]'''''
''Stay connected and receive updates:''
* [https://t.me/WikiLovesRamadan Telegram channel]
* [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list]
We look forward to collaborating with you and your community.
'''The Wiki Loves Ramadan 2026 Organizing Team''' 19:45, 16 Januari 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:ZI Jony@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 -->
== <span lang="en" dir="ltr">Annual review of the Universal Code of Conduct and Enforcement Guidelines</span> ==
<div lang="en" dir="ltr">
<section begin="announcement-content" />
I am writing to you to let you know the annual review period for the Universal Code of Conduct and Enforcement Guidelines is open now. You can make suggestions for changes through 9 February 2026. This is the first step of several to be taken for the annual review. [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|Read more information and find a conversation to join on the UCoC page on Meta]].
The [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Universal Code of Conduct Coordinating Committee]] (U4C) is a global group dedicated to providing an equitable and consistent implementation of the UCoC. This annual review was planned and implemented by the U4C. For more information and the responsibilities of the U4C, [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|you may review the U4C Charter]].
Please share this information with other members in your community wherever else might be appropriate.
-- In cooperation with the U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]])<section end="announcement-content" />
</div>
21:02, 19 Januari 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Keegan (WMF)@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 -->
== Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) ==
Hello everyone,
This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>).
'''The Change:'''<br />
Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]].
We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''.
'''What You Need To Do:'''<br />
To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search.
'''Deadline:'''<br />
We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles.
Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Pengguna:MediaWiki message delivery|MediaWiki message delivery]] ([[Perbincangan pengguna:MediaWiki message delivery|bincang]]) 17:11, 3 April 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:ZI Jony@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 -->
== Usul pemasukan bot PEACESEEKERS-BOT ==
Saya telah bangunkan sebuah bot bernama PEACESEEKERS-BOT berasaskan Pywikibot yang bertujuan untuk uruskan kategori-kategori Wikikamus. Setelah [[Khas:Sumbangan/PEACESEEKERS-BOT|sedikit pengujian]] yang nampaknya berjaya, saya ingin dapatkan pendapat kalian untuk "merasmikan" bot ini dengan [[meta:Steward_requests/Bot_status|status bot]]. Status rasmi ini membolehkan bot ini menjalankan fungsinya dengan lebih lancar. Harap maklum dan terima kasih. [[Pengguna:PeaceSeekers|PeaceSeekers]] ([[Perbincangan pengguna:PeaceSeekers|bincang]]) 07:04, 6 April 2026 (UTC)
:{{undi|Y}} '''[[Pengguna:Hakimi97|محمد حكيمي]]''' ([[Perbincangan pengguna:Hakimi97|bincang]]) 07:28, 6 April 2026 (UTC)
:{{Undi|y}} [[Pengguna:EmpAhmadK|EmpAhmadK]] ([[Perbincangan pengguna:EmpAhmadK|bincang]]) 09:05, 6 April 2026 (UTC)
:Nampak ok. [[Pengguna:Aurora|...Aurora...]] ([[Perbincangan pengguna:Aurora|bincang]]) 07:58, 12 April 2026 (UTC)
== Request for comment (global AI policy) ==
<bdi lang="en" dir="ltr" class="mw-content-ltr">
Apologies for writing in English. {{int:Please-translate}}
A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}}
[[Pengguna:MediaWiki message delivery|MediaWiki message delivery]] ([[Perbincangan pengguna:MediaWiki message delivery|bincang]]) 00:58, 26 April 2026 (UTC)
</bdi>
<!-- Pesanan dihantar oleh Pengguna:Codename Noreste@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 -->
== Undi sekarang dalam pemilihan U4C 2026 ==
<section begin="announcement-content" />
Pemilih yang layak akan ditanya untuk menyertai pemilihan [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Jawatankuasa Penyelaras Tatakelakuan Sejagat]] 2026. Maklumat lanjut–termasuk pemeriksaan kelayakan, maklumat proses mengundi, maklumat calon, dan pautan ke undi–tersedia di Meta di [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|laman maklumat Pemilihan 2026]]. Undi tutup pada 2 Jun 2026 pada [https://zonestamp.toolforge.org/1780358400 00:00 UTC].
Sila undi jika akaun anda layak. Hasil akan tersedia pada 14 Jun 2026. -- Dengan kerjasama U4C,<section end="announcement-content" />
[[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 17:15, 27 Mei 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Keegan (WMF)@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 -->
== RFC about AI-generated content in Wikimedia Commons ==
<bdi lang="en" dir="ltr">Apologies for writing in English, please help translate this message to your language. You are invited to participate in a [[c:Commons:Requests for comment/Policy update for AI content|request for comment on Wikimedia Commons about a policy update for AI content]]. This may affect files that are uploaded to Wikimedia Commons for use on this project. Thank you. [[m:User:Codename Noreste|Codename Noreste]] ([[m:User talk:Codename Noreste|bincang]])</bdi> 17:12, 23 Jun 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Codename Noreste@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 -->
== Pelaksanaan Pautan Maklumat Perhubungan Undang-undang dan Keselamatan di Bahagian Pembawah Wiki Anda ==
<section begin="Message"/>
'''Maklumat Perhubungan Undang-undang & Keselamatan'''
Helo komuniti, Wikimedia Foundation telah menyediakan satu [[wmf:Special:MyLanguage/Legal:Wikimedia Foundation Legal and Safety Contact Information|halaman tunggal maklumat perhubungan undang-undang dan keselamatan]] untuk dipautkan di bahagian pembawah wiki anda bagi memastikan akses kepada maklumat undang-undang yang tepat. Ini merupakan keperluan peraturan. Kami telah pun melaksanakan pautan ini di wiki Bahasa Inggeris, Jerman, Itali, Sepanyol dan lain-lain dan kami akan melaksanakannya di wiki anda tidak lama lagi. [[m:Special:MyLanguage/Wikimedia_Foundation_Legal_and_Safety_Contacts_FAQ|Sila baca lanjut di halaman projek]] dan tinggalkan sebarang komen dalam perbincangan ini atau di [[m:Special:MyLanguage/Talk:Wikimedia Foundation Legal and Safety Contacts FAQ|halaman perbincangan]].
<section end="Message"/>
-- [[User:Sannita (WMF)|User:Sannita (WMF)]] ([[User talk:Sannita (WMF)|talk]]) 13:31, 25 Jun 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Sannita (WMF)@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=User:Sannita_(WMF)/Mass_sending_test&oldid=30731267 -->
== [[:Wikikamus:Bahasa Korea]] ==
Salam sejahtera. Saya telah menemui ralat atau masalah dengan [[Wikikamus:Bahasa Korea]].
1. Halaman [[Wikikamus:Bahasa Korea]] tidak mempunyai beberapa halaman yang terdapat dalam [[Khas:Indeks_awalan/Wikikamus:ko]], kerana ia tidak mempunyai apa-apa yang datang selepas [[Wikikamus:ko/소년]].
2. [[Wikikamus:ko/돜]] harus dipindahkan ke [[Wikikamus:ko/독]] tanpa meninggalkan pengalihan, kerana "돜" bukan perkataan Korea, dan "독" ialah perkataan Korea untuk "racun".
3. Begitu juga, [[Wikikamus:ko/뒤쫓다다]] harus dipindahkan ke [[Wikikamus:ko/뒤쫓다]] tanpa meninggalkan pengalihan.
Sila betulkan isu ini. [[Pengguna:Intolerable situation|Intolerable situation]] ([[Perbincangan pengguna:Intolerable situation|bincang]]) 09:13, 2 Julai 2026 (UTC)
== Request for comment (the future of Abstract Wikipedia) ==
<bdi lang="en" dir="ltr" class="mw-content-ltr">
Apologies if this has not yet been translated into your wiki's language. {{int:Please-translate}}
You are invited to voice your opinions in a [[:m:Requests for comment/The future of Abstract Wikipedia|request for comment about the future of Abstract Wikipedia]]. {{Int:Feedback-thanks-title}}
[[:m:User:Kowal2701|Kowal2701]] ([[:m:User talk:Kowal2701|talk]]) 12:25, 24 Julai 2026 (UTC)
</bdi>
<!-- Pesanan dihantar oleh Pengguna:DreamRimmer@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 -->
== [[Modul:language utilities]] ==
This module not used any pages in Wiktionary. Please delete module with reason "use [[Module:languages/templates]] and [[Module:families/templates]] instead". [[User:Hiyuune|<span style="font-family: Segoe UI Light;color:#FF69B4;letter-spacing:">Linh Huynh</span>]] ([[User talk:Hiyuune|<span style="color:#008080;">talk</span>]]) 15:09, 29 Julai 2026 (UTC)
== Pertukaran pelayan - Wiki anda akan berada dalam mod baca sahaja tidak lama lagi ==
<section begin="server-switch"/><div class="plainlinks">
[[:m:Special:MyLanguage/Tech/Server switch|Baca pesanan ini dalam bahasa lain]] • [https://meta.wikimedia.org/w/index.php?title=Special:Translate&group=page-Tech%2FServer+switch&language=&action=page&filter= {{int:please-translate}}]
[[foundation:|Yayasan Wikimedia]] akan mengalihkan lalu lintas di antara pusat datanya. Ini akan memastikan Wikipedia dan wiki-wiki Wikimedia yang lain boleh kekal dalam talian walaupun selepas berlakunya bencana.
Semua trafik akan beralih pada '''{{#time:j xg|2026-09-23|ms}}'''. Ujian akan bermula pada '''[https://zonestamp.toolforge.org/{{#time:U|2026-09-23T14:00|en}} {{#time:H:i e|2026-09-23T14:00}}]'''.
Malangnya, kerana beberapa perbatasan di [[mw:Special:MyLanguage/Manual:What is MediaWiki?|MediaWiki]], semua penyuntingann mesti dihentikan apabila pertukaran dibuat. Kami memohon maaf atas gangguan ini, dan kami berusaha meminimumkannya pada masa hadapan.
Sepanduk akan dipaparkan di semua wiki 30 minit sebelum pengendalian ini berlaku. Bendera ini akan kekal kelihatan sehingga akhir operasi.
Anda boleh menyumbang kepada [https://meta.wikimedia.org/w/index.php?title=Special%3ATranslate&group=Centralnotice-tgroup-read_only_banner&task=view&language=&filter=&action=translate terjemahan atau pembacaprufan] teks banner ini.
'''Anda akan dapat membaca, tetapi tidak menyunting, semua wiki buat tempoh masa yang pendek.'''
* Anda tidak akan dapat menyunting sehingga sejam pada {{#time:l j xg Y|2026-09-23|ms}}.
* Jika anda cuba menyunting atau menyimpan semasa waktu-waktu ini, anda akan nampak pesanan ralat. Kami berharap tiada suntingan akan hilang semasa minit tersebut, tetapi kami tidak boleh menjaminkannya. Jika anda nampak pesanan ralat, selepas itu sila tunggu sehingga semuanya kembali normal. Kemudian anda patut dapat menyimpan suntingan anda. Namun, kami syorkan anda membuat salinan perubahan anda dahulu, kalau-kalaulah.
''Kesan lain'':
* Kerja latar belakang akan menjadi lebih perlahan dan beberapa mungkin digugurkan. Pautan merah mungkin tidak dikemas kini secepat yang biasa. Jika anda mencipta rencana yang sudah dipaut di mana-mana, pautan akan kekal merah lebih panjang daripada biasa. Beberapa skrip sedang jalan lama akan perlu dihentikan.
* Kami menjangkakan kerah tugas kod berlaku seperti mana-mana minggu yang lain. Walau bagaimanapun, beberapa beku kod kes demi kes boleh berlaku tepat masanya jika pengendalian memerlukannya selepas itu.
* [[mw:Special:MyLanguage/GitLab|GitLab]] akan tidak tersedia selama 90 minit.
Projek ini boleh ditunda jika perlu. Anda boleh [[wikitech:Switch_Datacenter|baca jadual di wikitech.wikimedia.org]]. Sebarang perubahan akan diumumkan dalam jadual.
'''Tolong kongsikan maklumat ini dengan komuniti anda.'''</div><section end="server-switch"/>
[[m:user:Trizek (WMF)|Trizek (WMF)]] 12:58, 15 September 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Trizek (WMF)@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=30513874 -->
== Your feedback wanted: Remove ''(Language link added:) and similar'' edits from Special:RecentChanges ==
''(Apologies for posting in English. You can help by translating it)''
Hello, I’m Danny from [[:en:w:Wikimedia_Deutschland|Wikimedia Deutschland’s]] [[m:Wikidata_For_Wikimedia_Projects|Wikidata For Wikimedia Projects]] team.<br/>
We have been investigating and examining how Wikidata’s use in the [[Special:RecentChanges]] and [[Special:Watchlist]] pages can be made to be more useful, or less ‘noisy’ (fewer edits that have little value to the reader).
We are currently exploring to make a change in the volume and the type of Wikidata edits that appear in these pages, and '''we need your feedback''' to help us ensure this is a positive change for the Wikis and won’t disrupt your workflows.<br/>
Language links are also known as sitelinks or interlanguage links and describe when a Wikidata item is connected to a Wiki, adding it to the language dropdown tool for other connected Wikis.
[[File:Types of Lang Link changes.png|x350px|frame|A variety of "Language Link" edits as seen in the Recent Changes feed]]
The request for feedback is whether you support the removal of these language link edits from the Recent Changes and Watchlist feed, or would you oppose such a change and if so, why?
Please share you thoughts on the dedicated '''[[m:Talk:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Hide_Language_Link_edits|metawiki Talk page]]'''.
Further information about this change: [[m:Wikidata_For_Wikimedia_Projects/Clearer_Wikidata_Edit_Summaries/Hide_Language_Link_edits|m:Wikidata_For_Wikimedia_Projects/Hide_Language_Link_edits]]
Thank you for any participation or feedback you give, -- [[m:User:Danny_Benjafield_(WMDE)|User:Danny Benjafield (WMDE)]] 12:48, 25 September 2026 (UTC)
<!-- Pesanan dihantar oleh Pengguna:Danny Benjafield (WMDE)@metawiki yang menggunakan senarai di https://meta.wikimedia.org/w/index.php?title=User:Danny_Benjafield_(WMDE)/MassMessage_test_list&oldid=31081007 -->
b6ct5d10j25qqcg9ptaomhht82lf8tz
alas
0
3755
375891
346932
2026-09-26T02:30:02Z
Hakimi97
2668
/* Kata nama */ Noun > Kata nama
375891
wikitext
text/x-wiki
{{Pautan Projek Wikimedia}}
==Bahasa Melayu==
===Kata nama===
{{ms-kn}}
# benda yang menjadi [[lapik]] tempat meletakkan suatu benda lain, [[asas]], [[dasar]].
# kain dan sebagainya yang digunakan untuk [[tutup|menutup]] sesuatu, lapik, tutup.
====Kata terbitan====
* beralas:
*# memakai alas, berlapik.
*# mempunyai asas, berasas.
* mengalas: memberi beralas.
* alasan:
*# asas, dasar.
*# sesuatu yang dijadikan asas atau dasar bagi sesuatu, pendapat, sebab.
*# sesuatu yang dijadikan sebagai alas.
===Etimologi===
<!-- Anda boleh membantu! -->
===Sebutan===
{{dewan|a|las}}
===Tulisan Jawi===
{{ARchar|الس}}
===Terjemahan===
{{ter-atas|asas, dasar}}
* Arab: {{ARchar|أساس}} , {{ARchar|قاعدة}} {{f}}
* Belanda: basis {{f}}
* Catalan: base {{f}}, fonament
* Finland: perustus, pohja
* Ibrani: בסיס (basys)
* Inggeris: base, foundation
* Itali: basi {{f}} ''jamak''
* Jerman: Basis {{f}}, Grundlage {{f}}
* Kurdi: {{KUchar|بنکه}}
* Perancis: base
* Portugis: base {{f}}
* Slovenia: temelj
* Sepanyol: base {{f}}
* Sweden: grund
* Turki: temel
* Telugu: పీఠం
{{ter-bawah}}
{{ter-atas|lapik, tutup}}
* Afrikaan: dekking
* Albania: kapak
* Belanda: deksel {{n}}
* Catalan: tapa {{f}}
* Croatia: poklopac
* Esperanto: tegilo, fermoplato
* Finland: kansi
* Hungary: fedő, fedél
* Inggeris: cover, lid
* Itali: coperto , coperchio
* Jerman: Deckel , Abdeckung {{f}}
* Kurdi: {{KUchar|سهرقاپ}}
* Portugis: tampa {{f}}
* Rusia: крышка (krýška) {{f}}
* Slovenia: pokrov , pokrovka {{f}}
* Sepanyol: tapa , cubierta {{f}}
* Sweden: lock {{n}}, skydd {{n}}
* Telugu: మూత (mootha)
* Turki: kapak
{{ter-bawah}}
===Tesaurus===
; Sinonim: ganjal, landasan, lapik, lapisan, seperah, tikar.
==Bahasa Indonesia==
* Lihat takrifan bahasa Melayu.
==Bahasa Jawa==
===Kata nama===
{{inti|jv|kata nama}}
# {{lb|jv|Selangor}} hutan {{jv-kn|n=alas|k=wana}}
#: {{cp|jv|ing '''alas''' akeh macan lan menjangan.|di '''hutan''' banyak harimau dan rusa.}}
===Sinonim===
====Hutan====
* [[wana]] {{lb|jv|krama}}
===Sebutan===
* {{penyempangan|jv|a|las}}
===Tulisan Jawa===
* Hanacaraka: <big>[[ꦲꦭꦱ꧀]]</big>
==Bahasa Sunda==
===Etimologi===
Dari {{inh|su|osn|alas}}, dari {{inh|su|poz-pro|*halas|t=hutan, hutan liar, lipur, semak}}, dari {{inh|su|map-pro|*Salas|t=hutan, hutan liar, semak}}.
===Kata nama===
{{head|su|kata nama|Skrip bahasa Sunda|ᮃᮜᮞ᮪}}
# [[hutan]]
#: {{syn|su|leuweung}}
ds2c2azxs5weuqjedrj50h1sx8n8dgw
abuya
0
8911
376222
333790
2026-09-26T11:21:14Z
Hakimi97
2668
/* Etimologi */ Betulkan templat
376222
wikitext
text/x-wiki
{{Pautan Projek Wikimedia}}
==Bahasa Melayu==
===Kata nama===
{{ms-kn}}
# Ayah.
# Panggilan hormat kepada orang yang ajarannya (biasanya ajaran agama Islam) atau pendapatnya diikuti.
===Etimologi===
{{bor+|ms|ar|-}}.
===Sebutan===
{{dewan|a|bu|ya}}
===Tulisan Jawi===
{{ARchar|ابوي}}
===Tesaurus===
; Sinonim: [[abah]], [[ayah]], [[bapa]].
edr0onf9w9wxrkba2l0shz64xbiaarm
Modul:languages/templates
828
10016
376230
223663
2026-09-26T11:53:38Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/92778053|92778053]])
376230
Scribunto
text/plain
local export = {}
local concat = table.concat
local insert = table.insert
local sort = table.sort
local scripts_module = "Module:scripts"
local function get_script_by_code(...)
get_script_by_code = require(scripts_module).getByCode
return get_script_by_code(...)
end
function export.exists(frame)
return require("Module:languages").getByCode(
require("Module:parameters").process(frame.args, {
[1] = {required = true}
})[1]
) and "1" or ""
end
do
local function getByCode(frame, allow_etym)
local plain = true
local args = require("Module:parameters").process(frame.args, {
[1] = {required = true, type = allow_etym and "language" or "full language"},
[2] = {required = true},
[3] = plain,
[4] = plain,
[5] = plain,
})
local function check_empty(...)
local varargs = {...}
for i = 1, select("#", ...) do
if args[varargs[i]] then
error(("Cannot specify a value for argument %s= when using subfunction '%s' of getByCode()"):format(
varargs[i], args[2]))
end
end
end
return require("Module:language-like").templateGetByCode(args,
function(itemname)
local list
if itemname == "getWikimediaLanguages" then
list = args[1]:getWikimediaLanguages()
elseif itemname == "getScripts" then
list = args[1]:getScriptCodes()
elseif itemname == "getAncestors" then
list = args[1]:getAncestors()
end
if list then
check_empty(4, 5)
local retval = list[tonumber(args[3]) or error("Please specify the numeric index of the desired item in 3=.")]
if retval then
if type(retval) == "string" then
return retval
else
return retval:getCode()
end
else
return ""
end
end
if itemname == "transliterate" then
local sc = get_script_by_code(args[4])
return (args[1]:transliterate(args[3], sc, args[5])) or ""
elseif itemname == "makeDisplayText" then
local sc = get_script_by_code(args[4])
check_empty(5)
return (args[1]:makeDisplayText(args[3], sc)) or ""
elseif itemname == "makeEntryName" then
-- FIXME, find places that use makeEntryName and convert to stripDiacritics
local sc = get_script_by_code(args[4])
check_empty(5)
return args[1]:makeEntryName(args[3], sc) or ""
elseif itemname == "stripDiacritics" then
local sc = get_script_by_code(args[4])
check_empty(5)
return args[1]:stripDiacritics(args[3], sc) or ""
elseif itemname == "makeSortKey" then
local sc = get_script_by_code(args[4])
check_empty(5)
return (args[1]:makeSortKey(args[3], sc)) or ""
elseif itemname == "logicalToPhysical" then
check_empty(4, 5)
return args[1]:logicalToPhysical(args[3]) or ""
elseif itemname == "countCharacters" then
local sc = get_script_by_code(args[4])
check_empty(5)
return sc:countCharacters(args[3] or "")
elseif itemname == "findBestScript" then
check_empty(5)
return args[1]:findBestScript(args[3] or "", args[4]):getCode()
elseif itemname == "getCategoryName" then
return args[1]:getCategoryName(args[3] == "nocap") or ""
end
end
)
end
-- Used by the following JS:
-- * [[WT:ACCEL]]
-- * [[WT:EDIT]]
-- * [[WT:NEC]]
function export.getByCode(frame)
return getByCode(frame, false)
end
function export.getByCodeAllowEtym(frame)
return getByCode(frame, true)
end
end
function export.getByCanonicalName(frame)
return require("Module:parameters").process(frame.args, {
[1] = {required = true, type = "language", method = "name"}
})[1]:getCode() or ""
end
function export.getCanonicalName(frame)
local args = require("Module:parameters").process(
require("Module:yesno")(frame.args.parent) and frame:getParent().args or frame.args,
{
[1] = {required = true},
["return_if_invalid"] = {type = "boolean"},
}
)
local lang = require("Module:languages").getByCode(args[1], nil, true)
return lang and lang:getCanonicalName() or not args.return_if_invalid and "" or args[1]
end
function export.getFull(frame)
local args = require("Module:parameters").process(
require("Module:yesno")(frame.args.parent) and frame:getParent().args or frame.args,
{
[1] = {required = true, type = "language"},
}
)
return args[1]:getFullCode()
end
function export.getChildren(frame)
local args = require("Module:parameters").process(
require("Module:yesno")(frame.args.parent) and frame:getParent().args or frame.args,
{
[1] = {required = true, type = "language"},
}
)
local children = args[1]:getChildren()
sort(children, function(a, b)
return a:getCanonicalName() < b:getCanonicalName()
end)
local list = {}
for _, child in ipairs(children) do
insert(list, "* " .. child:makeWikipediaLink() .. ": " .. "<code>" .. child:getCode() .. "</code>")
end
return concat(list, "\n")
end
return export
3ctb71guoz9p03m69whwaqjjiqcn4m9
Modul:labels
828
10141
375904
232738
2026-09-26T07:22:20Z
SNN95
2113
375904
Scribunto
text/plain
local export = {}
export.lang_specific_data_list_module = "Module:labels/data/lang"
export.lang_specific_data_modules_prefix = "Module:labels/data/lang/"
local load_module = "Module:load"
local parse_utilities_module = "Module:parse utilities"
local string_utilities_module = "Module:string utilities"
local utilities_module = "Module:utilities"
local insert = table.insert
local concat = table.concat
local require_when_needed = require("Module:require when needed")
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local dump = mw.dumpObject
local m_lang_specific_data = mw.loadData(export.lang_specific_data_list_module)
local m_table = require_when_needed("Module:table")
--[==[ intro:
Labels go through several stages of processing to get from the original (raw) label specified in the Wikicode to the
final (formatted) label displayed to the user. The following terminology will help keep things straight:
* The "raw label" is the label specified in the Wikicode.
* The "non-canonical label" is the label extracted from the raw label, used for looking up in the label modules in order
to fetch the associated label data structure and determine the canonical form of the label. Normally this is the same
as the raw label, but it will be different if the raw label is of the form `!<var>label</var>` (e.g. `!Australian`)
`<var>label</var>!<var>display</var>` (e.g. `Southern US!Southern`). The former syntax indicates that the label
should display as-is instead of in its canonical form (which in the example given is `Australia`), and the latter
syntax indicates that the label should display in the form specified after the exclamation point.
* The "canonical label" is the result of applying alias resolution to the non-canonical label. Normally, the
canonical label rather than the non-canonical label is what is shown to the user.
* The "display form of the label" is what is shown to the user, not considering links and HTML that may wrap the
display form to get the formatted form of the label. The display form comes from the `.display` field of the module
label data for the label; if no such field exists in the label data, it is normally the canonical label. However, if
the display override exists (see below), it takes precedence over the `.display` field or canonical label when
determining the display form of the label.
* The "display override", if specified, overrides all other means of determining the display form of the label. It is
specified in two circumstances, i.e. in the `!<var>label</var>` and `<var>label</var>!<var>display</var>` raw label
formats (i.e. in the same cirumstances where the raw label and non-canonical label are different).
* The "formatted form of the label" is the final form of the label shown directly to the user. It generally appears to
the user as the display form of the label, but in the Wikicode, the formatted form may wrap the display form with a
link to Wikipedia, the Wiktionary glossary or another Wiktionary entry, and that link in turn may be wrapped in an
HTML span with a "deprecated" CSS class attached, causing the label to display differently (to indicate that it is
deprecated).
]==]
-- for testing
local force_cat = false
local m_headword_data = mw.loadData("Module:headword/data")
local SUBPAGENAME = m_headword_data.pagename
-- Disable tracking on heavy pages to save time.
local pages_where_tracking_is_disabled = m_headword_data.large_pages
-- Add tracking category for PAGE. The tracking category linked to is [[Wiktionary:Tracking/labels/PAGE]].
-- We also add to [[Wiktionary:Tracking/labels/PAGE/LANGCODE]] and [[Wiktionary:Tracking/labels/PAGE/MODE]] if
-- LANGCODE and/or MODE given.
local function track(page, langcode, mode)
if pages_where_tracking_is_disabled[SUBPAGENAME] then
return true
end
-- avoid including links in pages (may cause error)
page = page:gsub("%[", "("):gsub("%]", ")"):gsub("|", "!")
require("Module:debug/track")("labels/" .. page)
if langcode then
require("Module:debug/track")("labels/" .. page .. "/" .. langcode)
end
if mode then
require("Module:debug/track")("labels/" .. page .. "/" .. mode)
end
-- We don't currently add a tracking label for both langcode and mode to reduce the total number of labels, to
-- save some memory.
return true
end
local function ucfirst(txt)
return mw.getContentLanguage():ucfirst(txt)
end
local mode_to_outer_class = {
["label"] = "usage-label-sense",
["term-label"] = "usage-label-term",
["accent"] = "usage-label-accent",
["form-of"] = "usage-label-form-of",
}
local mode_to_property_prefix = {
["label"] = false,
["term-label"] = false, -- handled specially
["accent"] = "accent_",
["form-of"] = "form_of_",
}
local function validate_mode(mode)
mode = mode or "label"
if not mode_to_outer_class[mode] then
local allowed_values = {}
for key, _ in pairs(mode_to_outer_class) do
insert(allowed_values, "'" .. key .. "'")
end
table.sort(allowed_values)
error(("Invalid value '%s' for `mode`; should be one of %s"):format(mode, concat(allowed_values, ", ")))
end
return mode
end
local function getprop(labdata, mode, prop)
local mode_prefix = mode_to_property_prefix[mode]
return mode_prefix and labdata[mode_prefix .. prop] or labdata[prop]
end
local function check_type(label, lang, prop, value, expected_types)
if value == nil or expected_types == nil then
return value
end
if type(expected_types) ~= "table" then
expected_types = {expected_types}
end
local valtype = type(value)
local matches = false
for _, expected_type in ipairs(expected_types) do
if type(expected_type) == "string" then
if valtype == expected_type then
matches = true
break
end
elseif value == expected_type then
matches = true
break
end
end
if not matches then
local function join_untagged_or(elements)
return m_table.serialCommaJoin(elements, {conj = "or", dontTag = true})
end
local quoted_types = {}
local quoted_values = {}
for _, expected_type in ipairs(expected_types) do
if type(expected_type) == "string" then
insert(quoted_types, "'" .. expected_type .. "'")
else
insert(quoted_values, "'" .. dump(expected_type) .. "'")
end
end
local possible_matches = {}
if quoted_types[1] then
insert(possible_matches, ("be of type%s %s"):format(
quoted_types[2] and "s" or "", join_untagged_or(quoted_types)))
end
if quoted_values[1] then
insert(possible_matches, ("have the value%s %s"):format(
quoted_values[2] and "s" or "", join_untagged_or(quoted_values)))
end
error(("Internal error: For label '%s', langcode '%s', property '%s' should %s but is of type '%s' with value %s"):format(
label, lang and lang:getCode() or "UNKNOWN", prop, join_untagged_or(possible_matches), valtype, dump(value)))
end
end
-- HACK! For languages in any of the given families, check the specified-language Wikipedia for appropriate
-- Wikipedia articles for the language in question (esp. useful for obscure etymology-only languages that may not
-- have English articles for them, like many Chinese lects).
local families_to_wikipedia_languages = {
{"zhx", "zh"},
{"sem-arb", "ar"},
}
--[==[
Given language `lang` (a full language, etymology-language or family), fetch a list of Wikimedia languages to check
when converting a Wikidata item to a Wikipedia article. English is always first, followed by the Wikimedia language
code(s) of `lang` if `lang` is a language (which may or may not be the same as `lang`'s Wiktionary code), followed
by the macrolanguage of `lang` for certain languages and families (currently, only languages and families in the Chinese
and Arabic families). If `lang` is nil, only return English. Note that the same code may occur more than once in the
list. This is exported because it's also used by [[Module:category tree/lects]].
]==]
function export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang)
local wikipedia_langs = {}
insert(wikipedia_langs, "en")
if lang then
local article_lang = lang
while article_lang do
if article_lang:hasType("language") then
local wmcodes = article_lang:getWikimediaLanguageCodes()
for _, wmcode in ipairs(wmcodes) do
insert(wikipedia_langs, wmcode)
end
end
article_lang = article_lang:getParent()
end
for _, family_to_wp_lang in ipairs(families_to_wikipedia_languages) do
local family, wp_lang = unpack(family_to_wp_lang)
if lang:inFamily(family) then
insert(wikipedia_langs, wp_lang)
end
end
end
return wikipedia_langs
end
--[==[
Fetch the categories to add to a page, given that the label whose canonical form is `canon_label` with language `lang`
has been seen. `labdata` is the label data structure for `label`, fetched from the appropriate submodule. `mode`
specifies how the label was invoked (see {get_label_info()} for more information). The return value is a list of the
actual categories, unless `for_doc` is specified, in which case the categories returned are marked up for display on a
documentation page. If `for_doc` is given, `lang` may be nil to format the categories in a language-independent fashion;
otherwise, it must be specified. If `category_types` is specified, it should be a set object (i.e. with category types
as keys and {true} as values), and only categories of the specified types will be returned.
]==]
function export.fetch_categories(canon_label, labdata, lang, mode, for_doc, category_types)
local categories = {}
mode = validate_mode(mode)
local langcode, canonical_name
if lang then
langcode = lang:getFullCode()
canonical_name = lang:getFullName()
elseif for_doc then
langcode = "<var>[langcode]</var>"
canonical_name = "<var>[language name]</var>"
else
error("Internal error: Must specify `lang` unless `for_doc` is given")
end
local function labprop(prop, expected_types)
local retval = getprop(labdata, mode, prop)
check_type(canon_label, lang, prop, retval, expected_types)
return retval
end
local empty_list = {}
local function get_cats(cat_type)
if category_types and not category_types[cat_type] then
return empty_list
end
local cats = labprop(cat_type)
if not cats then
return empty_list
end
if type(cats) ~= "table" then
return {cats}
end
return cats
end
local topical_categories = get_cats("topical_categories")
local sense_categories = get_cats("sense_categories")
local pos_categories = get_cats("pos_categories")
local regional_categories = get_cats("regional_categories")
local plain_categories = get_cats("plain_categories")
local function insert_cat(cat, sense_cat)
if for_doc then
cat = "<code>" .. cat .. "</code>"
if sense_cat then
if mode == "term-label" then
cat = cat .. " (using {{tl|tlb}})"
else
cat = cat .. " (using {{tl|lb}} or form-of template)"
end
cat = mw.getCurrentFrame():preprocess(cat)
end
end
insert(categories, cat)
end
for _, cat in ipairs(topical_categories) do
insert_cat(langcode .. ":" .. (cat == true and ucfirst(canon_label) or cat))
end
for _, cat in ipairs(sense_categories) do
if cat == true then
cat = canon_label
end
cat = mode == "term-label" and cat .. " terms" or "terms with " .. cat .. " senses"
insert_cat(canonical_name .. " " .. cat, true)
end
for _, cat in ipairs(pos_categories) do
insert_cat(canonical_name .. " " .. (cat == true and canon_label or cat))
end
for _, cat in ipairs(regional_categories) do
insert_cat((cat == true and ucfirst(canon_label) or cat) .. " " .. canonical_name)
end
for _, cat in ipairs(plain_categories) do
insert_cat(cat == true and ucfirst(canon_label) or cat)
end
return categories
end
--[==[
Return the list of all labels data modules for a label whose language is `lang`. The return value is a list of
module names, with overriding modules earlier in the list (that is, if a label occurs in two modules in the list,
the earlier-listed module takes precedence). If `lang` is nil, only return non-language-specific submodules.
]==]
function export.get_submodules(lang)
local submodules = {
"Module:labels/data",
"Module:labels/data/qualifiers",
"Module:labels/data/regional",
"Module:labels/data/topical",
}
if not lang then
return submodules
end
-- get language-specific labels from data module
local langcode = lang:getFullCode()
if m_lang_specific_data.langs_with_lang_specific_modules[langcode] then
-- prefer per-language label in order to pick subvariety labels over regional ones
insert(submodules, 1, export.lang_specific_data_modules_prefix .. langcode)
end
return submodules
end
--[==[
Return the formatted form of a label `label` (which should be the canonical form of the label; see comment at top),
given (a) the label data structure `labdata` from one of the data modules; (b) the language object `lang` of the
language being processed, or nil for no language; (c) `deprecated` (true if the label is deprecated, otherwise the
deprecation information is taken from `labdata`); (d) `override_display` (if specified, override the display form of the
label with the specified string, instead of any value in `labdata.display` or `labdata.special_display` or the canonical
label in `label` itself); (e) `mode` (same as `data.mode` passed to {get_label_info()}). Returns two values: the
formatted label form and a boolean indicating whether the label is deprecated.
'''NOTE: Under normal circumstances, do not use this.''' Instead, use {get_label_info()}, which searches all the data
modules for a given label and handles other complications.
]==]
function export.format_label(label, labdata, lang, deprecated, override_display, mode)
local formatted_label
mode = validate_mode(mode)
local function labprop(prop, expected_types)
local retval = getprop(labdata, mode, prop)
check_type(label, lang, prop, retval, expected_types)
return retval
end
deprecated = deprecated or labprop("deprecated")
if not override_display and labprop("special_display") then
local function add_language_name(str)
if str == "canonical_name" then
if lang then
return lang:getFullName()
else
return "<code><var>[language name]</var></code>"
end
else
return ""
end
end
formatted_label = labprop("special_display", "string"):gsub("<(.-)>", add_language_name)
else
--[=[
We proceed as follows:
1. The display form comes from either (a) the `override_display` variable if set (this happens when
the user uses a label like '!British'); (b) the `display` property, if set; or (c) the label iself.
2. If the display form contains a link, use it directly and ignore the other display-related settings.
(NOTE: Settings `Wikipedia` and `Wikidata` may still be used on the category page itself, by the
category tree code.)
3. Otherwise, use one of the other display-related settings, in the following order:
`glossary` > `Wiktionary` > `Wikipedia` > `Wikidata`. Specifically:
a. If any of the values is equal to `true`, that is equivalent to specifying a string consisting of
the canonical label.
b. If `glossary` is set, it specifies the anchor in [[Lampiran:Glosari]].
c. If `Wiktionary` is set, it specifies an arbitrary Wiktionary page or page + anchor (e.g. a
separate Appendix entry).
d. If `Wikipedia` is set, it specifies an arbitrary Wikipedia article, or a list of such items (in
this case, we select the first one, but the category tree uses all of them).
e. If `Wikidata` is set, it specifies an arbitrary Wikidata item to retrieve a Wikipedia article from,
or a list of such items (in this case, we select the first one, but the category tree uses all of
them). If the item is of the form `wmcode:id`, the Wikipedia article corresponding to `id` in the
`wmcode`-language Wikipedia is fetched if available. Otherwise, the English-language Wikipedia
article corresponding to `id` is retrieved if available, falling back to the Wikimedia language(s)
corresponding to `lang` and then (in certain cases) to the macrolanguage that `lang` is part of.
Note that if `mode` is specified, prefixed properties (e.g. `accent_display` for `mode` == "accent",
`form_display` for `mode` == "form") are checked before the bare equivalent (e.g. `display`).
]=]
local display = override_display or labprop("display", "string") or label
-- There are several 'Foo spelling' labels specially designed for use in the |from= param in
-- {{alternative form of}}, {{standard spelling of}} and the like. Often the display includes the word
-- "spelling" at the end (e.g. if it's defaulted), which is useful when the label is used with {{tl|lb}} or
-- {{tl|tlb}}; but it causes redundancy when used with the form-of templates, which add the word "form",
-- "spelling", "standard spelling", etc. after the label.
if mode == "form-of" then
display = display:gsub(" spelling$", "")
end
if display:find("%[%[") then
formatted_label = display
else
local glossary = labprop("glossary", {"string", true})
local Wiktionary = labprop("Wiktionary", {"string", true})
local Wikipedia = labprop("Wikipedia", {"string", true, "table"})
local Wikidata = labprop("Wikidata", {"string", true, "table"})
if glossary then
local glossary_entry = glossary == true and label or glossary
formatted_label = "[[Lampiran:Glosari#" .. glossary_entry .. "|" .. display .. "]]"
elseif Wiktionary then
local Wiktionary_entry = Wiktionary == true and label or Wiktionary
if Wiktionary == display then
formatted_label = "[[" .. display .. "]]"
else
formatted_label = "[[" .. Wiktionary_entry .. "|" .. display .. "]]"
end
elseif Wikipedia then
if type(Wikipedia) == "table" then
Wikipedia = Wikipedia[1]
end
local Wikipedia_entry = Wikipedia == true and label or Wikipedia
formatted_label = "[[w:" .. Wikipedia_entry .. "|" .. display .. "]]"
elseif Wikidata then
if not mw.wikibase then
error(("Unable to retrieve data from Wikidata ID for label '%s'; `mw.wikibase` not defined"
):format(label))
end
local function make_formatted_label(wmcode, id)
local article = mw.wikibase.sitelink(id, wmcode .. "wiki")
if article then
local link = wmcode == "en" and "w:" .. article or "w:" .. wmcode .. ":" .. article
return ("[[%s|%s]]"):format(link, display)
else
return nil
end
end
if type(Wikidata) == "table" then
Wikidata = Wikidata[1]
end
local wmcode, id = Wikidata:match("^(.*):(.*)$")
if wmcode then
formatted_label = make_formatted_label(wmcode, id)
else
local langs_to_check = export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang)
for _, wmcode in ipairs(langs_to_check) do
formatted_label = make_formatted_label(wmcode, Wikidata)
if formatted_label then
break
end
end
end
formatted_label = formatted_label or display
else
formatted_label = display
end
end
end
if deprecated then
formatted_label = '<span class="deprecated-label">' .. formatted_label .. '</span>'
end
return formatted_label, deprecated
end
--[==[
Return information on a label. On input `data` is an object with the following fields:
* `label`: The raw label to return information on.
* `lang`: The language of the label. Must be specified unless `for_doc` is given.
* `mode`: How the label was invoked. One of the following:
** {nil} or {"label"}: invoked through {{tl|lb}} or another template whose labels in the same fashion, e.g.
{{tl|alt}}, {{tl|quote}} or {{tl|syn}};
** {"term-label"}: invoked through {{tl|tlb}};
** {"accent"}: invoked through {{tl|a}} or the {{para|a}} or {{para|aa}} parameters of other pronunciation templates,
such as {{tl|IPA}}, {{tl|rhymes}} or {{tl|homophones}};
** {"form-of"}: invoked through {{tl|alt form}}, {{tl|standard spelling of}} or other form-of template.
This changes the display and/or categorization of a minority of labels. (The majority work the same for all modes.)
* `for_doc`: Data is being fetched for documentation purposes. This causes the raw categories returned in
`categories` to be formatted for documentation display.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
The return value is an object with the following fields:
* `raw_text`: If specified, the object does not describe a label but simply raw text surrounding labels. This occurs
when double angle bracket (<<...>>) notation is used. {get_label_info()} does not currently return objects with this
field set, but {process_raw_labels()} does. The value is {"begin"} (this is the first raw text portion derived from
a double angle bracket spec, provided there are at least two raw text portions); {"end"} (this is the last raw text
portion derived from a double angle bracket spec, provided there are at least two portions); {"middle"} (this is
neither the first nor the last raw text portion); or {"only"} (this is a raw text portion standing by itself). The
particular value determines the handling of commas and spaces on one or both sides of the raw text. If this field is
specified, only the `label` field (containing the actual raw text) and the `category` field (containing an empty list)
are set; all other fields are {nil}.
* `raw_label`: The raw label that was passed in.
* `non_canonical`: The label prior to canonicalization (i.e. alias resolution). Usually this is the same as `raw_label`,
but if the raw label was preceded by an exclamation point (meaning "display the raw label as-is"), this field will
contain the label stripped of the exclamation point, and if the raw label is of the form
`<var>label</var>!<var>display</var>` (meaning "display the label in the specified form"), this field will contain the
label before the exclamation point.
* `canonical`: If the label in `non_canonical` is an alias, this contains the canonical name of the label; otherwise it
will be {nil}.
* `override_display`: If specified, this contains a string that overrides the normal display form of the label. The
display form of a label is the `.display` field of the label data if present, and otherwise is normally the canonical
form of the label (i.e. after alias resolution). (This is not the same as the formatted form of the label, found in
`label`, which is the final form shown to the user and includes links to Wikipedia, the glossary, etc. as well as an
HTML wrapper if the label is deprecated.) If `override_display` is specified, however, this is used in place of the
normal display form of the label. This currently happens in two circumstances: (1) the label was preceded by ! to
indicate that the raw label should be displayed rather than the canonical form; (2) the label was given in the form
`<var>label</var>!<var>display</var>` (meaning "display the label in the specified `<var>display</var>` form").
* `label`: The formatted form of the label. This is what is actually shown to the user. If the label is recognized
(found in some module), this will typically be in the form of a link.
* `categories`: A list of the categories to add the label to; an empty list if `nocat` was specified.
* `formatted_categories`: A string containing the formatted categories; {nil} if `nocat` or `for_doc` was specified,
or if `categories` is empty. Currently will be an empty string if there are categories to format but the namespace is
one that normally excludes categories (e.g. userspace and discussion pages), and `force_cat` isn't specified.
* `deprecated`: True if the label is deprecated.
* `recognized`: If true, the label was found in some module.
* `data`: The data structure for the label, as fetched from the label modules. For unrecognized labels, this will
be an empty object.
]==]
function export.get_label_info(data)
if not data.label then
error("`data` must now be an object containing the params")
end
local mode = validate_mode(data.mode)
local ret = {categories = {}}
local label = data.label
local raw_label = label
ret.raw_label = raw_label
local override_display
if label:find("^!") then
label = label:gsub("^!", "")
override_display = label
elseif label:find("![^%s]") then
label, override_display = label:match("^(.-)!([^%s].*)$")
if not label then
error(("Internal error: This Lua pattern should never fail to match for label '%s'"):format(raw_label))
end
end
local non_canonical = label
ret.non_canonical = non_canonical
local deprecated = false
local labdata
local submodule
local data_langcode = data.lang and data.lang:getCode() or nil
local submodules_to_check = export.get_submodules(data.lang)
for _, submodule_to_check in ipairs(submodules_to_check) do
submodule = mw.loadData(submodule_to_check)
local this_labdata = submodule[label]
local resolved_label
if type(this_labdata) == "string" then
resolved_label = this_labdata
this_labdata = submodule[this_labdata]
if not this_labdata then
error(("Internal error: Label alias '%s' points to '%s', which is undefined in module [[%s]]"):format(
label, resolved_label, submodule_to_check))
end
if type(this_labdata) == "string" then
error(("Internal error: Label alias '%s' points to '%s', which is also an alias (of '%s') in module [[%s]]"):format(
label, resolved_label, this_labdata, submodule_to_check))
end
end
if this_labdata then
-- Make sure either there's no lang restriction, or we're processing lang-independent, or our language
-- is among the listed languages. Otherwise, continue processing (which could conceivably pick up a
-- lang-appropriate version of the label in another label data module).
local lablangs = getprop(this_labdata, mode, "langs")
if not lablangs or not data_langcode then
labdata = this_labdata
label = resolved_label or label
break
end
local lang_in_list = false
for _, langcode in ipairs(lablangs) do
if langcode == data_langcode then
lang_in_list = true
break
end
end
if lang_in_list then
labdata = this_labdata
label = resolved_label or label
break
elseif not data.notrack then
-- Track use of a label that fails the lang restriction.
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LANGCODE]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL/LANGCODE]]
track("wrong-lang-label", data_langcode)
track("wrong-lang-label/" .. label, data_langcode)
if resolved_label then
track("wrong-lang-label/" .. resolved_label, data_langcode)
end
end
end
end
if labdata then
ret.recognized = true
else
labdata = {}
ret.recognized = false
end
local function labprop(prop)
return getprop(labdata, mode, prop)
end
if labprop("deprecated") then
deprecated = true
end
if label ~= non_canonical then
-- Note that this is an alias and store the canonical version.
ret.canonical = label
end
if not data.notrack then -- labprop("track") then -- track all labels now
-- Track label (after converting aliases to canonical form; but also track raw label (alias) if different
-- from canonical label).
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/LANGCODE]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/MODE]]
track("label/" .. label, data_langcode, mode)
if label ~= non_canonical then
track("label/" .. non_canonical, data_langcode, mode)
end
end
local formatted_label
formatted_label, deprecated = export.format_label(label, labdata, data.lang, deprecated, override_display, mode)
ret.deprecated = deprecated
if deprecated then
if not data.nocat then
local depcat = "Entries with deprecated labels"
if data.for_doc then
depcat = "<code>" .. depcat .. "</code>"
end
insert(ret.categories, depcat)
end
end
local label_for_already_seen =
(labprop("topical_categories") or labprop("regional_categories")
or labprop("plain_categories") or labprop("pos_categories")
or labprop("sense_categories")) and formatted_label
or nil
-- Track label text. If label text was previously used, don't show it, but include the categories.
-- For an example, see [[hypocretin]].
if data.already_seen and data.already_seen[label_for_already_seen] then
ret.label = ""
else
if formatted_label:find("{") then
formatted_label = mw.getCurrentFrame():preprocess(formatted_label)
end
ret.label = formatted_label
end
if data.nocat then
-- do nothing
else
local cats = export.fetch_categories(label, labdata, data.lang, mode, data.for_doc)
for _, cat in ipairs(cats) do
insert(ret.categories, cat)
end
if not ret.categories[1] or data.for_doc then
-- Don't try to format categories if we're doing this for documentation ({{label/doc}}), because there
-- will be HTML in the categories.
-- do nothing
else
ret.formatted_categories = require(utilities_module).format_categories(ret.categories, data.lang,
data.sort, nil, force_cat or data.force_cat)
end
end
ret.data = labdata
if label_for_already_seen and data.already_seen then
data.already_seen[label_for_already_seen] = true
end
return ret
end
--[==[
Split a string containing comma-separated raw labels into the individual labels. This will not split on a comma
followed by whitespace, and it will not split inside of matched <...> or [...]. The code is written to be efficient, so
that it does not load modules (e.g. [[Module:parse utilities]]) unnecessarily.
]==]
function export.split_labels_on_comma(term)
if term:find("[%[<]") then
-- Do it the "hard way". We don't want to split anything inside of <...> or <<...>> even if there are commas
-- inside of the angle brackets. For good measure we do the same for [...] and [[...]]. We first parse balanced
-- segment runs involving either [...] or <...>. Then we split alternating runs on comma (but not on
-- comma+whitespace). Then we rejoin the split runs. For example, given the following:
-- "regional,older <<non-rhotic,and,non-hoarse-horse>> speakers", the first call to
-- parse_multi_delimiter_balanced_segment_run() produces
--
-- {"regional,older ", "<<non-rhotic,and,non-hoarse-horse>>", " speakers"}
--
-- After calling split_alternating_runs_on_comma(), we get the following:
--
-- {{"regional"}, {"older ", "<<non-rhotic,and,non-hoarse-horse>>", " speakers"}}
--
-- After rejoining each group, we get:
--
-- {"regional", "older <<non-rhotic,and,non-hoarse-horse>> speakers"}
--
-- which is the desired output. When processing the second "label" string, the code in process_raw_labels()
-- will do a similar process to this to pull out the labels inside of the <<...>> notation.
local put = require(parse_utilities_module)
local segments = put.parse_multi_delimiter_balanced_segment_run(term, {{"<", ">"}, {"[", "]"}})
-- This won't split on comma+whitespace.
local comma_separated_groups = put.split_alternating_runs_on_comma(segments)
for i, group in ipairs(comma_separated_groups) do
comma_separated_groups[i] = concat(group)
end
return comma_separated_groups
elseif term:find(",%s") then
-- This won't split on comma+whitespace.
return require(parse_utilities_module).split_on_comma(term)
elseif term:find(",") then
return require(string_utilities_module).split(term, ",")
else
return {term}
end
end
--[==[
Return a list of objects corresponding to a set of raw labels. Each object returned is of the format returned by
{get_label_info()}. This is similar to looping over the labels and calling {get_label_info()} on each one, but it also
correctly handles embedded double angle bracket specs <<...>> found in the labels. (In such a case, there will be more
objects returned than raw labels passed in.) On input, `data` is an object with the following fields:
* `labels`: The list of labels to process.
* `lang`: The language of the labels. Must be specified.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
]==]
function export.process_raw_labels(data)
local label_infos = {}
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
local function get_info_and_insert(label)
-- Reuse this structure to save memory.
data.label = label
insert(label_infos, export.get_label_info(data))
end
for _, label in ipairs(data.labels) do
if label:find("<<") then
local segments = require(string_utilities_module).split(label, "<<(.-)>>")
for i, segment in ipairs(segments) do
if i % 2 == 1 then
local raw_text_type = i == 1 and "begin" or i == #segments and "end" or "middle"
insert(label_infos, {raw_text = raw_text_type, label = segment, categories = {}})
else
local segment_labels = export.split_labels_on_comma(segment)
for _, segment_label in ipairs(segment_labels) do
get_info_and_insert(segment_label)
end
end
end
else
get_info_and_insert(label)
end
end
return label_infos
end
--[==[
Split a comma-separated string of raw labels and process each label to get a list of objects suitable for passing to
{format_processed_labels()}. Each object returned is of the format returned by {get_label_info()}. This is equivalent to
calling {split_labels_on_comma()} followed by {process_raw_labels()}. On input, `data` is an object with the following
fields:
* `labels`: The string containing the raw comma-separated labels.
* `lang`: The language of the labels. Must be specified.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
]==]
function export.split_and_process_raw_labels(data)
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
data.labels = export.split_labels_on_comma(data.labels)
return export.process_raw_labels(data)
end
--[==[
Format one or more already-processed labels for display and categorization. "Already-processed" means that
{get_label_info()} or {process_raw_labels()} has been called on the raw labels to convert them into objects containing
information on how to display and categorize the labels. This is a lower-level alternative to {show_labels()} and is
meant for modules such as [[Module:alternative forms]], [[Module:quote]] and [[Module:etymology/templates/descendant]]
that support displaying labels along with some other information.
On input `data` is an object with the following fields:
* `labels`: List of the label objects to format, in the format returned by {get_label_info()}.
* `lang`: The language of the labels.
* `open`: Open bracket or parenthesis to display before the concatenated labels. If specified, it is wrapped in the
{"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no open bracket is displayed.
* `close`: Close bracket or parenthesis to display after the concatenated labels. If specified, it is wrapped in the
{"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no close bracket is displayed.
* `no_ib_content`: By default, the concatenated formatted labels inside of the open/close brackets are wrapped in the
{"ib-content"} and {"label-content"} CSS classes. Specify this to suppress this wrapping.
* `raw`: Suppress all CSS wrapping of content, including open/close parentheses, content and comma delimiters (which
are normally wrapped in {"ib-comma"} and {"label-comma"} CSS classes).
* `ok_to_destructively_modify`: If set, the `data` structure, and the `data.labels` table inside of it, will be
destructively modified in the process of this function running.
* `split_output`: If not given, the return value is a concatenation of the formatted concatenated labels and formatted
categories. Otherwise, two values are returned: the formatted pronunciation and the categories. If `split_output` is
the value {"raw"}, the categories are returned in list form, where the list elements are strings f the form suitable
for passing to {format_categories()} in [[Module:utilities]]. If `split_output` is any other value besides {nil}, the
categories are returned as a pre-formatted concatenated string.
The return value (or the first return value, if `split_output` is given) is a string containing the contenated labels,
optionally surrounded by open/close brackets or parentheses. Normally, labels are separated by comma-space sequences,
but this may be suppressed for certain labels. If `nocat` wasn't given to {get_label_info()} or {process_raw_labels()},
and `split_output` wasn't given, the label objects will contain formatted categories in them, which will be inserted
into the returned text. (Use `split_output` if you need the categories returned separately.) The concatenated text
inside of the open/close brackets is normally wrapped in the {"ib-content"} CSS class, but this can be suppressed, as
mentioned above.
]==]
function export.format_processed_labels(data)
if not data.labels then
error("`data` must now be an object containing the params")
end
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.labels = m_table.deepCopy(data.labels)
data.ok_to_destructively_modify = true
end
local labels = data.labels
if not labels[1] then
error("You must specify at least one label.")
end
local split_output = data.split_output
-- Show the labels
local omit_preComma
local omit_preSpace
local omit_postComma = true
local omit_postSpace = true
for _, label in ipairs(labels) do
omit_preComma = omit_postComma
omit_preSpace = omit_postSpace
local raw_text_omit_before = label.raw_text == "middle" or label.raw_text == "end"
local raw_text_omit_after = label.raw_text == "middle" or label.raw_text == "begin"
label.omit_comma = omit_preComma or (label.data and label.data.omit_preComma) or raw_text_omit_before
omit_postComma = (label.data and label.data.omit_postComma) or raw_text_omit_after
label.omit_space = omit_preSpace or (label.data and label.data.omit_preSpace) or raw_text_omit_before
omit_postSpace = (label.data and label.data.omit_postSpace) or raw_text_omit_after
end
if data.lang then
local lang_functions_module = export.lang_specific_data_modules_prefix .. data.lang:getCode() .. "/functions"
local m_lang_functions = require(load_module).safe_require(lang_functions_module)
if m_lang_functions and m_lang_functions.postprocess_handlers then
for _, handler in ipairs(m_lang_functions.postprocess_handlers) do
handler(data)
end
end
end
local function wrap_css(txt, suffix)
if data.raw then
return txt
end
return ("<span class=\"ib-%s label-%s\">%s</span>"):format(suffix, suffix, txt)
end
local categories = nil
local formatted_categories = split_output and split_output ~= "raw" and {} or nil
for i, labelinfo in ipairs(labels) do
local label
-- Need to check for 'not raw_text' here because blank labels may legitimately occur as raw text if a double
-- angle bracket spec occurs at the beginning of a label. In this case we've already taken into account the
-- context and don't want to leave out a preceding comma and space e.g. in a case like
-- {{lb|en|rare|<<dialect>> or <<eye dialect>>}}. FIXME: We should reconsider whether we need this special case
-- at all.
if labelinfo.label == "" and not labelinfo.raw_text then
label = ""
else
label = (labelinfo.omit_comma and "" or wrap_css(",", "comma")) ..
(labelinfo.omit_space and "" or " ") ..
labelinfo.label
end
if split_output then
labels[i] = label
if split_output == "raw" then
if labelinfo.categories and labelinfo.categories[1] then
if categories then
m_table.extend(categories, labelinfo.categories)
else
categories = labelinfo.categories
end
end
elseif labelinfo.formatted_categories then
insert(formatted_categories, labelinfo.formatted_categories)
end
else
labels[i] = label .. (labelinfo.formatted_categories or "")
end
end
local function wrap_open_close(val)
if val then
return wrap_css(val, "brac")
else
return ""
end
end
local concatenated_labels = concat(labels, "")
if not data.no_ib_content then
concatenated_labels = wrap_css(concatenated_labels, "content")
end
local ret_labels = wrap_open_close(data.open) .. concatenated_labels .. wrap_open_close(data.close)
if split_output == "raw" then
return ret_labels, categories
elseif split_output then
return ret_labels, concat(formatted_categories)
else
return ret_labels
end
end
--[==[
Format one or more labels for display and categorization. This provides the implementation of the
{{tl|label}}/{{tl|lb}}, {{tl|term label}}/{{tl|tlb}} and {{tl|accent}}/{{tl|a}} templates, and can also be called from a
module. The return value is a string to be inserted into the generated page, including the display and categories. On
input `data` is an object with the following fields:
* `labels`: List of the labels to format.
* `lang`: The language of the labels.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the labels to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for these labels.
* `sort`: Sort key for categorization.
* `no_track_already_seen`: Don't track already-seen labels. If not specified, already-seen labels are not displayed
again, but still categorize. See the documentation of {get_label_info()}.
* `open`: Open bracket or parenthesis to display before the concatenated labels. If {nil}, defaults to an open
parenthesis. Set to {false} to disable.
* `close`: Close bracket or parenthesis to display after the concatenated labels. If {nil}, defaults to a close
parenthesis. Set to {false} to disable.
* `no_ib_content`: As in `format_processed_labels()`.
* `raw`: As in `format_processed_labels()`. Also suppress wrapping the entire formatted result in a usage label CSS
class (see below).
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
Compared with {format_processed_labels()}, this function has the following differences:
# The labels specified in `labels` are raw labels (i.e. strings) rather than formatted objects.
# The open and close brackets default to parentheses ("round brackets") rather than not being displayed by default.
# Tracking of already-seen labels is enabled unless explicitly turned off using `no_track_already_seen`.
# The entire formatted result is wrapped in a {"usage-label-<var>type</var>"} CSS class (depending on the value of
`mode`), unless `raw` is given.
]==]
function export.show_labels(data)
if not data.labels then
error("`data` must now be an object containing the params")
end
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
local labels = data.labels
if not labels[1] then
error("You must specify at least one label.")
end
local mode = validate_mode(data.mode)
if not data.no_track_already_seen then
data.already_seen = {}
end
data.labels = export.process_raw_labels(data)
if data.open == nil then
data.open = "("
end
if data.close == nil then
data.close = ")"
end
local formatted = export.format_processed_labels(data)
if data.raw then
return formatted
else
return "<span class=\"" .. mode_to_outer_class[mode] .. "\">" .. formatted .. "</span>"
end
end
--[==[Helper function for the data modules.]==]
function export.alias(labels, key, aliases)
m_table.alias(labels, key, aliases)
end
--[==[
Split the display form of a label. Returns two values: `link` and `display`. If the display form consists of a
two-part link, `link` is the first part and `display` is the second part. If the display form consists of a
single-part link, `link` and `display` are the same. Otherwise (the display form is not a link or contains an
embedded link), `link` is the same as the passed-in `label` and `display` is nil.
]==]
function export.split_display_form(label)
if not label:find("%[%[") then
return label, nil
end
local link, display = label:match("^%[%[([^%[%]|]+)|([^%[%]|]+)%]%]$")
if link then
return link, display
end
link = label:match("^%[%[([^%[%]|])+%]%]$")
if link then
return link, link
end
return label, nil
end
--[==[
Combine the `link` and `display` parts of the display form of a label as returned by {split_display_form()}.
If `display` is nil, `link` is returned directly. Otherwise, a one-part or two-part link is constructed
depending on whether `link` and `display` are the same. (As a special case, if both consist of a blank string,
the return value is a blank string rather than a malformed link.)
]==]
function export.combine_display_form_parts(link, display)
if not display then
return link
end
if link == display then
if link == "" then
return ""
else
return ("[[%s]]"):format(link)
end
end
return ("[[%s|%s]]"):format(link, display)
end
--[==[Used to finalize the data into the form that is actually returned.]==]
function export.finalize_data(labels)
local shallow_copy = m_table.shallowCopy
local aliases = {}
for label, data in pairs(labels) do
if type(data) == "table" then
if data.aliases then
for _, alias in ipairs(data.aliases) do
aliases[alias] = label
end
data.aliases = nil
end
if data.deprecated_aliases then
local data2 = shallow_copy(data)
data2.deprecated = true
data2.canonical = label
for _, alias in ipairs(data2.deprecated_aliases) do
aliases[alias] = data2
end
data.deprecated_aliases = nil
data2.deprecated_aliases = nil
end
end
end
for label, data in pairs(aliases) do
labels[label] = data
end
return labels
end
return export
hemnsbbc2axiqyzrd0ceepntx0ej90g
376178
375904
2026-09-26T09:21:31Z
Hakimi97
2668
Pengembalian penyetempatan ke bahasa Melayu
376178
Scribunto
text/plain
local export = {}
export.lang_specific_data_list_module = "Module:labels/data/lang"
export.lang_specific_data_modules_prefix = "Module:labels/data/lang/"
local load_module = "Module:load"
local parse_utilities_module = "Module:parse utilities"
local string_utilities_module = "Module:string utilities"
local utilities_module = "Module:utilities"
local insert = table.insert
local concat = table.concat
local require_when_needed = require("Module:require when needed")
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local dump = mw.dumpObject
local m_lang_specific_data = mw.loadData(export.lang_specific_data_list_module)
local m_table = require_when_needed("Module:table")
--[==[ intro:
Labels go through several stages of processing to get from the original (raw) label specified in the Wikicode to the
final (formatted) label displayed to the user. The following terminology will help keep things straight:
* The "raw label" is the label specified in the Wikicode.
* The "non-canonical label" is the label extracted from the raw label, used for looking up in the label modules in order
to fetch the associated label data structure and determine the canonical form of the label. Normally this is the same
as the raw label, but it will be different if the raw label is of the form `!<var>label</var>` (e.g. `!Australian`)
`<var>label</var>!<var>display</var>` (e.g. `Southern US!Southern`). The former syntax indicates that the label
should display as-is instead of in its canonical form (which in the example given is `Australia`), and the latter
syntax indicates that the label should display in the form specified after the exclamation point.
* The "canonical label" is the result of applying alias resolution to the non-canonical label. Normally, the
canonical label rather than the non-canonical label is what is shown to the user.
* The "display form of the label" is what is shown to the user, not considering links and HTML that may wrap the
display form to get the formatted form of the label. The display form comes from the `.display` field of the module
label data for the label; if no such field exists in the label data, it is normally the canonical label. However, if
the display override exists (see below), it takes precedence over the `.display` field or canonical label when
determining the display form of the label.
* The "display override", if specified, overrides all other means of determining the display form of the label. It is
specified in two circumstances, i.e. in the `!<var>label</var>` and `<var>label</var>!<var>display</var>` raw label
formats (i.e. in the same cirumstances where the raw label and non-canonical label are different).
* The "formatted form of the label" is the final form of the label shown directly to the user. It generally appears to
the user as the display form of the label, but in the Wikicode, the formatted form may wrap the display form with a
link to Wikipedia, the Wiktionary glossary or another Wiktionary entry, and that link in turn may be wrapped in an
HTML span with a "deprecated" CSS class attached, causing the label to display differently (to indicate that it is
deprecated).
]==]
-- for testing
local force_cat = false
local m_headword_data = mw.loadData("Module:headword/data")
local SUBPAGENAME = m_headword_data.pagename
-- Disable tracking on heavy pages to save time.
local pages_where_tracking_is_disabled = m_headword_data.large_pages
-- Add tracking category for PAGE. The tracking category linked to is [[Wiktionary:Tracking/labels/PAGE]].
-- We also add to [[Wiktionary:Tracking/labels/PAGE/LANGCODE]] and [[Wiktionary:Tracking/labels/PAGE/MODE]] if
-- LANGCODE and/or MODE given.
local function track(page, langcode, mode)
if pages_where_tracking_is_disabled[SUBPAGENAME] then
return true
end
-- avoid including links in pages (may cause error)
page = page:gsub("%[", "("):gsub("%]", ")"):gsub("|", "!")
require("Module:debug/track")("labels/" .. page)
if langcode then
require("Module:debug/track")("labels/" .. page .. "/" .. langcode)
end
if mode then
require("Module:debug/track")("labels/" .. page .. "/" .. mode)
end
-- We don't currently add a tracking label for both langcode and mode to reduce the total number of labels, to
-- save some memory.
return true
end
local function ucfirst(txt)
return mw.getContentLanguage():ucfirst(txt)
end
local mode_to_outer_class = {
["label"] = "usage-label-sense",
["term-label"] = "usage-label-term",
["accent"] = "usage-label-accent",
["form-of"] = "usage-label-form-of",
}
local mode_to_property_prefix = {
["label"] = false,
["term-label"] = false, -- handled specially
["accent"] = "accent_",
["form-of"] = "form_of_",
}
local function validate_mode(mode)
mode = mode or "label"
if not mode_to_outer_class[mode] then
local allowed_values = {}
for key, _ in pairs(mode_to_outer_class) do
insert(allowed_values, "'" .. key .. "'")
end
table.sort(allowed_values)
error(("Invalid value '%s' for `mode`; should be one of %s"):format(mode, concat(allowed_values, ", ")))
end
return mode
end
local function getprop(labdata, mode, prop)
local mode_prefix = mode_to_property_prefix[mode]
return mode_prefix and labdata[mode_prefix .. prop] or labdata[prop]
end
local function check_type(label, lang, prop, value, expected_types)
if value == nil or expected_types == nil then
return value
end
if type(expected_types) ~= "table" then
expected_types = {expected_types}
end
local valtype = type(value)
local matches = false
for _, expected_type in ipairs(expected_types) do
if type(expected_type) == "string" then
if valtype == expected_type then
matches = true
break
end
elseif value == expected_type then
matches = true
break
end
end
if not matches then
local function join_untagged_or(elements)
return m_table.serialCommaJoin(elements, {conj = "or", dontTag = true})
end
local quoted_types = {}
local quoted_values = {}
for _, expected_type in ipairs(expected_types) do
if type(expected_type) == "string" then
insert(quoted_types, "'" .. expected_type .. "'")
else
insert(quoted_values, "'" .. dump(expected_type) .. "'")
end
end
local possible_matches = {}
if quoted_types[1] then
insert(possible_matches, ("be of type%s %s"):format(
quoted_types[2] and "s" or "", join_untagged_or(quoted_types)))
end
if quoted_values[1] then
insert(possible_matches, ("have the value%s %s"):format(
quoted_values[2] and "s" or "", join_untagged_or(quoted_values)))
end
error(("Internal error: For label '%s', langcode '%s', property '%s' should %s but is of type '%s' with value %s"):format(
label, lang and lang:getCode() or "UNKNOWN", prop, join_untagged_or(possible_matches), valtype, dump(value)))
end
end
-- HACK! For languages in any of the given families, check the specified-language Wikipedia for appropriate
-- Wikipedia articles for the language in question (esp. useful for obscure etymology-only languages that may not
-- have English articles for them, like many Chinese lects).
local families_to_wikipedia_languages = {
{"zhx", "zh"},
{"sem-arb", "ar"},
}
--[==[
Given language `lang` (a full language, etymology-language or family), fetch a list of Wikimedia languages to check
when converting a Wikidata item to a Wikipedia article. English is always first, followed by the Wikimedia language
code(s) of `lang` if `lang` is a language (which may or may not be the same as `lang`'s Wiktionary code), followed
by the macrolanguage of `lang` for certain languages and families (currently, only languages and families in the Chinese
and Arabic families). If `lang` is nil, only return English. Note that the same code may occur more than once in the
list. This is exported because it's also used by [[Module:category tree/lects]].
]==]
function export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang)
local wikipedia_langs = {}
insert(wikipedia_langs, "ms")
if lang then
local article_lang = lang
while article_lang do
if article_lang:hasType("language") then
local wmcodes = article_lang:getWikimediaLanguageCodes()
for _, wmcode in ipairs(wmcodes) do
insert(wikipedia_langs, wmcode)
end
end
article_lang = article_lang:getParent()
end
for _, family_to_wp_lang in ipairs(families_to_wikipedia_languages) do
local family, wp_lang = unpack(family_to_wp_lang)
if lang:inFamily(family) then
insert(wikipedia_langs, wp_lang)
end
end
end
return wikipedia_langs
end
--[==[
Fetch the categories to add to a page, given that the label whose canonical form is `canon_label` with language `lang`
has been seen. `labdata` is the label data structure for `label`, fetched from the appropriate submodule. `mode`
specifies how the label was invoked (see {get_label_info()} for more information). The return value is a list of the
actual categories, unless `for_doc` is specified, in which case the categories returned are marked up for display on a
documentation page. If `for_doc` is given, `lang` may be nil to format the categories in a language-independent fashion;
otherwise, it must be specified. If `category_types` is specified, it should be a set object (i.e. with category types
as keys and {true} as values), and only categories of the specified types will be returned.
]==]
function export.fetch_categories(canon_label, labdata, lang, mode, for_doc, category_types)
local categories = {}
mode = validate_mode(mode)
local langcode, canonical_name
if lang then
langcode = lang:getFullCode()
canonical_name = lang:getFullName()
elseif for_doc then
langcode = "<var>[langcode]</var>"
canonical_name = "<var>[language name]</var>"
else
error("Internal error: Must specify `lang` unless `for_doc` is given")
end
local function labprop(prop, expected_types)
local retval = getprop(labdata, mode, prop)
check_type(canon_label, lang, prop, retval, expected_types)
return retval
end
local empty_list = {}
local function get_cats(cat_type)
if category_types and not category_types[cat_type] then
return empty_list
end
local cats = labprop(cat_type)
if not cats then
return empty_list
end
if type(cats) ~= "table" then
return {cats}
end
return cats
end
local topical_categories = get_cats("topical_categories")
local sense_categories = get_cats("sense_categories")
local pos_categories = get_cats("pos_categories")
local regional_categories = get_cats("regional_categories")
local plain_categories = get_cats("plain_categories")
local function insert_cat(cat, sense_cat)
if for_doc then
cat = "<code>" .. cat .. "</code>"
if sense_cat then
if mode == "term-label" then
cat = cat .. " (using {{tl|tlb}})"
else
cat = cat .. " (using {{tl|lb}} or form-of template)"
end
cat = mw.getCurrentFrame():preprocess(cat)
end
end
insert(categories, cat)
end
for _, cat in ipairs(topical_categories) do
insert_cat(langcode .. ":" .. (cat == true and ucfirst(canon_label) or cat))
end
for _, cat in ipairs(sense_categories) do
if cat == true then
cat = canon_label
end
cat = mode == "term-label"
and "Perkataan " .. cat .. " bahasa " .. canonical_name
or "Perkataan dengan erti " .. cat .. " bahasa " .. canonical_name
insert_cat(cat, true)
end
for _, cat in ipairs(pos_categories) do
insert_cat((cat == true and ucfirst(canon_label) or ucfirst(cat)) .. " bahasa " .. canonical_name)
end
for _, cat in ipairs(regional_categories) do
insert_cat("Bahasa " .. canonical_name .. " " .. (cat == true and ucfirst(canon_label) or cat))
end
for _, cat in ipairs(plain_categories) do
insert_cat(cat == true and ucfirst(canon_label) or cat)
end
return categories
end
--[==[
Return the list of all labels data modules for a label whose language is `lang`. The return value is a list of
module names, with overriding modules earlier in the list (that is, if a label occurs in two modules in the list,
the earlier-listed module takes precedence). If `lang` is nil, only return non-language-specific submodules.
]==]
function export.get_submodules(lang)
local submodules = {
"Module:labels/data",
"Module:labels/data/qualifiers",
"Module:labels/data/regional",
"Module:labels/data/topical",
}
if not lang then
return submodules
end
-- get language-specific labels from data module
local langcode = lang:getFullCode()
if m_lang_specific_data.langs_with_lang_specific_modules[langcode] then
-- prefer per-language label in order to pick subvariety labels over regional ones
insert(submodules, 1, export.lang_specific_data_modules_prefix .. langcode)
end
return submodules
end
--[==[
Return the formatted form of a label `label` (which should be the canonical form of the label; see comment at top),
given (a) the label data structure `labdata` from one of the data modules; (b) the language object `lang` of the
language being processed, or nil for no language; (c) `deprecated` (true if the label is deprecated, otherwise the
deprecation information is taken from `labdata`); (d) `override_display` (if specified, override the display form of the
label with the specified string, instead of any value in `labdata.display` or `labdata.special_display` or the canonical
label in `label` itself); (e) `mode` (same as `data.mode` passed to {get_label_info()}). Returns two values: the
formatted label form and a boolean indicating whether the label is deprecated.
'''NOTE: Under normal circumstances, do not use this.''' Instead, use {get_label_info()}, which searches all the data
modules for a given label and handles other complications.
]==]
function export.format_label(label, labdata, lang, deprecated, override_display, mode)
local formatted_label
mode = validate_mode(mode)
local function labprop(prop, expected_types)
local retval = getprop(labdata, mode, prop)
check_type(label, lang, prop, retval, expected_types)
return retval
end
deprecated = deprecated or labprop("deprecated")
if not override_display and labprop("special_display") then
local function add_language_name(str)
if str == "canonical_name" then
if lang then
return lang:getFullName()
else
return "<code><var>[language name]</var></code>"
end
else
return ""
end
end
formatted_label = labprop("special_display", "string"):gsub("<(.-)>", add_language_name)
else
--[=[
We proceed as follows:
1. The display form comes from either (a) the `override_display` variable if set (this happens when
the user uses a label like '!British'); (b) the `display` property, if set; or (c) the label iself.
2. If the display form contains a link, use it directly and ignore the other display-related settings.
(NOTE: Settings `Wikipedia` and `Wikidata` may still be used on the category page itself, by the
category tree code.)
3. Otherwise, use one of the other display-related settings, in the following order:
`glossary` > `Wiktionary` > `Wikipedia` > `Wikidata`. Specifically:
a. If any of the values is equal to `true`, that is equivalent to specifying a string consisting of
the canonical label.
b. If `glossary` is set, it specifies the anchor in [[Lampiran:Glosari]].
c. If `Wiktionary` is set, it specifies an arbitrary Wiktionary page or page + anchor (e.g. a
separate Appendix entry).
d. If `Wikipedia` is set, it specifies an arbitrary Wikipedia article, or a list of such items (in
this case, we select the first one, but the category tree uses all of them).
e. If `Wikidata` is set, it specifies an arbitrary Wikidata item to retrieve a Wikipedia article from,
or a list of such items (in this case, we select the first one, but the category tree uses all of
them). If the item is of the form `wmcode:id`, the Wikipedia article corresponding to `id` in the
`wmcode`-language Wikipedia is fetched if available. Otherwise, the English-language Wikipedia
article corresponding to `id` is retrieved if available, falling back to the Wikimedia language(s)
corresponding to `lang` and then (in certain cases) to the macrolanguage that `lang` is part of.
Note that if `mode` is specified, prefixed properties (e.g. `accent_display` for `mode` == "accent",
`form_display` for `mode` == "form") are checked before the bare equivalent (e.g. `display`).
]=]
local display = override_display or labprop("display", "string") or label
-- There are several 'Foo spelling' labels specially designed for use in the |from= param in
-- {{alternative form of}}, {{standard spelling of}} and the like. Often the display includes the word
-- "spelling" at the end (e.g. if it's defaulted), which is useful when the label is used with {{tl|lb}} or
-- {{tl|tlb}}; but it causes redundancy when used with the form-of templates, which add the word "form",
-- "spelling", "standard spelling", etc. after the label.
if mode == "form-of" then
display = display:gsub(" spelling$", "")
end
if display:find("%[%[") then
formatted_label = display
else
local glossary = labprop("glossary", {"string", true})
local Wiktionary = labprop("Wiktionary", {"string", true})
local Wikipedia = labprop("Wikipedia", {"string", true, "table"})
local Wikidata = labprop("Wikidata", {"string", true, "table"})
if glossary then
local glossary_entry = glossary == true and label or glossary
formatted_label = "[[Lampiran:Glosari#" .. glossary_entry .. "|" .. display .. "]]"
elseif Wiktionary then
local Wiktionary_entry = Wiktionary == true and label or Wiktionary
if Wiktionary == display then
formatted_label = "[[" .. display .. "]]"
else
formatted_label = "[[" .. Wiktionary_entry .. "|" .. display .. "]]"
end
elseif Wikipedia then
if type(Wikipedia) == "table" then
Wikipedia = Wikipedia[1]
end
local Wikipedia_entry = Wikipedia == true and label or Wikipedia
formatted_label = "[[w:" .. Wikipedia_entry .. "|" .. display .. "]]"
elseif Wikidata then
if not mw.wikibase then
error(("Unable to retrieve data from Wikidata ID for label '%s'; `mw.wikibase` not defined"
):format(label))
end
local function make_formatted_label(wmcode, id)
local article = mw.wikibase.sitelink(id, wmcode .. "wiki")
if article then
local link = wmcode == "ms" and "w:" .. article or "w:" .. wmcode .. ":" .. article
return ("[[%s|%s]]"):format(link, display)
else
return nil
end
end
if type(Wikidata) == "table" then
Wikidata = Wikidata[1]
end
local wmcode, id = Wikidata:match("^(.*):(.*)$")
if wmcode then
formatted_label = make_formatted_label(wmcode, id)
else
local langs_to_check = export.get_langs_to_extract_wikipedia_articles_from_wikidata(lang)
for _, wmcode in ipairs(langs_to_check) do
formatted_label = make_formatted_label(wmcode, Wikidata)
if formatted_label then
break
end
end
end
formatted_label = formatted_label or display
else
formatted_label = display
end
end
end
if deprecated then
formatted_label = '<span class="deprecated-label">' .. formatted_label .. '</span>'
end
return formatted_label, deprecated
end
--[==[
Return information on a label. On input `data` is an object with the following fields:
* `label`: The raw label to return information on.
* `lang`: The language of the label. Must be specified unless `for_doc` is given.
* `mode`: How the label was invoked. One of the following:
** {nil} or {"label"}: invoked through {{tl|lb}} or another template whose labels in the same fashion, e.g.
{{tl|alt}}, {{tl|quote}} or {{tl|syn}};
** {"term-label"}: invoked through {{tl|tlb}};
** {"accent"}: invoked through {{tl|a}} or the {{para|a}} or {{para|aa}} parameters of other pronunciation templates,
such as {{tl|IPA}}, {{tl|rhymes}} or {{tl|homophones}};
** {"form-of"}: invoked through {{tl|alt form}}, {{tl|standard spelling of}} or other form-of template.
This changes the display and/or categorization of a minority of labels. (The majority work the same for all modes.)
* `for_doc`: Data is being fetched for documentation purposes. This causes the raw categories returned in
`categories` to be formatted for documentation display.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
The return value is an object with the following fields:
* `raw_text`: If specified, the object does not describe a label but simply raw text surrounding labels. This occurs
when double angle bracket (<<...>>) notation is used. {get_label_info()} does not currently return objects with this
field set, but {process_raw_labels()} does. The value is {"begin"} (this is the first raw text portion derived from
a double angle bracket spec, provided there are at least two raw text portions); {"end"} (this is the last raw text
portion derived from a double angle bracket spec, provided there are at least two portions); {"middle"} (this is
neither the first nor the last raw text portion); or {"only"} (this is a raw text portion standing by itself). The
particular value determines the handling of commas and spaces on one or both sides of the raw text. If this field is
specified, only the `label` field (containing the actual raw text) and the `category` field (containing an empty list)
are set; all other fields are {nil}.
* `raw_label`: The raw label that was passed in.
* `non_canonical`: The label prior to canonicalization (i.e. alias resolution). Usually this is the same as `raw_label`,
but if the raw label was preceded by an exclamation point (meaning "display the raw label as-is"), this field will
contain the label stripped of the exclamation point, and if the raw label is of the form
`<var>label</var>!<var>display</var>` (meaning "display the label in the specified form"), this field will contain the
label before the exclamation point.
* `canonical`: If the label in `non_canonical` is an alias, this contains the canonical name of the label; otherwise it
will be {nil}.
* `override_display`: If specified, this contains a string that overrides the normal display form of the label. The
display form of a label is the `.display` field of the label data if present, and otherwise is normally the canonical
form of the label (i.e. after alias resolution). (This is not the same as the formatted form of the label, found in
`label`, which is the final form shown to the user and includes links to Wikipedia, the glossary, etc. as well as an
HTML wrapper if the label is deprecated.) If `override_display` is specified, however, this is used in place of the
normal display form of the label. This currently happens in two circumstances: (1) the label was preceded by ! to
indicate that the raw label should be displayed rather than the canonical form; (2) the label was given in the form
`<var>label</var>!<var>display</var>` (meaning "display the label in the specified `<var>display</var>` form").
* `label`: The formatted form of the label. This is what is actually shown to the user. If the label is recognized
(found in some module), this will typically be in the form of a link.
* `categories`: A list of the categories to add the label to; an empty list if `nocat` was specified.
* `formatted_categories`: A string containing the formatted categories; {nil} if `nocat` or `for_doc` was specified,
or if `categories` is empty. Currently will be an empty string if there are categories to format but the namespace is
one that normally excludes categories (e.g. userspace and discussion pages), and `force_cat` isn't specified.
* `deprecated`: True if the label is deprecated.
* `recognized`: If true, the label was found in some module.
* `data`: The data structure for the label, as fetched from the label modules. For unrecognized labels, this will
be an empty object.
]==]
function export.get_label_info(data)
if not data.label then
error("`data` must now be an object containing the params")
end
local mode = validate_mode(data.mode)
local ret = {categories = {}}
local label = data.label
local raw_label = label
ret.raw_label = raw_label
local override_display
if label:find("^!") then
label = label:gsub("^!", "")
override_display = label
elseif label:find("![^%s]") then
label, override_display = label:match("^(.-)!([^%s].*)$")
if not label then
error(("Internal error: This Lua pattern should never fail to match for label '%s'"):format(raw_label))
end
end
local non_canonical = label
ret.non_canonical = non_canonical
local deprecated = false
local labdata
local submodule
local data_langcode = data.lang and data.lang:getCode() or nil
local submodules_to_check = export.get_submodules(data.lang)
for _, submodule_to_check in ipairs(submodules_to_check) do
submodule = mw.loadData(submodule_to_check)
local this_labdata = submodule[label]
local resolved_label
if type(this_labdata) == "string" then
resolved_label = this_labdata
this_labdata = submodule[this_labdata]
if not this_labdata then
error(("Internal error: Label alias '%s' points to '%s', which is undefined in module [[%s]]"):format(
label, resolved_label, submodule_to_check))
end
if type(this_labdata) == "string" then
error(("Internal error: Label alias '%s' points to '%s', which is also an alias (of '%s') in module [[%s]]"):format(
label, resolved_label, this_labdata, submodule_to_check))
end
end
if this_labdata then
-- Make sure either there's no lang restriction, or we're processing lang-independent, or our language
-- is among the listed languages. Otherwise, continue processing (which could conceivably pick up a
-- lang-appropriate version of the label in another label data module).
local lablangs = getprop(this_labdata, mode, "langs")
if not lablangs or not data_langcode then
labdata = this_labdata
label = resolved_label or label
break
end
local lang_in_list = false
for _, langcode in ipairs(lablangs) do
if langcode == data_langcode then
lang_in_list = true
break
end
end
if lang_in_list then
labdata = this_labdata
label = resolved_label or label
break
elseif not data.notrack then
-- Track use of a label that fails the lang restriction.
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LANGCODE]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/wrong-lang-label/LABEL/LANGCODE]]
track("wrong-lang-label", data_langcode)
track("wrong-lang-label/" .. label, data_langcode)
if resolved_label then
track("wrong-lang-label/" .. resolved_label, data_langcode)
end
end
end
end
if labdata then
ret.recognized = true
else
labdata = {}
ret.recognized = false
end
local function labprop(prop)
return getprop(labdata, mode, prop)
end
if labprop("deprecated") then
deprecated = true
end
if label ~= non_canonical then
-- Note that this is an alias and store the canonical version.
ret.canonical = label
end
if not data.notrack then -- labprop("track") then -- track all labels now
-- Track label (after converting aliases to canonical form; but also track raw label (alias) if different
-- from canonical label).
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/LANGCODE]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/labels/label/LABEL/MODE]]
track("label/" .. label, data_langcode, mode)
if label ~= non_canonical then
track("label/" .. non_canonical, data_langcode, mode)
end
end
local formatted_label
formatted_label, deprecated = export.format_label(label, labdata, data.lang, deprecated, override_display, mode)
ret.deprecated = deprecated
if deprecated then
if not data.nocat then
local depcat = "Entries with deprecated labels"
if data.for_doc then
depcat = "<code>" .. depcat .. "</code>"
end
insert(ret.categories, depcat)
end
end
local label_for_already_seen =
(labprop("topical_categories") or labprop("regional_categories")
or labprop("plain_categories") or labprop("pos_categories")
or labprop("sense_categories")) and formatted_label
or nil
-- Track label text. If label text was previously used, don't show it, but include the categories.
-- For an example, see [[hypocretin]].
if data.already_seen and data.already_seen[label_for_already_seen] then
ret.label = ""
else
if formatted_label:find("{") then
formatted_label = mw.getCurrentFrame():preprocess(formatted_label)
end
ret.label = formatted_label
end
if data.nocat then
-- do nothing
else
local cats = export.fetch_categories(label, labdata, data.lang, mode, data.for_doc)
for _, cat in ipairs(cats) do
insert(ret.categories, cat)
end
if not ret.categories[1] or data.for_doc then
-- Don't try to format categories if we're doing this for documentation ({{label/doc}}), because there
-- will be HTML in the categories.
-- do nothing
else
ret.formatted_categories = require(utilities_module).format_categories(ret.categories, data.lang,
data.sort, nil, force_cat or data.force_cat)
end
end
ret.data = labdata
if label_for_already_seen and data.already_seen then
data.already_seen[label_for_already_seen] = true
end
return ret
end
--[==[
Split a string containing comma-separated raw labels into the individual labels. This will not split on a comma
followed by whitespace, and it will not split inside of matched <...> or [...]. The code is written to be efficient, so
that it does not load modules (e.g. [[Module:parse utilities]]) unnecessarily.
]==]
function export.split_labels_on_comma(term)
if term:find("[%[<]") then
-- Do it the "hard way". We don't want to split anything inside of <...> or <<...>> even if there are commas
-- inside of the angle brackets. For good measure we do the same for [...] and [[...]]. We first parse balanced
-- segment runs involving either [...] or <...>. Then we split alternating runs on comma (but not on
-- comma+whitespace). Then we rejoin the split runs. For example, given the following:
-- "regional,older <<non-rhotic,and,non-hoarse-horse>> speakers", the first call to
-- parse_multi_delimiter_balanced_segment_run() produces
--
-- {"regional,older ", "<<non-rhotic,and,non-hoarse-horse>>", " speakers"}
--
-- After calling split_alternating_runs_on_comma(), we get the following:
--
-- {{"regional"}, {"older ", "<<non-rhotic,and,non-hoarse-horse>>", " speakers"}}
--
-- After rejoining each group, we get:
--
-- {"regional", "older <<non-rhotic,and,non-hoarse-horse>> speakers"}
--
-- which is the desired output. When processing the second "label" string, the code in process_raw_labels()
-- will do a similar process to this to pull out the labels inside of the <<...>> notation.
local put = require(parse_utilities_module)
local segments = put.parse_multi_delimiter_balanced_segment_run(term, {{"<", ">"}, {"[", "]"}})
-- This won't split on comma+whitespace.
local comma_separated_groups = put.split_alternating_runs_on_comma(segments)
for i, group in ipairs(comma_separated_groups) do
comma_separated_groups[i] = concat(group)
end
return comma_separated_groups
elseif term:find(",%s") then
-- This won't split on comma+whitespace.
return require(parse_utilities_module).split_on_comma(term)
elseif term:find(",") then
return require(string_utilities_module).split(term, ",")
else
return {term}
end
end
--[==[
Return a list of objects corresponding to a set of raw labels. Each object returned is of the format returned by
{get_label_info()}. This is similar to looping over the labels and calling {get_label_info()} on each one, but it also
correctly handles embedded double angle bracket specs <<...>> found in the labels. (In such a case, there will be more
objects returned than raw labels passed in.) On input, `data` is an object with the following fields:
* `labels`: The list of labels to process.
* `lang`: The language of the labels. Must be specified.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
]==]
function export.process_raw_labels(data)
local label_infos = {}
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
local function get_info_and_insert(label)
-- Reuse this structure to save memory.
data.label = label
insert(label_infos, export.get_label_info(data))
end
for _, label in ipairs(data.labels) do
if label:find("<<") then
local segments = require(string_utilities_module).split(label, "<<(.-)>>")
for i, segment in ipairs(segments) do
if i % 2 == 1 then
local raw_text_type = i == 1 and "begin" or i == #segments and "end" or "middle"
insert(label_infos, {raw_text = raw_text_type, label = segment, categories = {}})
else
local segment_labels = export.split_labels_on_comma(segment)
for _, segment_label in ipairs(segment_labels) do
get_info_and_insert(segment_label)
end
end
end
else
get_info_and_insert(label)
end
end
return label_infos
end
--[==[
Split a comma-separated string of raw labels and process each label to get a list of objects suitable for passing to
{format_processed_labels()}. Each object returned is of the format returned by {get_label_info()}. This is equivalent to
calling {split_labels_on_comma()} followed by {process_raw_labels()}. On input, `data` is an object with the following
fields:
* `labels`: The string containing the raw comma-separated labels.
* `lang`: The language of the labels. Must be specified.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the label to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for this label.
* `sort`: Sort key for categorization.
* `already_seen`: An object used to track labels already seen, so they aren't displayed twice. Tracking is according
to the display form of the label, so if two labels have the same display form, the second one won't be displayed
(but its categories will still be added). If `already_seen` is {nil}, this tracking doesn't happen.
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
]==]
function export.split_and_process_raw_labels(data)
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
data.labels = export.split_labels_on_comma(data.labels)
return export.process_raw_labels(data)
end
--[==[
Format one or more already-processed labels for display and categorization. "Already-processed" means that
{get_label_info()} or {process_raw_labels()} has been called on the raw labels to convert them into objects containing
information on how to display and categorize the labels. This is a lower-level alternative to {show_labels()} and is
meant for modules such as [[Module:alternative forms]], [[Module:quote]] and [[Module:etymology/templates/descendant]]
that support displaying labels along with some other information.
On input `data` is an object with the following fields:
* `labels`: List of the label objects to format, in the format returned by {get_label_info()}.
* `lang`: The language of the labels.
* `open`: Open bracket or parenthesis to display before the concatenated labels. If specified, it is wrapped in the
{"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no open bracket is displayed.
* `close`: Close bracket or parenthesis to display after the concatenated labels. If specified, it is wrapped in the
{"ib-brac"} and {"label-brac"} CSS classes. If {nil} or {false}, no close bracket is displayed.
* `no_ib_content`: By default, the concatenated formatted labels inside of the open/close brackets are wrapped in the
{"ib-content"} and {"label-content"} CSS classes. Specify this to suppress this wrapping.
* `raw`: Suppress all CSS wrapping of content, including open/close parentheses, content and comma delimiters (which
are normally wrapped in {"ib-comma"} and {"label-comma"} CSS classes).
* `ok_to_destructively_modify`: If set, the `data` structure, and the `data.labels` table inside of it, will be
destructively modified in the process of this function running.
* `split_output`: If not given, the return value is a concatenation of the formatted concatenated labels and formatted
categories. Otherwise, two values are returned: the formatted pronunciation and the categories. If `split_output` is
the value {"raw"}, the categories are returned in list form, where the list elements are strings f the form suitable
for passing to {format_categories()} in [[Module:utilities]]. If `split_output` is any other value besides {nil}, the
categories are returned as a pre-formatted concatenated string.
The return value (or the first return value, if `split_output` is given) is a string containing the contenated labels,
optionally surrounded by open/close brackets or parentheses. Normally, labels are separated by comma-space sequences,
but this may be suppressed for certain labels. If `nocat` wasn't given to {get_label_info()} or {process_raw_labels()},
and `split_output` wasn't given, the label objects will contain formatted categories in them, which will be inserted
into the returned text. (Use `split_output` if you need the categories returned separately.) The concatenated text
inside of the open/close brackets is normally wrapped in the {"ib-content"} CSS class, but this can be suppressed, as
mentioned above.
]==]
function export.format_processed_labels(data)
if not data.labels then
error("`data` must now be an object containing the params")
end
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.labels = m_table.deepCopy(data.labels)
data.ok_to_destructively_modify = true
end
local labels = data.labels
if not labels[1] then
error("You must specify at least one label.")
end
local split_output = data.split_output
-- Show the labels
local omit_preComma
local omit_preSpace
local omit_postComma = true
local omit_postSpace = true
for _, label in ipairs(labels) do
omit_preComma = omit_postComma
omit_preSpace = omit_postSpace
local raw_text_omit_before = label.raw_text == "middle" or label.raw_text == "end"
local raw_text_omit_after = label.raw_text == "middle" or label.raw_text == "begin"
label.omit_comma = omit_preComma or (label.data and label.data.omit_preComma) or raw_text_omit_before
omit_postComma = (label.data and label.data.omit_postComma) or raw_text_omit_after
label.omit_space = omit_preSpace or (label.data and label.data.omit_preSpace) or raw_text_omit_before
omit_postSpace = (label.data and label.data.omit_postSpace) or raw_text_omit_after
end
if data.lang then
local lang_functions_module = export.lang_specific_data_modules_prefix .. data.lang:getCode() .. "/functions"
local m_lang_functions = require(load_module).safe_require(lang_functions_module)
if m_lang_functions and m_lang_functions.postprocess_handlers then
for _, handler in ipairs(m_lang_functions.postprocess_handlers) do
handler(data)
end
end
end
local function wrap_css(txt, suffix)
if data.raw then
return txt
end
return ("<span class=\"ib-%s label-%s\">%s</span>"):format(suffix, suffix, txt)
end
local categories = nil
local formatted_categories = split_output and split_output ~= "raw" and {} or nil
for i, labelinfo in ipairs(labels) do
local label
-- Need to check for 'not raw_text' here because blank labels may legitimately occur as raw text if a double
-- angle bracket spec occurs at the beginning of a label. In this case we've already taken into account the
-- context and don't want to leave out a preceding comma and space e.g. in a case like
-- {{lb|en|rare|<<dialect>> or <<eye dialect>>}}. FIXME: We should reconsider whether we need this special case
-- at all.
if labelinfo.label == "" and not labelinfo.raw_text then
label = ""
else
label = (labelinfo.omit_comma and "" or wrap_css(",", "comma")) ..
(labelinfo.omit_space and "" or " ") ..
labelinfo.label
end
if split_output then
labels[i] = label
if split_output == "raw" then
if labelinfo.categories and labelinfo.categories[1] then
if categories then
m_table.extend(categories, labelinfo.categories)
else
categories = labelinfo.categories
end
end
elseif labelinfo.formatted_categories then
insert(formatted_categories, labelinfo.formatted_categories)
end
else
labels[i] = label .. (labelinfo.formatted_categories or "")
end
end
local function wrap_open_close(val)
if val then
return wrap_css(val, "brac")
else
return ""
end
end
local concatenated_labels = concat(labels, "")
if not data.no_ib_content then
concatenated_labels = wrap_css(concatenated_labels, "content")
end
local ret_labels = wrap_open_close(data.open) .. concatenated_labels .. wrap_open_close(data.close)
if split_output == "raw" then
return ret_labels, categories
elseif split_output then
return ret_labels, concat(formatted_categories)
else
return ret_labels
end
end
--[==[
Format one or more labels for display and categorization. This provides the implementation of the
{{tl|label}}/{{tl|lb}}, {{tl|term label}}/{{tl|tlb}} and {{tl|accent}}/{{tl|a}} templates, and can also be called from a
module. The return value is a string to be inserted into the generated page, including the display and categories. On
input `data` is an object with the following fields:
* `labels`: List of the labels to format.
* `lang`: The language of the labels.
* `mode`: How the label was invoked; see {get_label_info()} for more information.
* `nocat`: If true, don't add the labels to any categories.
* `force_cat`: Force adding categories even in namespaces that normally exclude them (e.g. userspace and discussion
pages).
* `notrack`: Disable all tracking for these labels.
* `sort`: Sort key for categorization.
* `no_track_already_seen`: Don't track already-seen labels. If not specified, already-seen labels are not displayed
again, but still categorize. See the documentation of {get_label_info()}.
* `open`: Open bracket or parenthesis to display before the concatenated labels. If {nil}, defaults to an open
parenthesis. Set to {false} to disable.
* `close`: Close bracket or parenthesis to display after the concatenated labels. If {nil}, defaults to a close
parenthesis. Set to {false} to disable.
* `no_ib_content`: As in `format_processed_labels()`.
* `raw`: As in `format_processed_labels()`. Also suppress wrapping the entire formatted result in a usage label CSS
class (see below).
* `ok_to_destructively_modify`: If set, the `data` structure will be destructively modified in the process of this
function running.
Compared with {format_processed_labels()}, this function has the following differences:
# The labels specified in `labels` are raw labels (i.e. strings) rather than formatted objects.
# The open and close brackets default to parentheses ("round brackets") rather than not being displayed by default.
# Tracking of already-seen labels is enabled unless explicitly turned off using `no_track_already_seen`.
# The entire formatted result is wrapped in a {"usage-label-<var>type</var>"} CSS class (depending on the value of
`mode`), unless `raw` is given.
]==]
function export.show_labels(data)
if not data.labels then
error("`data` must now be an object containing the params")
end
if not data.ok_to_destructively_modify then
data = m_table.shallowCopy(data)
data.ok_to_destructively_modify = true
end
local labels = data.labels
if not labels[1] then
error("You must specify at least one label.")
end
local mode = validate_mode(data.mode)
if not data.no_track_already_seen then
data.already_seen = {}
end
data.labels = export.process_raw_labels(data)
if data.open == nil then
data.open = "("
end
if data.close == nil then
data.close = ")"
end
local formatted = export.format_processed_labels(data)
if data.raw then
return formatted
else
return "<span class=\"" .. mode_to_outer_class[mode] .. "\">" .. formatted .. "</span>"
end
end
--[==[Helper function for the data modules.]==]
function export.alias(labels, key, aliases)
m_table.alias(labels, key, aliases)
end
--[==[
Split the display form of a label. Returns two values: `link` and `display`. If the display form consists of a
two-part link, `link` is the first part and `display` is the second part. If the display form consists of a
single-part link, `link` and `display` are the same. Otherwise (the display form is not a link or contains an
embedded link), `link` is the same as the passed-in `label` and `display` is nil.
]==]
function export.split_display_form(label)
if not label:find("%[%[") then
return label, nil
end
local link, display = label:match("^%[%[([^%[%]|]+)|([^%[%]|]+)%]%]$")
if link then
return link, display
end
link = label:match("^%[%[([^%[%]|])+%]%]$")
if link then
return link, link
end
return label, nil
end
--[==[
Combine the `link` and `display` parts of the display form of a label as returned by {split_display_form()}.
If `display` is nil, `link` is returned directly. Otherwise, a one-part or two-part link is constructed
depending on whether `link` and `display` are the same. (As a special case, if both consist of a blank string,
the return value is a blank string rather than a malformed link.)
]==]
function export.combine_display_form_parts(link, display)
if not display then
return link
end
if link == display then
if link == "" then
return ""
else
return ("[[%s]]"):format(link)
end
end
return ("[[%s|%s]]"):format(link, display)
end
--[==[Used to finalize the data into the form that is actually returned.]==]
function export.finalize_data(labels)
local shallow_copy = m_table.shallowCopy
local aliases = {}
for label, data in pairs(labels) do
if type(data) == "table" then
if data.aliases then
for _, alias in ipairs(data.aliases) do
aliases[alias] = label
end
data.aliases = nil
end
if data.deprecated_aliases then
local data2 = shallow_copy(data)
data2.deprecated = true
data2.canonical = label
for _, alias in ipairs(data2.deprecated_aliases) do
aliases[alias] = data2
end
data.deprecated_aliases = nil
data2.deprecated_aliases = nil
end
end
end
for label, data in pairs(aliases) do
labels[label] = data
end
return labels
end
return export
r963e5jdq0he9ubedo9qpqbgnon99r0
Templat:ur-kn
10
10306
375879
245545
2026-09-25T13:04:28Z
Hakimi97
2668
Kemas kini kod
375879
wikitext
text/x-wiki
{{#invoke:inc-headword|show|Kata nama|lang=ur}}<!--
--><noinclude>{{documentation}}</noinclude>
dyfrggfgidg6c7vdwbg89oarqdof7jw
375880
375879
2026-09-25T13:05:07Z
Hakimi97
2668
Tetapkan semula
375880
wikitext
text/x-wiki
{{#invoke:inc-headword|show|nouns|lang=ur}}<!--
--><noinclude>{{documentation}}</noinclude>
l75nwuste0zhpnotpp7t9g3yg0ys9p6
Modul:etymology/templates
828
11467
375890
375842
2026-09-26T02:28:20Z
Hakimi97
2668
Kemas kini
375890
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or (lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local current_L2 = get_current_L2()
if not current_L2 then
return
end
local full_name = "Bahasa " .. lang:getFullName()
if full_name == current_L2 then
return
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(current_L2)
if L2_lang and is_sinitic(L2_lang) then
return
end
end
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc .. ", an etymology-only language whose full language is " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error("Language '" .. lang_desc .. "' does not match the L2 header (" .. current_L2 .. ").")
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] doesn't support multiple comma-separated sources")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Invalid characters in |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Duplicate param |" .. param
.. " in |ignore-params=: already specified in params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
as65hv3r4cb26k6gboxfn79yebm82l8
375892
375890
2026-09-26T02:45:02Z
Hakimi97
2668
Detect "Bahasa X" pattern for L2
375892
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or (lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local current_L2 = get_current_L2()
if not current_L2 then
return
end
current_L2 = trim(current_L2)
-- Malay Wiktionary language sections use ==Bahasa X==.
-- Convert the actual L2 heading back to the canonical language name
-- before comparing it with the language object's full name.
local current_L2_name = current_L2:match("^Bahasa%s+(.+)$") or current_L2
local full_name = lang:getFullName()
if full_name == current_L2_name then
return
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(current_L2_name)
if L2_lang and is_sinitic(L2_lang) then
return
end
end
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc .. ", an etymology-only language whose full language is " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error("Language '" .. lang_desc .. "' does not match the L2 header (" .. current_L2 .. ").")
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] doesn't support multiple comma-separated sources")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Invalid characters in |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Duplicate param |" .. param
.. " in |ignore-params=: already specified in params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
43mmi1ia2rythzufre40k4sxdcuj2wx
375893
375892
2026-09-26T02:49:06Z
Hakimi97
2668
Ensure detect "Bahasa X" and "Rentas bahasa" L2 header
375893
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or (lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local current_L2 = get_current_L2()
if not current_L2 then
return
end
current_L2 = trim(current_L2)
-- Malay Wiktionary language sections use ==Bahasa X==.
-- Convert the actual L2 heading back to the canonical language name
-- before comparing it with the language object's full name.
local current_L2_name = current_L2:match("^Bahasa%s+(.+)$") or current_L2
if current_L2_name == "Rentas bahasa" then
current_L2_name = "rentas bahasa"
end
local full_name = lang:getFullName()
if full_name == current_L2_name then
return
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(current_L2_name)
if L2_lang and is_sinitic(L2_lang) then
return
end
end
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc .. ", an etymology-only language whose full language is " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error("Language '" .. lang_desc .. "' does not match the L2 header (" .. current_L2 .. ").")
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] doesn't support multiple comma-separated sources")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Invalid characters in |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Duplicate param |" .. param
.. " in |ignore-params=: already specified in params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
rbx3t5680w5xab6720q2oyff6siposc
375894
375893
2026-09-26T06:14:29Z
Hakimi97
2668
Pembetulan dari segi penyetempatan kod
375894
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or (lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local current_L2 = get_current_L2()
if not current_L2 then
return
end
current_L2 = trim(current_L2)
local current_L2_name = current_L2:match("^Bahasa%s+(.+)$") or current_L2
if current_L2_name == "Rentas bahasa" then
current_L2_name = "rentas bahasa"
end
local full_name = lang:getFullName()
if full_name == current_L2_name then
return
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(current_L2_name)
if L2_lang and is_sinitic(L2_lang) then
return
end
end
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc .. ", bahasa etimologi sahaja yang bahasa penuhnya ialah " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error("Bahasa '" .. lang_desc .. "' tidak sepadan dengan pengepala L2 (" .. current_L2 .. ").")
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] tidak menyokong berbilang sumber yang dipisahkan dengan koma")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Aksara tidak sah dalam |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Parameter pendua |" .. param
.. " dalam |ignore-params=: sudah dinyatakan dalam params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
3vr4vz8mc61j2y0s2yzwxvg0xj6w0b9
375900
375894
2026-09-26T06:32:08Z
Hakimi97
2668
Pembetulan pengesanan pengepala L2
375900
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Malay Wiktionary uses L2 headings in the form "Bahasa <language>",
-- while language objects use the bare canonical name.
local function normalize_L2_name(name)
if not name then
return nil
end
return name:match("^Bahasa%s+(.+)$") or name
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or
(lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local current_L2 = get_current_L2()
if not current_L2 then
return
end
-- Malay Wiktionary uses headings such as "Bahasa Inggeris",
-- whereas lang:getFullName() returns "Inggeris".
local current_L2_name = normalize_L2_name(current_L2)
local full_name = lang:getFullName()
if full_name == current_L2_name then
return
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(current_L2_name)
if L2_lang and is_sinitic(L2_lang) then
return
end
end
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc ..
", bahasa etimologi sahaja yang bahasa penuhnya ialah " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error(
"Bahasa '" .. lang_desc ..
"' tidak sepadan dengan pengepala L2 (" .. current_L2 .. ")."
)
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] tidak menyokong berbilang sumber yang dipisahkan dengan koma")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Aksara tidak sah dalam |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Parameter pendua |" .. param
.. " dalam |ignore-params=: sudah dinyatakan dalam params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
nixrgpv183orafo6n0cke9hfiha74uh
375911
375900
2026-09-26T07:43:55Z
Hakimi97
2668
Betulkan ralat L2 (cubaan kedua)
375911
Scribunto
text/plain
local export = {}
local require_when_needed = require("Module:require when needed")
local get_current_L2 = require_when_needed("Module:pages", "get_current_L2")
local get_lang_by_name = require_when_needed("Module:languages", "getByCanonicalName")
local is_content_page = require_when_needed("Module:pages", "is_content_page")
local process_params = require_when_needed("Module:parameters", "process")
local trim = mw.text.trim
local lower = mw.ustring.lower
local etymology_module = "Module:etymology"
local headword_data_module = "Module:headword/data"
local etymology_specialized_module = "Module:etymology/specialized"
local parameter_utilities_module = "Module:parameter utilities"
-- For testing
local force_cat = false
local allowed_conjs = {"and", "or", ",", "/", "~", ";"}
-- Sinitic lects (Mandarin, Cantonese, Hokkien, etc.) are full languages, but Chinese entries sit
-- under a single ==Chinese== L2, while romanization entries (pinyin, jyutping, pe̍h-ōe-jī) have lect
-- L2s, and content is often shared between them. Contact languages (Chinese-based creoles and mixed
-- languages) have their own L2s and are excluded.
local function is_sinitic(lang)
return lang:inFamily("zhx") and not lang:inFamily("qfa-cnt")
end
local content_page
local function is_content_page_cached()
if content_page == nil then
content_page = is_content_page(mw.title.getCurrentTitle())
end
return content_page
end
-- Malay Wiktionary uses L2 headings in the form "Bahasa <language>",
-- while language objects use the bare canonical name.
local function normalize_L2_name(name)
if not name then
return nil
end
return name:match("^Bahasa%s+(.+)$") or name
end
-- Check whether an L2 heading is compatible with the specified language.
local function L2_matches_lang(L2, lang)
if not L2 then
return false
end
local L2_name = normalize_L2_name(trim(L2))
local full_name = lang:getFullName()
if L2_name == full_name then
return true
end
-- Accept any Sinitic language under any Sinitic L2.
if is_sinitic(lang) then
local L2_lang = get_lang_by_name(L2_name)
if L2_lang and is_sinitic(L2_lang) then
return true
end
end
return false
end
-- Throw an error if `lang` (the language of the entry) doesn't match
-- the L2 header that the template is invoked under.
local function check_lang_matches_L2(lang, nocat)
if nocat or not lang or lang:getCode() == "und" or
(lang.hasType and lang:hasType("family")) then
return
end
local headword_data = mw.loadData(headword_data_module)
if headword_data.large_pages[headword_data.pagename] then
return
end
if not is_content_page_cached() then
return
end
local page_data = headword_data.page
local L2_list = page_data and page_data.L2_list
local current_L2
-- If the page contains exactly one L2, its identity is unambiguous
-- and does not depend on parser-specific section detection.
if L2_list and L2_list.n == 1 then
current_L2 = trim(L2_list[1])
if L2_matches_lang(current_L2, lang) then
return
end
-- On multilingual pages, try to determine the current L2 normally.
else
current_L2 = get_current_L2()
if current_L2 then
current_L2 = trim(current_L2)
if L2_matches_lang(current_L2, lang) then
return
end
end
-- Under Parsoid, get_current_L2() can incorrectly return another
-- L2 (often the preceding one). If a compatible L2 actually exists
-- somewhere on this multilingual page, the result is ambiguous,
-- so don't throw a false-positive error.
if L2_list then
for i = 1, L2_list.n do
if L2_matches_lang(L2_list[i], lang) then
return
end
end
end
-- Preserve the previous behaviour if no current L2 can be found.
if not current_L2 then
return
end
end
local full_name = lang:getFullName()
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if lang:getFullCode() ~= lang:getCode() then
lang_desc = lang_desc ..
", bahasa etimologi sahaja yang bahasa penuhnya ialah " ..
lang:getFullCode() .. " (" .. full_name .. ")"
end
error(
"Bahasa '" .. lang_desc ..
"' tidak sepadan dengan pengepala L2 (" .. current_L2 .. ")."
)
end
local function parse_etym_args(parent_args, base_params, has_dest_lang)
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local sourcearg, termarg
if has_dest_lang then
sourcearg, termarg = 2, 3
else
sourcearg, termarg = 1, 2
end
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = base_params,
param_mods = param_mods,
raw_args = parent_args,
termarg = termarg,
track_module = "etymology",
lang = function(args)
return args[sourcearg][#args[sourcearg]]
end,
sc = "sc",
-- Don't do this, doesn't seem to make sense.
-- parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
-- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for
-- compatibility,, insert one. It will display as <small>[Term?]</small>.
if not terms.terms[1] then
terms.terms[1] = {
lang = args[sourcearg][#args[sourcearg]],
sc = args.sc,
}
end
return terms.terms, args
end
function export.parse_2_lang_args(parent_args, has_text, no_family)
local boolean = {type = "boolean"}
local params = {
[1] = {
required = true,
type = "language",
default = "und"
},
[2] = {
required = true,
sublist = true,
type = "language",
family = not no_family,
default = "und"
},
[3] = true,
[4] = {alias_of = "alt"},
[5] = {alias_of = "t"},
["senseid"] = true,
["nocat"] = boolean,
["sort"] = true,
["sourceconj"] = true,
["conj"] = {set = allowed_conjs, default = ","},
}
if has_text then
params["notext"] = boolean
params["nocap"] = boolean
end
local terms, args = parse_etym_args(parent_args, params, "has dest lang")
check_lang_matches_L2(args[1], args.nocat)
return terms, args
end
-- Implementation of deprecated {{etyl}}. Provided to make histories more legible.
function export.etyl(frame)
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {type = "language", default = "ms"},
["sort"] = {},
}
-- Empty language means Malay, but "-" means no language. Yes, confusing...
local args = frame:getParent().args
if args[2] and trim(args[2]) == "-" then
params[2] = nil
args = process_params({
[1] = args[1],
["sort"] = args.sort
}, params)
else
args = process_params(args, params)
end
check_lang_matches_L2(args[2])
return require(etymology_module).format_source {
lang = args[2],
source = args[1],
sort_key = args.sort,
force_cat = force_cat,
}
end
-- Implementation of {{derived}}/{{der}}.
function export.derived(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_derived {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
template_name = "derived",
force_cat = force_cat,
}
end
-- Implementation of {{borrowed}}/{{bor}}.
function export.borrowed(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
return require(etymology_module).format_borrowed {
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.inherited(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args)
local sources = args[2]
if sources[2] then
-- Because this doesn't really make sense.
error("[[Template:inherited]] tidak menyokong berbilang sumber yang dipisahkan dengan koma")
end
return require(etymology_module).format_inherited {
lang = args[1],
terms = terms,
sort_key = args.sort,
nocat = args.nocat,
conj = args.conj,
force_cat = force_cat,
}
end
function export.cognate(frame)
local params = {
[1] = {
required = true,
sublist = true,
type = "language",
family = true,
default = "und"
},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
sourceconj = true,
["conj"] = {set = allowed_conjs, default = ","},
sort = true,
}
local parent_args = frame:getParent().args
local terms, args = parse_etym_args(parent_args, params, false)
return require(etymology_module).format_cognate {
sources = args[1],
terms = terms,
sort_key = args.sort,
sourceconj = args.sourceconj,
conj = args.conj,
force_cat = force_cat,
}
end
function export.noncognate(frame)
return export.cognate(frame)
end
-- Supports various specialized types of borrowings, according to `frame.args.bortype`:
-- "learned" = {{lbor}}/{{learned borrowing}}
-- "semi-learned" = {{slbor}}/{{semi-learned borrowing}}
-- "orthographic" = {{obor}}/{{orthographic borrowing}}
-- "unadapted" = {{ubor}}/{{unadapted borrowing}}
-- "calque" = {{cal}}/{{calque}}
-- "partial-calque" = {{pcal}}/{{partial calque}}
-- "semantic-loan" = {{sl}}/{{semantic loan}}
-- "transliteration" = {{translit}}/{{transliteration}}
-- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}}
function export.specialized_borrowing(frame)
local parent_args = frame:getParent().args
local terms, args = export.parse_2_lang_args(parent_args, "has text")
local m_etymology_specialized = require(etymology_specialized_module)
return m_etymology_specialized.specialized_borrowing {
bortype = frame.args.bortype,
lang = args[1],
sources = args[2],
terms = terms,
sort_key = args.sort,
nocap = args.nocap,
notext = args.notext,
nocat = args.nocat,
sourceconj = args.sourceconj,
conj = args.conj,
senseid = args.senseid,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}},
-- {{rebracketing}} and {{reduplication}} that have a single associated term.
function export.misc_variant(frame)
local iparams = {
["ignore-params"] = true,
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = true,
[3] = {alias_of = "alt"},
[4] = {alias_of = "t"},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
-- |ignore-params= parameter to module invocation specifies
-- additional parameter names to allow in template invocation, separated by
-- commas. They must consist of ASCII letters or numbers or hyphens.
local ignore_params = iargs["ignore-params"]
if ignore_params then
ignore_params = trim(ignore_params)
if not ignore_params:match("^[%w%-,]+$") then
error("Aksara tidak sah dalam |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", ""))
end
for param in ignore_params:gmatch("[%w%-]+") do
if params[param] then
error("Parameter pendua |" .. param
.. " dalam |ignore-params=: sudah dinyatakan dalam params")
end
params[param] = true
end
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
track_module = "etymology",
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc",
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms.terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}}
-- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]].
function export.misc_variant_multiple_terms(frame)
local iparams = {
text = {required = true},
oftext = true,
cat = {list = true}, -- allow and compress holes
conj = true,
}
local iargs = process_params(frame.args, iparams)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", template_default = "und"},
[2] = {list = true, allow_holes = true},
nocap = boolean, -- should be processed in the template itself
notext = boolean,
nocat = boolean,
conj = {set = allowed_conjs},
sort = true,
}
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
-- We want to require an index for all params.
{default = true, require_index = true},
{group = {"link", "q", "l", "ref"}},
}
local parent_args = frame:getParent().args
local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
parse_lang_prefix = true,
allow_multiple_lang_prefixes = true,
track_module = "etymology-templates-doublet",
disallow_custom_separators = true,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Don't set lang here as we want to know whether there was a lang prefix or not.
sc = "sc.default",
}
check_lang_matches_L2(args[1], args.nocat)
return require(etymology_module).format_misc_variant {
lang = args[1],
notext = args.notext,
text = iargs.text,
oftext = iargs.oftext,
terms = terms,
sort_key = args.sort,
conj = args.conj or iargs.conj or "and",
nocat = args.nocat,
cats = iargs.cat,
force_cat = force_cat,
}
end
-- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms.
do
local function get_args(frame)
local boolean = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
["title"] = true,
["nocap"] = boolean, -- should be processed in the template itself
["notext"] = boolean,
["nocat"] = boolean,
["sort"] = true,
}
if frame.args.title2_alias then
params[2] = {alias_of = "title"}
end
local args = process_params(frame:getParent().args, params)
check_lang_matches_L2(args[1], args.nocat)
return args
end
function export.misc_variant_no_term(frame)
local args = get_args(frame)
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = args.title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
-- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in
-- `title`.
function export.onomatopoeia(frame)
local args = get_args(frame)
local title = args.title
if title and (lower(title) == "imitatif" or lower(title) == "imitasi" or lower(title) == "tiruan" or lower(title) == "peniruan") then
title = "[[Lampiran:Glosari#imitatif|" .. title .. "]]"
end
return require(etymology_module).format_misc_variant_no_term {
lang = args[1],
notext = args.notext,
title = title or frame.args.text,
nocat = args.nocat,
cat = frame.args.cat,
sort_key = args.sort,
force_cat = force_cat,
}
end
end
return export
m0x9y6646e4zigavzy47y9l7l8mvuio
Modul:etymology
828
11468
375898
375373
2026-09-26T06:14:39Z
Hakimi97
2668
Pembetulan dari segi penyetempatan kod
375898
Scribunto
text/plain
local export = {}
-- For testing
local force_cat = false
local debug_track_module = "Module:debug/track"
local languages_module = "Module:languages"
local links_module = "Module:links"
local table_module = "Module:table"
local utilities_module = "Module:utilities"
local concat = table.concat
local insert = table.insert
local new_title = mw.title.new
local function debug_track(...)
debug_track = require(debug_track_module)
return debug_track(...)
end
local function format_categories(...)
format_categories = require(utilities_module).format_categories
return format_categories(...)
end
local function full_link(...)
full_link = require(links_module).full_link
return full_link(...)
end
local function get_language_data_module_name(...)
get_language_data_module_name = require(languages_module).getDataModuleName
return get_language_data_module_name(...)
end
local function get_link_page(...)
get_link_page = require(links_module).get_link_page
return get_link_page(...)
end
local function language_link(...)
language_link = require(links_module).language_link
return language_link(...)
end
local function serial_comma_join(...)
serial_comma_join = require(table_module).serialCommaJoin
return serial_comma_join(...)
end
local function shallow_copy(...)
shallow_copy = require(table_module).shallowCopy
return shallow_copy(...)
end
local function track(page, code)
local tracking_page = "etymology/" .. page
debug_track(tracking_page)
if code then
debug_track(tracking_page .. "/" .. code)
end
end
local function join_segs(segs, conj)
if not segs[2] then
return segs[1]
elseif conj == "and" or conj == "or" then
return serial_comma_join(segs, {conj = conj})
end
local sep
if conj == "," or conj == ";" then
sep = conj .. " "
elseif conj == "/" then
sep = "/"
elseif conj == "~" then
sep = " ~ "
elseif conj then
error(("Internal error: Unrecognized conjunction \"%s\""):format(conj))
else
error(("Internal error: No value supplied for conjunction"):format(conj))
end
return concat(segs, sep)
end
-- Returns true if `lang` is the same as `source`, or a variety of it.
local function lang_is_source(lang, source)
return lang:getCode() == source:getCode() or lang:hasParent(source)
end
--[==[
Format one or more links as specified in `termobjs`, a list of term objects of the format accepted by `full_link()` in
[[Module:links]], including decorations (qualifiers, labels and references). `conj` is used to join multiple terms
and must be specified if there is more than one term. `template_name` is the template name used in debug tracking and
must be specified. Optional `sourcetext` is text to prepend to the concatenated terms, separated by a space if the
concatenated terms are non-empty (which is always the case unless there is a single term with the value "-"). If
`decorations_on_outside` is given, any decorations specified in the first term go on the outside of (i.e before)
`sourcetext`; otherwise they will end up on the inside.
]==]
function export.format_links(termobjs, conj, template_name, sourcetext, decorations_on_outside)
if not template_name then
error("Internal error: Must specify `template_name` to format_links()")
end
for i, termobj in ipairs(termobjs) do
if termobj.lang:hasType("family") or termobj.lang:getFamilyCode() == "qfa-sub" then
if termobj.term and termobj.term ~= "-" then
debug_track(template_name .. "/family-with-term")
end
termobj.term = "-"
end
if termobj.term == "-" then
--[=[
[[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]]
]=]
debug_track(template_name .. "/no-term")
termobjs[i] = i == 1 and sourcetext or ""
else
if i == 1 and decorations_on_outside and sourcetext then
termobj.pretext = sourcetext .. " "
sourcetext = nil
end
termobjs[i] = (i == 1 and sourcetext and sourcetext .. " " or "") .. full_link(termobj, "term")
end
end
return join_segs(termobjs, conj)
end
function export.get_display_and_cat_name(source, raw)
local display, cat_name
if source:getCode() == "und" then
display = "tidak ditentukan"
cat_name = "bahasa lain"
elseif source:getCode() == "mul" then
display = raw and "rentas bahasa" or "[[w:Translingualisme|rentas bahasa]]"
cat_name = "Rentas bahasa"
elseif source:getCode() == "mul-tax" then
display = raw and "nama taksonomi" or "[[w:Tatanama biologi|nama taksonomi]]"
cat_name = "Nama taksonomi"
else
display = raw and source:getCanonicalName() or source:makeWikipediaLink()
cat_name = source:getDisplayForm()
end
return display, cat_name
end
function export.insert_source_cat_get_display(data)
local categories, lang, source = data.categories, data.lang, data.source
local display, cat_name = export.get_display_and_cat_name(source, data.raw)
if lang and not data.nocat then
-- Add the category, but only if there is a current language
if not categories then
categories = {}
end
local langname = lang:getFullName()
-- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`.
-- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a
-- category 'Latin terms derived from Latin'.
insert(categories, "Perkataan bahasa " .. langname .. (
lang_is_source(lang, source) and " dipinjam balik ke dalam bahasa " .. cat_name or
" " .. (data.borrowing_type or "diterbitkan") .. " daripada bahasa " .. cat_name
))
end
return display, categories
end
function export.format_source(data)
local lang, sort_key = data.lang, data.sort_key
-- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]]
if sort_key then
track("sortkey")
end
local display, categories = export.insert_source_cat_get_display(data)
if lang and not data.nocat then
-- Format categories, but only if there is a current language; {{cog}} currently gets no categories
categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat)
else
categories = ""
end
return "<span class=\"etyl\">" .. display .. categories .. "</span>"
end
--[==[
Format sources for etymology templates such as {{tl|bor}}, {{tl|der}}, {{tl|inh}} and {{tl|cog}}. There may potentially
be more than one source language (except currently {{tl|inh}}, which doesn't support it because it doesn't really
make sense). In that case, all but the last source language is linked to the first term, but only if there is such a
term and this linking makes sense, i.e. either (1) the term page exists after stripping diacritics according to the
source language in question, or (2) the result of stripping diacritics according to the source language in question
results in a different page from the same process applied with the last source language. For example, {{m|ru|соля́нка}}
will link to [[солянка]] but {{m|en|соля́нка}} will link to [[соля́нка]] with an accent, and since they are different
pages, the use of English as a non-final source with term 'соля́нка' will link to [[соля́нка]] even though it doesn't
exist, on the assumption that it is merely a redlink that might exist. If none of the above criteria apply, a non-final
source language will be linked to the Wikipedia entry for the language, just as final source languages always are.
`data` contains the following fields:
* `lang`: The destination language object into which the terms were borrowed, inherited or otherwise derived. Used for
categorization and can be nil, as with {{tl|cog}}.
* `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are
handled specially; see above.
* `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as
multiple term objects, the non-final source objects link to the first term object.
* `sort_key`: Sort key for categories. Usually nil.
* `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source
languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be
added.
* `nocat`: Don't add any categories to the page.
* `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized
values are `and`, `or`, `,`, `;`, `/` and `~`.
* `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}.
* `force_cat`: Force category generation on non-mainspace pages.
]==]
function export.format_sources(data)
local lang, sources, terms, borrowing_type, sort_key, categories, nocat =
data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat
local term1, sources_n, source_segs = terms[1], #sources, {}
local final_link_page
local term1_term, term1_sc = term1.term, term1.sc
if sources_n > 1 and term1_term and term1_term ~= "-" then
final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc)
end
for i, source in ipairs(sources) do
local seg, display_term
if i < sources_n and term1_term and term1_term ~= "-" then
local link_page = get_link_page(term1_term, source, term1_sc)
display_term = (link_page ~= final_link_page) or (link_page and not not new_title(link_page):getContent())
end
-- TODO: if the display forms or transliterations are different, display the terms separately.
if display_term then
local display, this_cats = export.insert_source_cat_get_display{
lang = lang,
source = source,
borrowing_type = borrowing_type,
raw = true,
categories = categories,
nocat = nocat,
}
seg = language_link {
lang = source,
term = term1_term,
alt = display,
tr = "-",
}
if lang and not nocat then
-- Format categories, but only if there is a current language; {{cog}} currently gets no categories
this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat)
else
this_cats = ""
end
seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>"
else
seg = export.format_source{
lang = lang,
source = source,
borrowing_type = borrowing_type,
sort_key = sort_key,
categories = categories,
nocat = nocat,
}
end
insert(source_segs, seg)
end
return join_segs(source_segs, data.sourceconj or "and")
end
-- Internal implementation of {{cognate}}/{{cog}} template.
function export.format_cognate(data)
return export.format_derived {
sources = data.sources,
terms = data.terms,
sort_key = data.sort_key,
sourceconj = data.sourceconj,
conj = data.conj,
template_name = "cognate",
force_cat = data.force_cat,
}
end
--[==[
Internal implementation of {{derived}}/{{der}} template. This is called externally from [[Module:affix]],
[[Module:affixusex]] and [[Module:see]] and needs to support decorations (qualifiers, labels and references) on the
outside of the sources for use by those modules.
`data` contains the following fields:
* `lang`: The destination language object into which the terms were derived. Used for categorization and can be nil, as
with {{tl|cog}}; in this case, no categories are added.
* `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are
handled specially; see `format_sources()`.
* `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as
multiple term objects, the non-final source objects link to the first term object.
* `conj`: Conjunction used to separate multiple terms. '''Required'''. Currently recognized values are `and`, `or`, `,`,
`;`, `/` and `~`.
* `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized
values are as for `conj` above.
* `decorations_on_outside`: If specified, any decorations (qualifiers, labels or references) in the first term in
`terms` will be displayed on the outside of (before) the source language(s) in `sources`. Normally this should be
specified if there is only one term possible in `terms`.
* `template_name`: Name of the template invoking this function. Must be specified. Only used for tracking pages.
* `sort_key`: Sort key for categories. Usually nil.
* `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source
languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be
added.
* `nocat`: Don't add any categories to the page.
* `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}.
* `force_cat`: Force category generation on non-mainspace pages.
]==]
function export.format_derived(data)
local terms = data.terms
local sourcetext = export.format_sources(data)
return export.format_links(terms, data.conj, data.template_name, sourcetext, data.decorations_on_outside)
end
function export.insert_borrowed_cat(categories, lang, source)
if lang_is_source(lang, source) then
return
end
-- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not
-- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source().
-- The second parameter here doesn't matter as it only affects `display`, which we don't use.
insert(categories, "Perkataan bahasa " .. lang:getFullName() .. " dipinjam daripada bahasa " .. select(2, export.get_display_and_cat_name(source, "raw")))
end
-- Internal implementation of {{borrowed}}/{{bor}} template.
function export.format_borrowed(data)
local categories = {}
if not data.nocat then
local lang = data.lang
for _, source in ipairs(data.sources) do
export.insert_borrowed_cat(categories, lang, source)
end
end
data = shallow_copy(data)
data.categories = categories
return export.format_links(data.terms, data.conj, "borrowed", export.format_sources(data))
end
do
-- Generate the non-ancestor error message.
local function show_language(lang)
local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode())
if lang:hasType("etymology-only") then
retval = retval .. (" (bahasa etimologi sahaja yang bahasa induk biasanya ialah %s)"):format(
show_language(lang:getParent()))
end
return retval
end
-- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if
-- not. When `lang` is a family, verifies that `otherlang` is a language in that family.
function export.check_ancestor(lang, otherlang)
-- When `lang` is a family, verify `otherlang` is in that family or in its parent family.
if lang.hasType and lang:hasType("family") then
local family_code = lang:getCode()
local function in_family_code(fcode, other)
if not fcode or fcode == "" then return false end
if other.inFamily and other:inFamily(fcode) then return true end
if other.getFamilyCode and other:getFamilyCode() == fcode then return true end
return false
end
local in_family = in_family_code(family_code, otherlang)
if not in_family then
local parent_code
if lang.getParent then
local parent_family = lang:getParent()
if parent_family and parent_family.getCode then
parent_code = parent_family:getCode()
end
end
if not parent_code and family_code:find("-", 1, true) then
parent_code = family_code:match("^(.+)-[^-]+$")
end
if parent_code then
in_family = in_family_code(parent_code, otherlang)
end
end
if not in_family then
local other_display = (otherlang.getCanonicalName and otherlang:getCanonicalName()) or (otherlang.getCode and otherlang:getCode()) or tostring(otherlang)
local fam_display = (lang.getCanonicalName and lang:getCanonicalName()) or family_code
error(("%s bukan dalam keluarga %s; leluhur diwarisi di bawah keluarga mestilah bahasa dalam keluarga tersebut atau keluarga induknya.")
:format(other_display, fam_display))
end
return
end
-- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up
-- the module link code appropriately (June 2024) but the remaining logic is untouched.
if lang:hasAncestor(otherlang) then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/variety]]
-- Track inheritance from varieties of Latin that shouldn't have any descendants (everything except Old Latin, Classical Latin and Vulgar Latin).
if otherlang:getFullCode() == "la" then
otherlang = otherlang:getCode()
if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then
track("bad ancestor", otherlang)
end
end
return
end
local ancestors = lang:getAncestors()
local postscript
local etym_module_link = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or ""
local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]"
if not ancestors[1] then
postscript = show_language(lang) .. " tidak mempunyai leluhur."
else
local ancestor_list = {}
for _, ancestor in ipairs(ancestors) do
insert(ancestor_list, show_language(ancestor))
end
postscript = ("Leluhur bahasa%s kepada %s %s %s."):format(
"", lang:getCanonicalName(),
"adalah", concat(ancestor_list, " dan "))
end
error(("%s tidak ditetapkan sebagai leluhur kepada %s dalam %s%s. %s")
:format(show_language(otherlang), show_language(lang), etym_module_link, module_link, postscript))
end
end
-- Internal implementation of {{inherited}}/{{inh}} template.
function export.format_inherited(data)
local lang, terms, nocat = data.lang, data.terms, data.nocat
local source = terms[1].lang
local categories = {}
if not nocat then
insert(categories, "Perkataan bahasa " .. lang:getFullName() .. " diwariskan daripada bahasa " .. source:getCanonicalName())
end
export.check_ancestor(lang, source)
data = shallow_copy(data)
data.categories = categories
data.source = source
return export.format_links(terms, data.conj, "inherited", export.format_source(data))
end
-- Internal implementation of "misc variant" templates such as {{abbrev}}, {{clipping}}, {{reduplication}} and the like.
function export.format_misc_variant(data)
local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {}
if not notext then
insert(parts, data.text)
end
if terms[1] then
if not notext then
-- FIXME: If term is given as '-', we should consider displaying just "Clipping" not "Clipping of".
insert(parts, " " .. (data.oftext or "bagi"))
end
local termparts = {}
-- Make links out of all the parts.
for _, termobj in ipairs(terms) do
local result
if termobj.lang then
result = export.format_derived {
lang = lang,
terms = {termobj},
sources = termobj.termlangs or {termobj.lang},
template_name = "misc_variant",
decorations_on_outside = true,
force_cat = data.force_cat,
}
else
termobj.lang = lang
result = export.format_links({termobj}, nil, "misc_variant")
end
table.insert(termparts, result)
end
local linktext = join_segs(termparts, data.conj)
if not notext and linktext ~= "" then
insert(parts, " ")
end
insert(parts, linktext)
end
local categories = {}
if not data.nocat and cats then
for _, cat in ipairs(cats) do
insert(categories, cat .. " bahasa " .. lang:getFullName())
end
end
if categories[1] then
insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
end
return concat(parts)
end
-- Implementation of miscellaneous templates such as {{unknown}} and {{onomatopoeia}} that have no associated terms.
function export.format_misc_variant_no_term(data)
local parts = {}
if not data.notext then
insert(parts, data.title)
end
if not data.nocat and data.cat then
local lang, categories = data.lang, {}
insert(categories, data.cat .. " bahasa " .. lang:getFullName())
insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
end
return concat(parts)
end
return export
d7dsyjuf79uzc4ggl1vuvxjx0mtfbxn
a la mode
0
11800
375912
245967
2026-09-26T07:46:43Z
Hakimi97
2668
/* Etimologi */ Betulkan templat
375912
wikitext
text/x-wiki
{{also|alamode|à la mode|ala mode}}
==Bahasa Inggeris==
[[File:Pie A La Mode.JPG|thumb|right|Pai à la mode]]
===Bentuk alternatif===
* {{l|en|à la mode}}
* {{l|en|alamode}}
===Etimologi===
Daripada {{ety|en|:ubor|fr:à la mode<t:in fashion>|text=+|tree=1}} Pengertian AS dicipta oleh pemilik restoran [[poliglot|bertutur pelbagai bahasa]] John Gieriet di [[Minnesota]] pada tahun 1800-an walaupun kemudian dikaitkan dengan Berry Hall dan Charles Watson Townsend.
===Adjektif===
{{en-adj}}
# mengikut fesyen; dalam gaya [[fesyen]] [[terkini]].
# {{lb|en|US}} Dihidang bersama [[ais krim]].
#: ''Pai '''a la mode''' kami mempunyai satu sudu ais krim vanila di atas.''
#* '''November 1959''', "Martin Bunn", [[w:Popular Science|Popular Science]], ''[http://gus-stories.org/november_1959.htm Gus Pulls a Switch]'':
#*: Dengan semangkuk rebus daging lembu, pai epal '''a la mode''', dan dua cawan kopi di bawah sabuknya, Gus Wilson berjalan santai kembali ke Model Garage.
====Sinonim====
* {{sense|fashionable}} {{l|en|cool}}, {{l|en|trendy}}, {{l|en|classy}}
===Kata keterangan===
{{en-adv}}
# Dalam [[gaya]] atau [[fesyen]] tertentu.
cqz28jqn9sgfjdmxcw3p70p7l4wol5p
376181
375912
2026-09-26T09:24:26Z
Hakimi97
2668
Pembetulan
376181
wikitext
text/x-wiki
{{also|alamode|à la mode|ala mode}}
==Bahasa Inggeris==
[[File:Pie A La Mode.JPG|thumb|right|Pai à la mode]]
===Bentuk alternatif===
* {{l|en|à la mode}}
* {{l|en|alamode}}
===Etimologi===
{{ety|en|:ubor|fr:à la mode<t:in fashion>|text=+|tree=1}} Pengertian AS dicipta oleh pemilik restoran [[poliglot|bertutur pelbagai bahasa]] John Gieriet di [[Minnesota]] pada tahun 1800-an walaupun kemudian dikaitkan dengan Berry Hall dan Charles Watson Townsend.
===Adjektif===
{{en-adj}}
# mengikut fesyen; dalam gaya [[fesyen]] [[terkini]].
# {{lb|en|US}} Dihidang bersama [[ais krim]].
#: ''Pai '''a la mode''' kami mempunyai satu sudu ais krim vanila di atas.''
#* '''November 1959''', "Martin Bunn", [[w:Popular Science|Popular Science]], ''[http://gus-stories.org/november_1959.htm Gus Pulls a Switch]'':
#*: Dengan semangkuk rebus daging lembu, pai epal '''a la mode''', dan dua cawan kopi di bawah sabuknya, Gus Wilson berjalan santai kembali ke Model Garage.
====Sinonim====
* {{sense|fashionable}} {{l|en|cool}}, {{l|en|trendy}}, {{l|en|classy}}
===Kata keterangan===
{{en-adv}}
# Dalam [[gaya]] atau [[fesyen]] tertentu.
0arj2ck21vcgbo8id7zvuq3vywkjavp
Modul:category tree/topic/Places
828
12236
375875
344228
2026-09-25T12:51:10Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/91688982|91688982]])
375875
Scribunto
text/plain
local labels = {}
local handlers = {}
local m_table = require("Module:table")
local en_utilities_module = "Module:en-utilities"
local string_utilities_module = "Module:string utilities"
local m_locations = require("Module:place/locations")
local m_placetypes = require("Module:place/placetypes")
local placetype_data = m_placetypes.placetype_data
local internal_error = m_locations.internal_error
local dump = mw.dumpObject
local insert = table.insert
local concat = table.concat
local is_callable = require("Module:fun").is_callable
--[==[ intro:
This module is part of the category tree code and contains code to generate the descriptions of place-related categories
such as [[Category:de:Hokkaido Prefecture, Japan]], [[Category:es:Cities in France]],
[[Category:pt:Municipalities of Tocantins, Brazil]], etc.). Note that this module doesn't actually create the
categories; that must be done separately, with the text "{{tl|auto cat}}" as the definition of the category. (This
process should automatically happen periodically for non-empty categories, because they will appear in
[[Special:WantedCategories]] and a bot will periodically examine that list and create any needed category.)
There are two ways that category descriptions are specified: (1) by manually adding an entry to the `labels` table,
keyed by the label (the category minus the language code) with a value consisting of a Lua table specifying the
description text and the category's parents; (2) through handlers (pieces of Lua code) added to the `handlers` list,
which recognize labels of a specific type (e.g. `Cities in France`) and generate the appropriate specification for that
label on-the-fly.
See [[Module:place]] for an introduction to the terminology associated with places along with a list of all the relevant
modules, along with for more specific information on types of toponyms and placetypes and how their categorization
works.
]==]
local function lcfirst(label)
return mw.getContentLanguage():lcfirst(label)
end
local function gsub_literally(str, from, to)
local m_strutils = require(string_utilities_module)
return (str:gsub(m_strutils.pattern_escape(from), m_strutils.replacement_escape(to)))
end
local class_to_bare_category_parent = {
["tatanegara"] = "tatanegara",
["subtatanegara"] = "pembahagian politik",
["petempatan"] = "petempatan",
["non-admin settlement"] = "petempatan",
["capital"] = "ibu kota",
["sifat semula jadi"] = "sifat semula jadi",
["man-made structure"] = "man-made structures",
["kawasan geografi"] = "kawasan geografi dan budaya",
}
local class_is_political_division = {
["tatanegara"] = true, -- strictly false but there are placetypes ambiguous between polity and subpolity
["subtatanegara"] = true,
["petempatan"] = true,
["non-admin settlement"] = false,
["capital"] = true,
["sifat semula jadi"] = false,
["man-made structure"] = false,
["kawasan geografi"] = false,
["tempat am"] = false,
}
local capital_cat_to_placetype = {}
for placetype, capital_cat in pairs(m_placetypes.placetype_to_capital_cat) do
capital_cat_to_placetype[capital_cat] = placetype
end
-- Handler for bare categories for all types of capitals. This needs to precede the handler for bare placetype
-- categories as some of the types of capitals exist as placetypes as well.
insert(handlers, function(label)
label = lcfirst(label)
local capital_placetype = capital_cat_to_placetype[label]
if capital_placetype then
local pl_placetype = m_placetypes.pluralize_placetype(capital_placetype)
local linkdesc = m_placetypes.get_placetype_display_form(pl_placetype, "top-level")
if linkdesc == nil then
internal_error("Unrecognized placetype %s when processing label %s", capital_placetype, label)
end
if linkdesc == false then
mw.log(("Display form for pl_placetype %s is false, can't categorize"):format(dump(pl_placetype)))
return nil
end
return {
type = "nama",
topic = label,
description = "{{{langname}}} names of [[capital]]s of " .. linkdesc .. ".",
parents = {"ibu kota"},
}
end
end)
-- Handler for bare placetype categories. FIXME: Add wpcat= and commonscat= info. Previously we had it for various
-- so-called "generic" placetypes, but sometimes the categories were wrong.
insert(handlers, function(label)
for _, canon_label in ipairs { lcfirst(label), label } do
local ptdesc, ptdata = m_placetypes.get_placetype_display_form(canon_label, "top-level", "return full")
if ptdesc then
local from_category_props = {
from_category = true,
no_split_qualifiers = true,
}
local bare_category_parent = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt)
local bare_category_parent = m_placetypes.get_placetype_prop(pt, "bare_category_parent")
if bare_category_parent then
return bare_category_parent
end
local class = m_placetypes.get_placetype_prop(pt, "class")
if class then
if class_to_bare_category_parent[class] == nil then
internal_error("Saw unknown category class %s derived from placetype %s",
class, canon_label)
end
return class_to_bare_category_parent[class]
end
end, from_category_props)
if not bare_category_parent then
internal_error("Saw placetype %s without a `class` or `bare_category_parent` setting, either " ..
"directly or through a fallback", canon_label)
end
local addl_bare_category_parents = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt)
return m_placetypes.get_placetype_prop(pt, "addl_bare_category_parents")
end, from_category_props)
local bare_category_breadcrumb = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt)
return m_placetypes.get_placetype_prop(pt, "bare_category_breadcrumb")
end, from_category_props)
if type(bare_category_parent) == "string" and bare_category_breadcrumb then
bare_category_parent = {name = bare_category_parent, sort = bare_category_breadcrumb}
end
local parents = {bare_category_parent}
if addl_bare_category_parents then
m_table.extend(parents, addl_bare_category_parents)
end
return {
type = "nama",
topic = canon_label,
description = "{{{langname}}} " .. ptdesc .. ".",
breadcrumb = bare_category_breadcrumb,
parents = parents,
}
elseif ptdesc == false then
mw.log(("Display form for canon_label %s is false, can't categorize"):format(dump(canon_label)))
end
end
end)
local function fetch_primary_placetype(key, spec)
local placetype = spec.placetype
if type(placetype) == "table" then
placetype = placetype[1]
end
if not placetype then
internal_error("No placetype specified or defaulted for key %s, spec %s", key, spec)
end
return placetype
end
--[==[
Construct an appropriately linked location based on the full or elliptical placename, preceded by `"the "`` if
appropriate. Specifically:
Fetch the full and elliptical_placenames. If they are the same, just link to the placename directly. Otherwise, check if
the full placename exists; if so link to it. Otherwise, if the elliptical placename exists, link to it but display it as
the full placename. Finally, if neither full placename nor elliptical placename exists, fall back to linking to the full
placename. That way, we prefer full placenames to elliptical placenames if both or neither exist as Wiktionary entries,
but if only one exists, we link to that one rather than have a red link.
]==]
local function construct_linked_location(group, key, spec)
local full_placename, elliptical_placename = m_locations.key_to_placename(group, key)
local linked_placename
if elliptical_placename ~= full_placename then
local full_placename_title = mw.title.new(full_placename)
if full_placename_title and full_placename_title.exists then
linked_placename = m_locations.construct_linked_placename(spec, full_placename)
else
local elliptical_placename_title = mw.title.new(elliptical_placename)
if elliptical_placename_title and elliptical_placename_title.exists then
linked_placename = m_locations.construct_linked_placename(spec, elliptical_placename, full_placename)
end
end
end
return linked_placename or m_locations.construct_linked_placename(spec, full_placename)
end
--[==[
Construct the description of a location, including its container trail either to the end or until we encounter a
`no_include_container_in_desc` setting. For example, for the city of [[Birmingham]], the description will read
`"[[Birmingham]], a [[city]] in the [[West Midlands]] (which is a [[county]] of [[England]], which is a
[[constituent country]] of the [[United Kingdom]], which is a [[country]] in [[Europe]])"`. FIXME: Possibly we should
adopt the way city descriptions used to read, which was similar to `"the city of [[Birmingham]], in the county of the
[[West Midlands]], in the [[constituent country]] of [[England]], in the [[country]] of the [[United Kingdom]], in
[[Europe]]"`.
]==]
local function construct_location_desc(group, key, spec)
local parts = {}
local function ins(txt)
insert(parts, txt)
end
ins(construct_linked_location(group, key, spec))
local iteration = 0
local need_closing_paren = false
local containers = {{group = group, key = key, spec = spec}}
local container_iterator = m_locations.iterate_containers(group, key, spec)
while true do
iteration = iteration + 1
local include_container_in_desc = false
for _, container in ipairs(containers) do
if not container.spec.no_include_container_in_desc then
include_container_in_desc = true
break
end
end
if not include_container_in_desc then
break
end
local next_containers = container_iterator()
if not next_containers then
break
end
local is_former = nil
for _, container in ipairs(containers) do
local this_is_former = container.spec.is_former_place
if is_former == nil then
is_former = this_is_former
elseif is_former ~= this_is_former then
internal_error("When processing container trail of key %s, found a mixture of former and non-former " ..
"containers: %s", key, containers)
end
end
if #containers > 1 then
local placetypes = {}
local prepositions = {}
for _, container in ipairs(containers) do
local container_type = fetch_primary_placetype(container.key, container.spec)
m_table.insertIfNot(placetypes, m_placetypes.pluralize_placetype(container_type))
m_table.insertIfNot(prepositions, m_placetypes.get_placetype_entry_preposition(container_type))
end
if iteration == 1 then
ins(", ")
elseif iteration == 2 then
ins(" (yakni ")
need_closing_paren = true
else
ins(", yakni ")
end
if is_former then
ins("former ")
end
ins(m_table.serialCommaJoin(placetypes))
ins(" ")
ins(concat(prepositions, "/"))
else
if iteration == 1 then
ins(", ")
elseif iteration == 2 then
ins(" (yakni ")
need_closing_paren = true
else
ins(", yakni ")
end
local container_type = fetch_primary_placetype(containers[1].key, containers[1].spec)
if is_former then
ins("sebelum ini merupakan sebuah ")
else
ins(m_placetypes.get_placetype_article(container_type))
ins(" ")
end
ins(container_type)
ins(" ")
ins(m_placetypes.get_placetype_entry_preposition(container_type))
end
ins(" ")
first_container = false
containers = next_containers
local container_locations = {}
for _, container in ipairs(containers) do
insert(container_locations, construct_linked_location(container.group, container.key,
container.spec))
end
ins(m_table.serialCommaJoin(container_locations))
end
if need_closing_paren then
ins(")")
end
return concat(parts)
end
-- Fetch or construct the description of the location specified by `key`. If the `keydesc` property is specified,
-- use it directly but substitute any occurrence of `+++` with the auto-constructed location description, which
-- mentions the placename corresponding to the key, its placetype and container, and repeats the description up
-- the container trail until either there are no more containers or (more usually) the `no_include_container_in_desc`
-- setting is found (which is set on all continents and continent-level regions).
local function fetch_or_construct_location_desc(group, key, spec)
local val = spec.keydesc
if is_callable(val) then
val = val(group, key, spec)
spec.keydesc = val
end
val = val or "+++"
if val:find("%+%+%+") then
val = gsub_literally(val, "+++", construct_location_desc(group, key, spec))
end
return val
end
local function normalize_cat_as(cat_as, div)
if type(cat_as) ~= "table" or cat_as.type then
cat_as = {cat_as}
end
local ret_cat_as = {}
for _, pt_cat_as in ipairs(cat_as) do
if type(pt_cat_as) == "string" then
pt_cat_as = {type = pt_cat_as}
end
insert(ret_cat_as, {type = pt_cat_as.type, prep = pt_cat_as.prep or div.prep or "bagi"})
end
return ret_cat_as
end
-- Find the specified plural placetype among the divs for a given known location. Return a list of cat_as specs, where
-- each spec is of the form {type = "PLURAL_PLACETYPE", prep = "PREP"} indicating the plural placetype to use when
-- categorizing and the preposition to follow.
local function find_placetype_cat_as(divs, pl_placetype)
if divs then
if type(divs) ~= "table" then
divs = {divs}
end
for _, div in ipairs(divs) do
if type(div) == "string" then
div = {type = div}
end
if div.type == pl_placetype then
local cat_as = div.cat_as or div.type
return normalize_cat_as(cat_as, div)
end
end
end
return nil
end
-- Handler for bare placename categories for known locations in `locations` in [[Module:place/locations]].
insert(handlers, function(label)
for _, canon_label in ipairs { label, lcfirst(label) } do
local group, spec = m_locations.find_canonical_key(canon_label)
if group then
-- wp= defaults to true (Wikipedia article matches location's full placename)
local wp = spec.wp
if wp == nil then
wp = true
end
-- wpcat= defaults to wp= (if Wikipedia article has its own name, Wikipedia category and Commons category
-- generally follow)
local wpcat = spec.wpcat
if wpcat == nil then
wpcat = wp
end
-- commonscat= defaults to wpcat= (if Wikipedia category has its own name, Commons category generally
-- follows)
local commonscat = spec.commonscat
if commonscat == nil then
commonscat = wpcat
end
local parents = {}
local bare_label_parents = spec.overriding_bare_label_parents
local container_iterator = m_locations.iterate_containers(group, canon_label, spec)
local containers = container_iterator()
if not bare_label_parents then
bare_label_parents = {"+++"}
end
local full_location_placename, elliptical_location_placename = m_locations.key_to_placename(group, canon_label)
local full_container_placename
if containers then
full_container_placename, _ = m_locations.key_to_placename(containers[1].group, containers[1].key)
end
local inserted_containers = false
for _, parent in ipairs(bare_label_parents) do
if parent == "+++" then
parent = "PL_PLACETYPE PREP CONTAINER"
end
if parent:find("CONTAINER") then
if not containers then
internal_error("Parent category %s needs the container of %s but no containers specified: %s",
parent, canon_label, spec)
end
local location_type = fetch_primary_placetype(canon_label, spec)
local pl_location_type = m_placetypes.pluralize_placetype(location_type)
for _, container in ipairs(containers) do
local per_container_parent = parent
local cat_as_list
if per_container_parent:find("PL_PLACETYPE") then
if spec.bare_category_parent_type then
cat_as_list = normalize_cat_as(spec.bare_category_parent_type, spec)
else
cat_as_list = find_placetype_cat_as(container.spec.divs, pl_location_type) or
find_placetype_cat_as(container.spec.addl_divs, pl_location_type)
end
end
if not cat_as_list then
local canon_placetype, ptdata, ptmatch = m_placetypes.get_placetype_data(location_type, "from category")
if not canon_placetype or not (ptdata.generic_before_non_cities or ptdata.generic_before_cities) then
internal_error("Unable to locate plural location type %s among the divs or addl_divs " ..
"for container key %s spec %s, and the location type is either not in placetype_data or " ..
"not identified as a generic placetype", pl_location_type, container.key, container.spec)
end
cat_as_list = {{type = pl_location_type, prep =
m_placetypes.get_placetype_entry_preposition(location_type)}}
end
local prefixed_key = m_placetypes.get_prefixed_key(container.key, container.spec)
per_container_parent = gsub_literally(per_container_parent, "CONTAINER", prefixed_key)
for _, cat_as in ipairs(cat_as_list) do
local per_container_per_placetype_parent = per_container_parent
per_container_per_placetype_parent = gsub_literally(per_container_per_placetype_parent, "PL_PLACETYPE",
cat_as.type)
per_container_per_placetype_parent = gsub_literally(per_container_per_placetype_parent, "PREP",
cat_as.prep)
m_table.insertIfNot(parents, per_container_per_placetype_parent)
end
end
inserted_containers = true
else
m_table.insertIfNot(parents, parent)
end
end
if not inserted_containers and containers then
-- If we didn't insert the containers above in some form, insert them now as bare categories. Note that
-- this may be different categories from the container categories inserted above.
for _, container in ipairs(containers) do
m_table.insertIfNot(parents, container.key)
end
end
if spec.addl_parents then
for _, parent in ipairs(spec.addl_parents) do
m_table.insertIfNot(parents, parent)
end
end
local function format_boxval(val, specname)
if val == true then
val = "%l"
end
if type(val) == "string" then
val = gsub_literally(val, "%l", full_location_placename)
val = gsub_literally(val, "%e", elliptical_location_placename)
if val:find("%%c") then
if not full_container_placename then
internal_error("Wikipedia/Commons spec %s = %s has %%c in it but key %s has no " ..
"containers: %s", specname, val, canon_label, spec)
end
val = gsub_literally(val, "%c", full_container_placename)
end
end
return val
end
local description = spec.fulldesc or (
"Istilah bahasa {{{langname}}} berkaitan dengan penduduk, budaya atau wilayah bagi " ..
fetch_or_construct_location_desc(group, canon_label, spec) .. ".")
local full_placename, _ = m_locations.key_to_placename(group, canon_label)
return {
type = "topic",
description = description,
breadcrumb = full_placename,
parents = parents,
wp = format_boxval(wp, "wp"),
wpcat = format_boxval(wpcat, "wpcat"),
commonscat = format_boxval(commonscat, "commonscat"),
}
end
end
end)
local function find_canonical_key_from_place(place, canon_label)
local has_the = false
local key
if place:find("^the ") then
key = place:gsub("^the ", "")
has_the = true
else
key = place
end
local group, spec = m_locations.find_canonical_key(key)
if group then
local requires_the = spec.the or false
if has_the ~= requires_the then
if has_the then
mw.log(("Mismatch in category name '%s', has 'the' in the category when it should not"):format(
canon_label))
else
mw.log(("Mismatch in category name '%s', should have 'the' in the category but does not"):
format(canon_label))
end
return nil
end
return group, key, spec
end
return nil
end
-- Handler for generic placetypes (those whose categories are added through category generation handlers or through
-- explicit category specs in the placetype data) for known locations in [[Module:place/locations]]. All such
-- placetypes have either a `generic_before_non_cities` setting (meaning they can occur before non-city locations) or
-- `generic_before_cities` setting (meaning they can occur before cities), or both. Examples of such categories are
-- "cities in the Bahamas" or "rivers in Western Australia, Australia", or (for city locations)
-- "neighbourhoods of Hong Kong" or "places in Melbourne".
insert(handlers, function(label)
for _, canon_label in ipairs { lcfirst(label), label } do
local placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (di) (.*)$")
if not placetype then
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (bagi) (.*)$")
end
if not placetype then
-- Legacy English category names; normalize to the Malay relation below.
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (in) (.*)$")
end
if not placetype then
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (of) (.*)$")
end
if in_of == "in" then
in_of = "di"
elseif in_of == "of" then
in_of = "bagi"
end
if placetype then
local normalized_placetype = placetype == "neighbourhoods" and "neighborhoods" or placetype
local canon_placetype, ptdata, ptmatch = m_placetypes.get_placetype_data(normalized_placetype, "from category")
if canon_placetype and (ptdata.generic_before_non_cities or ptdata.generic_before_cities) then
local group, key, spec = find_canonical_key_from_place(place, canon_label)
if group then
-- Check whether the location uses British spelling, but also check all containers, because
-- it's too hard to keep in sync the `british_spelling` setting for locations at all different
-- levels (e.g. cities of various countries, first and second level administrative division, etc.),
-- so we just set it at top level on the country.
local uses_british_spelling = spec.british_spelling
if uses_british_spelling == nil then
for containers in m_locations.iterate_containers(group, key, spec) do
local must_outer_break = false
for _, container in ipairs(containers) do
if container.spec.british_spelling ~= nil then
uses_british_spelling = container.spec.british_spelling
must_outer_break = true
break
end
end
if must_outer_break then
break
end
end
end
local allow_cat = true
if placetype == "neighborhoods" and uses_british_spelling or
placetype == "neighbourhoods" and not uses_british_spelling then
mw.log(("Mismatch in spelling of placetype '%s' in category '%s', should be '%s'"):format(
placetype, canon_label, uses_british_spelling and "neighbourhoods" or "neighborhoods"))
allow_cat = false
end
if spec.is_former_place and placetype ~= "tempat" then
allow_cat = false
end
local expected_prep
if spec.is_city then
expected_prep = ptdata.generic_before_cities
else
expected_prep = ptdata.generic_before_non_cities
end
if not expected_prep then
allow_cat = false
end
if allow_cat then
if expected_prep ~= in_of then
mw.log(("Mismatch in category name '%s', has '%s' when it should have '%s'"):format(
canon_label, in_of, expected_prep))
return nil
end
local linkdesc = m_placetypes.get_placetype_display_form(placetype,
spec.is_city and "bandar" or "noncity", "return full")
if linkdesc == false then
mw.log(("Display form for placetype %s is false, can't categorize"):format(dump(placetype)))
return nil
end
if not linkdesc then
internal_error("Unrecognized placetype %s when processing key %s, data %s, label %s",
placetype, key, spec, canon_label)
end
desc = linkdesc .. " " .. in_of .. " " .. fetch_or_construct_location_desc(group, key, spec)
desc = "{{{langname}}} " .. desc .. "."
local parents = {}
insert(parents, key)
if spec.no_container_parent then
-- top-level country, constituent country, continent or the like
insert(parents, {name = normalized_placetype, sort = key})
if spec.placetype == "negara" or m_table.contains(spec.placetype, "negara") then
local category_class = m_placetypes.get_equiv_placetype_prop(normalized_placetype,
function(pt) return m_placetypes.get_placetype_prop(pt, "class") end, {
from_category = true,
no_split_qualifiers = true,
})
if not category_class then
internal_error("Saw placetype %s that is either unknown or has no `class` " ..
"setting in `placetype_data`", normalized_placetype)
end
if class_is_political_division[category_class] == nil then
internal_error("Saw unknown category class %s derived from placetype %s",
category_class, normalized_placetype)
end
if class_is_political_division[category_class] then
insert(parents, "pembahagian politik negara tertentu")
end
end
else
local container_iterator = m_locations.iterate_containers(group, key, spec)
local next_containers = container_iterator()
if next_containers then
for _, container in ipairs(next_containers) do
local container_prep
if container.spec.is_city then
container_prep = ptdata.generic_before_cities
else
container_prep = ptdata.generic_before_non_cities
end
if not container_prep then
internal_error("For container key %s spec %s defines is_city = %s but " ..
"there is no corresponding `generic_before_*` setting in the " ..
"placedata for placetype %s", container.key, container.spec,
container.spec.is_city, placetype)
end
insert(parents, {
name = placetype .. " " .. container_prep .. " " .. m_placetypes.get_prefixed_key(
container.key, container.spec),
sort = key
})
end
else
-- unrecognized countries or the like
insert(parents, {name = normalized_placetype, sort = key})
end
end
return {
type = "nama",
topic = canon_label,
description = desc,
breadcrumb = placetype,
parents = parents,
}
end
end
end
end
end
end)
-- Handler for "state capitals of the United States", "provincial capitals of Canada", etc. This must precede the next
-- handler for specific political and misc (non-political) divisions of polities and subpolities, such as
-- "provinces of the Philippines", because "departmental capitals" is listed in cat_as for French prefectures and so
-- will trigger an error if that handler runs before this one.
insert(handlers, function(label)
label = lcfirst(label)
local capital_cat, place = label:match("^(.-) bagi (.*)$")
if not capital_cat then
-- Legacy English relation; generated descriptions/parents below remain canonical Malay.
capital_cat, place = label:match("^(.-) of (.*)$")
end
-- Make sure we recognize the type of capital.
if place and capital_cat_to_placetype[capital_cat] then
local placetype = capital_cat_to_placetype[capital_cat]
local pl_placetype = m_placetypes.pluralize_placetype(placetype)
-- Locate the container, fetch its known political divisions, and make sure the placetype corresponding to the
-- type of capital is among the list.
local group, key, spec = find_canonical_key_from_place(place, label)
if group and (spec.divs or spec.addl_divs) then
local saw_match = false
local variant_matches = {}
local divlists = {}
if spec.divs then
insert(divlists, spec.divs)
end
if spec.addl_divs then
insert(divlists, spec.addl_divs)
end
for _, divlist in ipairs(divlists) do
if type(divlist) ~= "table" then
divlist = {divlist}
end
for _, div in ipairs(divlist) do
if type(div) == "string" then
div = {type = div}
end
-- HACK. Currently if we don't find a match for the placetype, we map e.g. 'autonomous region'
-- -> 'regional capitals' and 'union territory' -> 'territorial capitals'. When encountering a
-- political division like 'autonomous region' or 'union territory', chop off everything up
-- through a space to make things match. To make this clearer, we record all such
-- "variant match" cases, and down below we insert a note into the category text indicating that
-- such "variant matches" are included among the category.
if pl_placetype == div.type or pl_placetype == div.type:gsub("^.* ", "") then
saw_match = true
if pl_placetype ~= div.type then
insert(variant_matches, div.type)
end
end
end
end
if saw_match then
-- Everything checks out, construct the category description.
local placetype_desc = m_placetypes.get_placetype_display_form(pl_placetype,
spec.is_city and "bandar" or "noncity")
if placetype_desc == false then
mw.log(("Display form for pl_placetype %s is false, can't categorize"):format(dump(pl_placetype)))
return nil
end
if not placetype_desc then
internal_error("Unrecognized plural placetype %s, generated as the plural of %s, which " ..
"was found as the placetype of capital placetype %s in label %s", pl_placetype,
placetype, capital_cat, label)
end
local variant_match_text = ""
if variant_matches[1] then
local real_variant_match_descs = {}
for i, variant_match in ipairs(variant_matches) do
local variant_match_desc = m_placetypes.get_placetype_display_form(variant_match,
spec.is_city and "bandar" or "noncity")
if variant_match_desc == nil then
internal_error("Unrecognized variant match plural placetype %s, coming from " ..
"place key %s, data %s in label %s", variant_match, key, spec, label)
end
if variant_match_desc then
-- skip those for which the description is `false`, like `ABBREVIATION_OF states`
-- in the United States divs.
insert(real_variant_match_descs, variant_match_desc)
end
end
if real_variant_match_descs[1] then
variant_match_text = " (including " .. m_table.serialCommaJoin(real_variant_match_descs)
.. ")"
end
end
local desc = "{{{langname}}} names of [[capital]]s of " .. placetype_desc .. variant_match_text ..
" bagi " .. fetch_or_construct_location_desc(group, key, spec) .. "."
local full_placename, _ = m_locations.key_to_placename(group, key)
local parents = {}
if spec.no_container_parent then
-- top-level country, constituent country, continent or the like
insert(parents, {name = capital_cat, sort = key})
else
local container_iterator = m_locations.iterate_containers(group, key, spec)
local next_containers = container_iterator()
if next_containers then
for _, container in ipairs(next_containers) do
insert(parents, {
name = capital_cat .. " bagi " .. m_placetypes.get_prefixed_key(
container.key, container.spec),
sort = key
})
end
else
-- unrecognized countries or the like
insert(parents, {name = capital_cat, sort = key})
end
end
insert(parents, key)
return {
type = "nama",
topic = label,
description = desc,
breadcrumb = full_placename,
parents = parents,
}
end
end
end
end)
local overriding_category_descriptions = {
["autonomous cities of Spain"] = "the [[w:Autonomous communities of Spain#Autonomous_cities|autonomous cities of Spain]]",
["regions of Greece"] = "the regions ([[periphery|peripheries]]) of [[Greece]]",
["regions of North Macedonia"] = "the regions ([[periphery|peripheries]]) of [[North Macedonia]]",
["subprefectures of Japan"] = "[[subprefecture]]s of [[Japan]]ese [[prefecture]]s",
}
-- Handler for specific political and misc (non-political) divisions of locations (polities, subpolities, cities, etc.),
-- such as "provinces of the Philippines", "counties of Wales", "municipalities of Tocantins, Brazil",
-- "boroughs of New York City", etc. This does not handle categories for generic placetypes (cities, rivers, etc.) of
-- locations, which are handled by different handlers above.
insert(handlers, function(label)
-- The label comes with an initial capitalization but we have to check both lowercase-initial and capital-initial
-- versions of the placetype to handle e.g. [[:Category:en:Indian reserves of Canada]].
for _, canon_label in ipairs { label, lcfirst(label) } do
for _, minimal_placetype in ipairs { true, false } do
local match_quantifier = minimal_placetype and "-" or "+"
-- Some categories have two "bagi"s in them, and depending on the category, it's correct to do either a greedy
-- ([[:Category:en:Abbreviations of states of the United States]], with placetype `abbreviations of states`)
-- or non-greedy ([[:Category:en:Provinces of the Democratic Republic of the Congo]], with placetype
-- `provinces`) match. We can't know in advance which is correct so we try both possibilities, doing the
-- non-greedy one first as it seems more common (there are many locations with "bagi" in them, but currently
-- only `abbreviations of states` occurs with a following location).
local placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (bagi) (.*)$")
if not placetype then
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (di) (.*)$")
end
if not placetype then
-- Legacy English category names; normalize to the Malay relation below.
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (of) (.*)$")
end
if not placetype then
placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (in) (.*)$")
end
if in_of == "in" then
in_of = "di"
elseif in_of == "of" then
in_of = "bagi"
end
if placetype then
local group, key, spec = find_canonical_key_from_place(place, canon_label)
if group then
local function find_placetype(divs)
if divs then
if type(divs) ~= "table" then
divs = {divs}
end
for _, div in ipairs(divs) do
if type(div) == "string" then
div = {type = div}
end
local cat_as = div.cat_as or div.type
if type(cat_as) ~= "table" then
cat_as = {cat_as}
end
for _, pt_cat_as in ipairs(cat_as) do
if type(pt_cat_as) == "string" then
pt_cat_as = {type = pt_cat_as}
end
if placetype == pt_cat_as.type then
local div_parent = pt_cat_as.container_parent_type
if div_parent == nil then -- allow false
div_parent = div.container_parent_type
end
if div_parent == nil then
div_parent = placetype
end
return div_parent, pt_cat_as.prep or div.prep or "bagi"
end
end
end
end
return nil
end
local div_parent, div_prep = find_placetype(spec.divs)
if div_parent == nil then -- allow false
div_parent, div_prep = find_placetype(spec.addl_divs)
end
if div_parent == nil then -- allow false
div_parent, div_prep = find_placetype(spec.addl_divs_for_categorization)
end
if div_parent ~= nil then
if div_prep ~= in_of then
mw.log(("Mismatch in category name '%s', has '%s' when it should have '%s'"):format(
canon_label, in_of, div_prep))
return nil
end
local linkdesc = m_placetypes.get_placetype_display_form(placetype, spec.is_city and "bandar" or "noncity",
"return full")
if linkdesc == false then
mw.log(("Display form for placetype %s is false, can't categorize"):format(dump(placetype)))
return nil
end
if not linkdesc then
internal_error("Unrecognized placetype %s when processing key %s, data %s, label %s",
placetype, key, spec, canon_label)
end
local desc = overriding_category_descriptions[canon_label]
if not desc then
desc = linkdesc .. " " .. in_of .. " " .. fetch_or_construct_location_desc(group, key, spec)
end
desc = "{{{langname}}} " .. desc .. "."
local parents = {}
insert(parents, key)
if div_parent then -- div_parent may be `false`
if spec.no_container_parent then
-- top-level country, constituent country, continent or the like
insert(parents, {name = placetype, sort = " " .. key})
if spec.placetype == "negara" or m_table.contains(spec.placetype, "negara") then
insert(parents, "Pembahagian politik negara tertentu")
end
else
local container_iterator = m_locations.iterate_containers(group, key, spec)
local next_containers = container_iterator()
if next_containers then
for _, container in ipairs(next_containers) do
insert(parents, {
name = div_parent .. " " .. in_of .. " " .. m_placetypes.get_prefixed_key(
container.key, container.spec),
sort = key
})
end
else
-- unrecognized countries or the like
insert(parents, {name = placetype, sort = " " .. key})
end
end
end
return {
type = "nama",
topic = canon_label,
description = desc,
breadcrumb = placetype,
parents = parents,
}
end
end
end
end
end
end)
labels["eksonim"] = {
type = "nama",
-- special-cased description
description = "{{{langname}}} [[exonym]]s.",
parents = {"Tempat"},
}
labels["Pembahagian politik negara tertentu"] = {
type = "kumpulan",
description = "{{{langname}}} categories for political divisions of specific countries.",
parents = {"Tempat"},
}
-- Misc. FIXME: Remove the need for this.
labels["nomes of Ancient Egypt"] = {
type = "nama",
-- special-cased description
description = "{{{langname}}} names of the [[nome]]s of [[Ancient Egypt]].",
breadcrumb = "nomes",
parents = {"Ancient Egypt"},
}
-- FIXME: Everything here has been moved from [[Module:category tree/topic/Earth]]. Most should be removed.
labels["Atlantic Ocean"] = {
type = "berkenaan",
description = "default with the",
parents = {"Bumi"},
}
labels["British Isles"] = {
type = "berkenaan",
description = "=the people, culture, or territory of [[Great Britain]], [[Ireland]], and other nearby islands",
parents = {"Eropah", "pulau"},
}
labels["European Union"] = {
type = "berkenaan",
description = "default with the",
parents = {"Eropah"},
}
labels["Gascony"] = {
type = "berkenaan",
parents = {"Occitania, France"},
}
labels["Indian subcontinent"] = {
type = "berkenaan",
description = "default with the",
parents = {"Asia Selatan"},
}
labels["Bengal"] = {
type = "berkenaan",
description = "{{{langname}}} terms related to the people, culture, or territory of [[Bengal]].",
parents = {"Indian subcontinent"},
}
labels["Kashmir"] = {
type = "berkenaan",
description = "{{{langname}}} terms related to the people, culture, or territory of [[Kashmir]].",
parents = {"Indian subcontinent"},
}
labels["Kashmir, India"] = {
type = "berkenaan",
description = "{{{langname}}} names of places in {{w|Kashmir, India}}.",
parents = {"India", "Kashmir"},
}
labels["Korea"] = {
type = "berkenaan",
description = "=the people, culture, or territory of [[Korea]]",
parents = {"Asia"},
}
labels["Languedoc"] = {
type = "berkenaan",
parents = {"Occitania, France"},
}
labels["Lapland"] = {
type = "berkenaan",
description = "=[[Lapland]], a region in northernmost Europe",
parents = {"Eropah", "Finland", "Norway", "Russia", "Sweden"},
}
labels["Timur Tengah"] = {
type = "berkenaan",
description = "default with the",
parents = {"Afrika", "Asia"},
}
labels["Netherlands Antilles"] = {
type = "berkenaan",
description = "=the people, culture, or territory of the [[Netherlands Antilles]]",
parents = {"Belanda", "Amerika Utara"},
}
labels["Provence"] = {
type = "berkenaan",
parents = {"Provence-Alpes-Côte d'Azur, France"},
}
labels["Polish People's Republic"] = {
type = "berkenaan",
parents = {"Poland"},
}
labels["Asia Selatan"] = {
type = "berkenaan",
parents = {"Eurasia", "Asia"},
}
return {LABELS = labels, HANDLERS = handlers}
3bld2en4qpvn3bp75woa4xpzvqiwgwr
Modul:etymology/style.css
828
13154
375896
111387
2026-09-26T06:14:34Z
Hakimi97
2668
Pembetulan dari segi penyetempatan kod
375896
sanitized-css
text/css
.desc-arr[title] { cursor: help }
.desc-arr[title="tidak pasti"] { font-size:.7em; vertical-align: super }
1zpyrujayjg5s0lxtzqnatno379rut9
جگہ
0
13672
375881
285973
2026-09-25T13:05:35Z
Hakimi97
2668
/* Kata nama */ Baiki
375881
wikitext
text/x-wiki
==Bahasa Urdu==
===Kata nama===
{{ur-noun|f|head=جَگَہْ,جَگَہ|hi=जगह}}
# [[tempat]], [[lokasi]]
5gnwutwli6msqlww7j3s6c1ruf0b2m0
Pengguna:Syed Muhammad Al Hafiz
2
14207
376206
114263
2026-09-26T09:45:10Z
Syed Muhammad Al Hafiz
4466
1895900900: blanked page for privacy reasons
376206
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
hanja
0
14313
375916
266385
2026-09-26T07:52:59Z
Hakimi97
2668
Pembetulan
375916
wikitext
text/x-wiki
{{also|Hanja}}
==Bahasa Inggeris==
{{wp}}
===Bentuk alternatif===
* {{l|en|Hanja}}
===Etimologi===
Dipinjam dari {{bor|en|ko|한자(漢字)}}, daripada {{der|en|ltc|-}} {{ltc-l|漢字|[[aksara bahasa Cina]]|lit=Bahasa Cina Han + aksara}}.
Banding {{cog|yue|漢字|tr=hon<sup>3</sup> zi<sup>6</sup>}}, {{cog|ja|漢字|tr=kanji}}, {{cog|cmn|漢字|tr=hànzì}}, {{cog|vi|Hán tự}}. {{doublet|en|kanji|Hanzi}}.
===Sebutan===
* {{IPA|en|/ˈhɑn.d͡ʒə/|/ˈhɑn.d͡ʒɑ/|a=US}}
* {{audio|en|LL-Q1860 (eng)-Vealhurl-hanja.wav|a=Southern England}}
===Kata nama===
{{en-noun|*}}
# Aksara Skrip [[Han]] dahulunya digunakan untuk menulis bahasa Korea, terutamanya dalam literasi klasikal. <!-- note that current academic writing often contains large quantities of hanja, it is hardly out of use! -->
# Setiap aksara Han yang digunakan dalam bahasa Korea.
====Perkataan berkaitan====
* {{l|en|hanjaeo}}
* {{l|en|hanmun}}
* {{l|en|hanzi}}
* {{l|en|kanji}}
* {{l|vi|Hán tự}}
====Terjemahan====
{{trans-top|Aksara Han yang digunakan untuk menulis Bahasa Korea}}
* Chinese:
*: Mandarin: {{t+|cmn|漢字}}
* Finnish: {{t|fi|hanja}}
* German: {{t+|de|Hanja|n}}
* Hungarian: {{t+|hu|handzsa}}
* Korean: {{t+|ko|한자(漢字)}}
* Polish: {{t+|pl|hanja|f}}
* Romanian: {{t|ro|hanja|?}}
* Russian: {{t|ru|ханча́|f}}
* Turkish: {{t|tr|hanca}}, {{t|tr|hanja}}
* Urdu: {{t|ur|ہانجا|tr=hānjā}}
{{trans-bottom}}
===Anagram===
* {{anagrams|en|a=aahjn|Jahan}}
{{C|en|Bahasa Korea|Sistem tulisan}}
{{cln|en|Perkataan bahasa Inggeris dengan tiada kewajiban huruf besar}}
l03hcnmp13rpswmlx2sx1ajd52muvzn
375924
375916
2026-09-26T08:01:16Z
Hakimi97
2668
/* Anagram */ pembetulan
375924
wikitext
text/x-wiki
{{also|Hanja}}
==Bahasa Inggeris==
{{wp}}
===Bentuk alternatif===
* {{l|en|Hanja}}
===Etimologi===
Dipinjam dari {{bor|en|ko|한자(漢字)}}, daripada {{der|en|ltc|-}} {{ltc-l|漢字|[[aksara bahasa Cina]]|lit=Bahasa Cina Han + aksara}}.
Banding {{cog|yue|漢字|tr=hon<sup>3</sup> zi<sup>6</sup>}}, {{cog|ja|漢字|tr=kanji}}, {{cog|cmn|漢字|tr=hànzì}}, {{cog|vi|Hán tự}}. {{doublet|en|kanji|Hanzi}}.
===Sebutan===
* {{IPA|en|/ˈhɑn.d͡ʒə/|/ˈhɑn.d͡ʒɑ/|a=US}}
* {{audio|en|LL-Q1860 (eng)-Vealhurl-hanja.wav|a=Southern England}}
===Kata nama===
{{en-noun|*}}
# Aksara Skrip [[Han]] dahulunya digunakan untuk menulis bahasa Korea, terutamanya dalam literasi klasikal. <!-- note that current academic writing often contains large quantities of hanja, it is hardly out of use! -->
# Setiap aksara Han yang digunakan dalam bahasa Korea.
====Perkataan berkaitan====
* {{l|en|hanjaeo}}
* {{l|en|hanmun}}
* {{l|en|hanzi}}
* {{l|en|kanji}}
* {{l|vi|Hán tự}}
====Terjemahan====
{{trans-top|Aksara Han yang digunakan untuk menulis Bahasa Korea}}
* Chinese:
*: Mandarin: {{t+|cmn|漢字}}
* Finnish: {{t|fi|hanja}}
* German: {{t+|de|Hanja|n}}
* Hungarian: {{t+|hu|handzsa}}
* Korean: {{t+|ko|한자(漢字)}}
* Polish: {{t+|pl|hanja|f}}
* Romanian: {{t|ro|hanja|?}}
* Russian: {{t|ru|ханча́|f}}
* Turkish: {{t|tr|hanca}}, {{t|tr|hanja}}
* Urdu: {{t|ur|ہانجا|tr=hānjā}}
{{trans-bottom}}
===Anagram===
* {{anagrams|en|a=aahjn|Jahan}}
{{C|en|Bahasa Korea|Sistem tulisan}}
{{cln|en|Perkataan dengan tiada kewajiban huruf besar}}
2zd6pieo6glorsk05vjfn0sg25pqew2
poi
0
15262
376009
315071
2026-09-26T08:34:32Z
Robiyatuladawiyah05
11514
/* Kata kerja */
376009
wikitext
text/x-wiki
==Bahasa Jepun==
===Perumian===
{{ja-romaji}}
# {{ja-romanization of|ぽい}}
# {{ja-romanization of|ポイ}}
==Bahasa Melayu Negeri Sembilan==
===Kata kerja===
{{inti|zmi|kata kerja}}
# [[pergi]]
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} Poi <!--Pergi-->
#: {{cp|ms|poi mano?.|pergi kemana?.}}
===Sebutan===
*{{IPA|zmi|/po.i/}}
*{{penyempangan|zmi|po|i}}
==Bahasa Semai==
===Kata kerja===
{{inti|sea|kata kerja}}
# angin bertiup
#: {{cp|sea|poi ajeh kuat.|angin bertiup sangat kencang.}}
n8wuohl5nwqfd4cq7zwri0iu59rhjvj
Wikikamus:Senarai tulisan
4
16186
375870
227407
2026-09-25T12:43:14Z
Hakimi97
2668
Senarai keluarga > Senarai keluarga bahasa
375870
wikitext
text/x-wiki
{{shortcut|WT:SCLIST|WT:LOS}}
{{main|Wiktionary:Tulisan}}
Laman ini menyenaraikan semua kod tulisan yang dikenal pasti oleh Wikikamus. Kandungan laman ini dihasilkan secara langsung dari [[Modul:scripts/data]], dan sebarang perubahan yang tersimpan pada modul tersebut akan disegerakkan secara langsung pada laman ini.
Untuk mencari kod tulisan dengan laju, tambah kod pada ruang pautan anda sebagai pautan bahagian. Contohnya, [[Wikikamus:Senarai tulisan#Latn]] akan bersambung terus ke tulisan Rumi/Latin.
Lihat juga [[Wikikamus:Senarai bahasa]] dan [[Wikikamus:Senarai keluarga bahasa]].
Jika anda menggunakan bot atau alat automasi yang memerlukan akses data Wikikamus, sila lihat [[Modul:JSON data]].
==Semua tulisan==
{{#invoke:list of scripts|show|with_stats=1}}
[[Category:Senarai tulisan]]
1kl56jjy75aopa7iz60janddgmj9x0q
abieu
0
16795
376205
332551
2026-09-26T09:43:52Z
Hakimi97
2668
ms > beg
376205
wikitext
text/x-wiki
==Bahasa Belait==
[[Fail:Campfire scar 08319.JPG|thumb|abieu]]
===Kata nama===
{{head|beg|kata nama}}
# [[abu]].
===Etimologi===
Daripada {{inh|beg|poz-pro|*(q)abu(s)}}, daripada {{inh|beg|map-pro|*qabu}}.
===Sebutan===
* {{AFA|beg|/a.biɛǔ/}}
* {{rima|beg|iɛǔ}}
* {{penyempangan|beg|a|bieu}}
===Rujukan===
* {{R:DL7D|2=1}}
[[Kategori:beg:Kelabu]]
j4rgdof887gpft1x2y9qi8j9bd18uqa
lai
0
19210
376081
310928
2026-09-26T08:52:23Z
Robiyatuladawiyah05
11514
/* Kata nama */
376081
wikitext
text/x-wiki
{{Kategori WikiKata 2021}}
==Bahasa Melayu==
{{wikipedia}}
===Kata nama===
{{ms-kn|j=لاي}}
# Buah jambu
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} Lari <!--Lari-->
#: {{cp|ms|dio poi lai.|dia pergi lari.}}
===Etimologi===
Daripada {{bor|ms|nan-hbl|梨|tr=lâi}}
===Sebutan===
{{ms-IPA}}
* {{rhymes|ms|ai̯}}
===Pautan luar===
* {{R:PRPM}}
==Bahasa Bugis==
===Kata kerja===
{{inti|bug|kata kerja}}
# {{lb|bug|Bone}} [[makan]]
==Bahasa Iban==
[[Fail:Pyrus pyrifolia fruit on tree PS 2z LR.jpg|thumb]]
===Kata nama===
{{inti|iba|kata nama}}
# sejenis buah, pir (Chinese pear)
#: {{cp|iba|Bala sida ke nembiak nya rindu makai buah '''lai'''. |Para budak sangat suka makan buah '''pir'''. }}
==Bahasa Melanau Daro-Matu==
===Kata nama===
{{inti|dro|kata nama}}
# [[lelaki]]
#: {{ux|dro|'''Lai''' dun panai.|'''Lelaki''' itu pandai.}}
===Sebutan===
* {{AFA|dro|/lai/}}
===Etimologi===
Daripada {{der|iba|nan-hbl|梨|tr=lâi}}.
{{:wt:meo/{{FULLPAGENAME}}}}
==Bahasa Semai==
===Kata kerja===
{{inti|sea|kata kerja}}
# bentang
#: {{cp|sea|Mok kilai ceruk.|Mak cik saya tengah bentang tikar.}}
ak6eg6qxtli63q7kxuhmqu0j4575jvw
talam
0
20712
376099
306651
2026-09-26T08:57:23Z
SY Reski
10853
376099
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata nama===
{{ms-kn|j=تالم}}
# Suatu [[dulang]] tak berkaki sebagai tempat menghantar dan menyaji [[makanan]] dan [[minuman]].
===Etimologi===
{{bor|ms|ta|தளம்}}.
===Sebutan===
* {{dewan|ta|lam}}
===Rujukan===
* {{R:KD4}}
===Pautan luar===
* {{R:PRPM}}
==Bahasa Kadazandusun==
===Kata nama===
{{inti|dtp|kata nama}}
# [[dulang]]
===Sebutan===
* {{IPA|dtp|/ta.lam/}}
* {{rima|dtp|lam|am}}
* {{penyempangan|dtp|ta|lam}}
===Kata terbitan===
* {{l|dtp|kitalam}}
===Rujukan===
#{{R:Komoiboros DusunKadazan|2=245}}
==Bahasa Melayu==
===Kata benda===
{{lb|ms|Kata benda}}
#{{lb|ms|Kampar}} talam <!--nampan->
#:{{cp|ms|ambiokkan gole di talam du dih.|tolong ambilkan gelas di nampan itu.}}
4ro2h6vh1zty3k2yie8kdl6n7omhljb
kolam
0
21113
376209
338393
2026-09-26T09:47:32Z
SY Reski
10853
376209
wikitext
text/x-wiki
==Bahasa Melayu==
===Takrifan 1===
[[Fail:Pool.jpg|thumb|Kolam (takrifan 1).]]
====Kata nama====
{{ms-kn|j=کولم}}
# Suatu lubang atau bekas yang diisi [[air]].
====Etimologi====
Pinjaman {{bor|ms|ta|குளம்}}.
===Takrifan 2===
[[Fail:Color in authoor.jpg|thumb|Kolam (takrifan 2).]]
====Kata nama====
{{ms-kn|j=کولم}}
# Suatu bentuk seni visual berasal daripada budaya India yang diperbuat daripada [[serbuk]] atau bijian berwarna.
====Etimologi====
Pinjaman {{bor|ms|ta|கோலம்}}.
===Sebutan===
* {{dewan|ko|lam}}
===Rujukan===
* {{R:KD4}}
===Pautan luar===
* {{R:PRPM}}
{{C|ms|Cecair}}
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|Kata Sifat}}
#{{lb|ms|Kampar}} gelap <!--kolam-->
#:{{cp|ms|kolam le yuang.| gelap sekali nak }}
hg9qg70686mf854rgb4wvjonmpiksmm
dapu
0
23086
375979
217073
2026-09-26T08:25:21Z
Muhammad Abdi Ramadhan
9873
/* Kata nama */
375979
wikitext
text/x-wiki
== Bahasa Kapampangan ==
{{Wikipedia|lang=pam}}
=== Takrifan ===
==== Kata nama ====
{{head|pam|kata nama}}
# [[buaya]]
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} dapur <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu di dapu?.|orang itu di dapur?.}}
=== Sebutan ===
* {{penyempangan|pam|da|pu}}
[[File:LL-Q5317225 (dtp)-Meqqal-dapu'.wav|thumb|LL-Q5317225 (dtp)-Meqqal-dapu']]
{{C|pam|Reptilia}}
hjzebcm3nxc2ph2s1ko9uew8r70nfje
papan nada
0
24686
376207
339640
2026-09-26T09:45:18Z
~2026-51423-28
11521
replaced piano picture
376207
wikitext
text/x-wiki
==Bahasa Melayu==
{{Wikipedia}} <!-- Kalau ada -->
[[Fail:Klaviatur-3-en-correct.svg|thumb|Papan nada.]]
===Kata nama===
{{ms-kn|j=ڤاڤن نادا}}
# Himpunan "[[butang]]" di sesetengah [[alat muzik]] (terutamanya [[piano]]) yang membunyikan suatu [[nada]] muzik apabila ditekan.
===Etimologi===
{{compound|ms|papan|nada}}
===Sebutan===
* {{dewan|pa|pan||na|da}}
===Pautan luar===
* {{R:PRPM}}
{{C|ms|Muzik}}
4i1lv21uveesk227v5mvazrcqf49apx
tuan
0
25464
376075
286522
2026-09-26T08:51:03Z
Robiyatuladawiyah05
11514
/* Kata nama */
376075
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata nama===
{{inti|dtp|kata nama}}
#[[uban]].
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} Kamu <!--Kamu-->
#: {{cp|ms|tuan nak mengapo?.|kamu mau ngapain?.}}
ev4lw34063sbo3r1khyaa63y0xrs163
suok
0
26346
376226
306470
2026-09-26T11:45:42Z
Thurama
11516
376226
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata nama===
{{inti|dtp|kata nama}}
# [[sudut]]
# [[teluk]]
# [[lurah]]
===Sebutan===
* {{IPA|dtp|/sʊ.ɔk/}}
* {{rima|dtp|ɔk}}
* {{penyempangan|dtp|su|wok}}
===Kata terbitan===
* {{l|dtp|suminuok}}
===Rujukan===
#{{R:Komoiboros DusunKadazan|2=227}}
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata benda}}
# {{lb|ms|bangkinang}} suap <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
6xyc31tqnujeoke1g81xo3d3zgm3h22
ontok
0
27036
376026
303014
2026-09-26T08:38:24Z
Robiyatuladawiyah05
11514
/* Kata sendi */
376026
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata sendi===
{{inti|dtp|kata sendi nama}}
# [[pada]]
#: {{ux|dtp|Moginum oku '''ontok''' tadau Kaamatan.
|Saya minum '''pada''' hari Kaamatan.}}
# [[ketika]]
# [[waktu]]
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} Ontok <!--Diam-->
#: {{cp|ms|ontok lah kau.|diam lah kamu.}}
===Sebutan===
* {{IPA|dtp|/ɔn.tɔk/}}
* {{penyempangan|dtp|on|tok}}
===Terbitan===
* {{l|dtp|antakan}}
* {{l|dtp|mongontok}}
* {{l|dtp|noontok}}
* {{l|dtp|kinaantakan}}
* {{l|dtp|nokoontok}}
===Rujukan===
* Komoiboros DusunKadazan, Mongulud Boros Dusun Kadazan (MBDK) 1994
==Bahasa Melayu Negeri Sembilan==
===Kata kerja===
{{inti|zmi|kata kerja}}
# diam<ref>{{cite web|url=https://www.hmetro.com.my/mutakhir/2020/04/568187/duduk-ontok-ontok-kek-ghumah|title='Duduk ontok-ontok kek ghumah'|author=Amran Yahya|date=18 April 2020|publisher=Harian Metro}}</ref>
#: {{cp|zmi|Duduk '''ontok-ontok''' kek ghumah, kito jago kito.|Duduk '''diam-diam''' di rumah, kita jaga kita.}}
===Rujukan===
gdhb0sa1tzglswt3gsl9zn8yw4k5u6t
Modul:utilities/templates
828
27239
375923
375701
2026-09-26T08:00:35Z
Hakimi97
2668
Sesuaikan format catlangname kepada tatabahasa Melayu (Kata nama bahasa Melayu) sambil mengekalkan fungsi huluan terkini
375923
Scribunto
text/plain
local export = {}
local debug_track_module = "Module:debug/track"
local parameters_module = "Module:parameters"
local utilities_module = "Module:utilities"
local utilities_format_categories_with_sort_keys_module = "Module:utilities/format_categories_with_sort_keys"
local concat = table.concat
local insert = table.insert
local require = require
local function format_categories(...)
format_categories = require(utilities_module).format_categories
return format_categories(...)
end
local function format_categories_with_sort_keys(...)
format_categories_with_sort_keys = require(utilities_format_categories_with_sort_keys_module)
return format_categories_with_sort_keys(...)
end
local function process_params(...)
process_params = require(parameters_module).process
return process_params(...)
end
local function track(...)
track = require(debug_track_module)
return track(...)
end
-- Used by {{catfix}}.
function export.catfix(frame)
local args = process_params(frame:getParent().args, {
[1] = {type = "language", required = true},
[2] = {alias_of = "sc"},
["sc"] = {type = "script"},
})
return require("Module:utilities").catfix(args[1], args.sc)
end
-- Used by {{categorize}}, {{catlangname}} and {{topics}}.
function export.categorize(frame)
local args = process_params(frame:getParent().args, {
[1] = {required = true, type = "language", default = "und", sublist = true},
[2] = {required = true, list = true, allow_holes = true},
sort = {list = true, separate_no_index = true, allow_holes = true},
force = {type = "boolean"},
})
local langs = args[1]
if not langs[1] then
return ""
end
local parts = {}
for _, lang in ipairs(langs) do
local full_langcode = lang:getFullCode()
if lang:getCode() ~= full_langcode then
track("Module:utilities/templates/categorize called with variant langcode")
end
local raw_cats, sort_keys, format = args[2], args.sort, frame.args["format"]
local default_sort = sort_keys.default
local prefix = format == "topic" and full_langcode .. ":" or ""
local suffix = format == "pos" and " bahasa " .. lang:getFullName() or ""
-- Put the categories in an array. If any have an individual sortkey, they
-- will need to be tables with the category and sort key for
-- [[Module:utilities/format_categories_with_sort_keys]]; otherwise, add
-- them as strings.
local cats, n, with_sort_keys = {}, 0, false
for i = 1, raw_cats.maxindex do
local cat = raw_cats[i]
if cat ~= nil then
if suffix ~= "" then
cat = cat:gsub("^%l", string.upper)
end
cat = prefix .. cat .. suffix
local sort_key = sort_keys[i]
if with_sort_keys then
cat = {category = cat, sort_key = sort_key}
-- If a sort key exists, reformat all previously-processed
-- categories into the table format.
elseif sort_key ~= nil then
with_sort_keys = true
for j = 1, n do
cats[j] = {category = cats[j]}
end
cat = {category = cat, sort_key = sort_key}
end
n = n + 1
cats[n] = cat
end
end
if with_sort_keys then
insert(parts, format_categories_with_sort_keys(cats, lang, default_sort, nil, args.force))
else
insert(parts, format_categories(cats, lang, default_sort, nil, args.force))
end
end
return concat(parts)
end
return export
9scntdgsqn5z727469096ro6d4ik4fz
Modul:etymology/specialized
828
27505
375897
335186
2026-09-26T06:14:38Z
Hakimi97
2668
Pembetulan dari segi penyetempatan kod
375897
Scribunto
text/plain
local export = {}
local m_str_utils = require("Module:string utilities")
local en_utilities_module = "Module:en-utilities"
local etymology_module = "Module:etymology"
local gsub = m_str_utils.gsub
local insert = table.insert
local pluralize = require(en_utilities_module).pluralize
local upper = m_str_utils.upper
-- This function handles all the messiness of different types of specialized borrowings. It should insert any
-- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display
-- before the source + term (or "" for no text).
local function get_specialized_borrowing_text_insert_cats(data)
local bortype, categories, lang, terms, source, nocap, nocat, senseid =
data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid
local function inscat(cat)
if not nocat then
local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw")
local sourcecat = sourcedisp:match("^bahasa%-bahasa ") and sourcedisp or "bahasa " .. sourcedisp
if cat:find("DISPLAY") then
cat = cat:gsub("DISPLAY", display)
elseif cat:find("SOURCE") then
cat = cat:gsub("SOURCE", sourcecat)
else
cat = cat .. " " .. sourcecat
end
insert(categories, "Perkataan bahasa " .. lang:getFullName() .. " " .. cat)
end
end
-- `text` is the display text for the borrowing type, which gets converted
-- into a link.
-- `appendix` is a the glossary anchor, which defaults to `text`
-- `prep` is the preposition between the borrowing type and the language
-- name (e.g. "of", "from")
-- `pos` is the part of speech for the borrowing type ("noun" or
-- "adjective"; defaults to "noun")
-- `plural` is the plural form of the borrowing type; if not specified,
-- the pluralize function is used
local text, appendix, prep, pos, plural
if bortype == "calque" then
text, prep = "pinjaman terjemah", "bagi"
inscat("dipinjam terjemah daripada")
elseif bortype == "partial-calque" then
text, prep = "pinjaman terjemah separa", "bagi"
inscat("dipinjam terjemah separa daripada")
elseif bortype == "semantic-loan" then
text, prep = "pinjaman semantik", "daripada"
inscat("dipinjam secara semantik daripada")
elseif bortype == "transliteration" then
text, prep = "transliterasi", "bagi"
inscat("dipinjam daripada")
inscat("transliterasi perkataan DISPLAY")
elseif bortype == "phono-semantic-matching" then
text, prep = "padanan fonosemantik", "bagi"
inscat("dengan padanan fonosemantik daripada")
else
local langcode = lang:getCode()
local lang_is_source = langcode == source:getCode()
if lang_is_source then
-- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived".
require("Module:debug/track"){
"etymology/specialized/self-as-source",
"etymology/specialized/self-as-source/" .. langcode
}
inscat("dipinjam balik ke dalam")
else
inscat("dipinjam daripada SOURCE")
if bortype ~= "borrowing" then
inscat("dengan " .. (bortype == "learned" and "pinjaman terpelajar" or bortype == "semi-learned" and "pinjaman terpelajar separa" or bortype == "orthographic" and "pinjaman ortografi" or bortype == "unadapted" and "pinjaman tidak tersuai" or bortype == "adapted" and "pinjaman tersuai" or bortype) .. " daripada SOURCE")
end
end
if bortype == "borrowing" then
text, appendix, prep, pos = "dipinjam", "kata pinjaman", "daripada", "adjective"
elseif (
bortype == "learned" or
bortype == "semi-learned" or
bortype == "orthographic" or
bortype == "unadapted"
) then
text, prep = (bortype == "learned" and "pinjaman terpelajar" or bortype == "semi-learned" and "pinjaman terpelajar separa" or bortype == "orthographic" and "pinjaman ortografi" or bortype == "unadapted" and "pinjaman tidak tersuai" or bortype == "adapted" and "pinjaman tersuai" or bortype), "daripada"
elseif bortype == "adapted" then
text, prep = (bortype == "learned" and "pinjaman terpelajar" or bortype == "semi-learned" and "pinjaman terpelajar separa" or bortype == "orthographic" and "pinjaman ortografi" or bortype == "unadapted" and "pinjaman tidak tersuai" or bortype == "adapted" and "pinjaman tersuai" or bortype), "daripada"
else
error("Internal error: Unrecognized bortype: " .. bortype)
end
end
-- If the term is suppressed, the preposition should always be "from":
-- "Calque of Chinese 中國".
-- "Calque from Chinese" (not "Calque of Chinese").
if terms[1].term == "-" then
prep = "daripada"
end
appendix = "Lampiran:Glosari#" .. (appendix or text)
if senseid then
local senseids, output = mw.text.split(senseid, '!!'), {}
for i, id in ipairs(senseids) do
-- FIXME: This should be done via a function.
insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}'))
end
local link
if senseid:find('!!') then
link, text = "merupakan", pos == "adjective" and text or plural or text
else
link = "merupakan"
end
text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]'
else
text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]"
end
return text .. " " .. prep .. " "
end
function export.specialized_borrowing(data)
local lang, sources, terms = data.lang, data.sources, data.terms
local categories = {}
local text
for _, source in ipairs(sources) do
text = get_specialized_borrowing_text_insert_cats {
bortype = data.bortype,
categories = categories,
lang = lang,
terms = terms,
source = source,
nocap = data.nocap,
nocat = data.nocat,
senseid = data.senseid,
}
end
text = data.notext and "" or text
local sourcetext = require(etymology_module).format_sources {
lang = lang,
sources = sources,
terms = terms,
sort_key = data.sort_key,
categories = categories,
nocat = data.nocat,
sourceconj = data.sourceconj,
}
return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext)
end
return export
j9z9ijqnh0amsvku6w4rfyluocoy00a
Modul:etymology/templates/descendant
828
27509
375895
375370
2026-09-26T06:14:32Z
Hakimi97
2668
Pembetulan dari segi penyetempatan kod
375895
Scribunto
text/plain
local export = {}
local debug_track_module = "Module:debug/track"
local decorations_module = "Module:decorations"
local descendants_tree_module = "Module:descendants tree"
local etymology_style_css = "Module:etymology/style.css"
local labels_module = "Module:labels"
local languages_module = "Module:languages"
local links_module = "Module:links"
local parameter_utilities_module = "Module:parameter utilities"
local scripts_module = "Module:scripts"
local table_module = "Module:table"
local table_module_list_to_set = "Module:table/listToSet"
local template_styles_module = "Module:TemplateStyles"
local concat = table.concat
local insert = table.insert
local list_to_set = require(table_module_list_to_set)
local error_on_no_descendants = false
local function track(page)
return require(debug_track_module)("descendant/" .. page)
end
local function ine(arg)
if arg == "" then
return nil
else
return arg
end
end
local function add_tooltip(text, tooltip)
return '<span class="desc-arr" title="' .. tooltip .. '">' .. text .. '</span>'
end
-- Boolean params indicating whether a descendant term (or all terms) are particular sorts of borrowings.
local bortypes = {"inh", "bor", "lbor", "slb", "obor", "translit", "der", "clq", "pclq", "sml", "unc"}
local bortype_set = list_to_set(bortypes)
-- Aliases of clq=.
local calque_aliases = {"cal", "calq", "calque"}
local calque_alias_set = list_to_set(calque_aliases)
-- Aliases of pclq=.
local partial_calque_aliases = {"pcal", "pcalq", "pcalque"}
local partial_calque_alias_set = list_to_set(partial_calque_aliases)
local semi_learned_borrowing_aliases = {"slbor"}
local semi_learned_borrowing_alias_set = list_to_set(semi_learned_borrowing_aliases)
--- Return a function of one argument `field` (a param name), which fetches `args`[`field`].default if index == 0, else
--- `container`[`field`].
local function get_val(container, args, index)
return function(field)
if index == 0 then
return args[field].default
else
return container[field]
end
end
end
local function get_arrow(container, args, index)
local val = get_val(container, args, index)
local arrow
if val("bor") then
arrow = add_tooltip("→", "pinjaman")
elseif val("lbor") then
arrow = add_tooltip("→", "pinjaman terpelajar")
elseif val("slb") then
arrow = add_tooltip("→", "pinjaman terpelajar separa")
elseif val("obor") then
arrow = add_tooltip("→", "pinjaman ortografi")
elseif val("translit") then
arrow = add_tooltip("→", "transliterasi")
elseif val("clq") then
arrow = add_tooltip("→", "pinjaman terjemahan")
elseif val("pclq") then
arrow = add_tooltip("→", "pinjaman terjemahan separa")
elseif val("sml") then
arrow = add_tooltip("→", "pinjaman semantik")
elseif val("inh") or (val("unc") and not val("der")) then
arrow = add_tooltip(">", "diwariskan")
else
arrow = ""
end
-- allow der=1 in conjunction with bor=1 to indicate e.g. English "pars recta"
-- derived and borrowed from Latin "pars".
if val("der") then
arrow = arrow .. add_tooltip("⇒", "dibentuk semula melalui analogi atau penambahan morfem")
end
if val("unc") then
arrow = arrow .. add_tooltip("?", "tidak pasti")
end
if arrow ~= "" then
arrow = arrow .. " "
end
return arrow
end
-- Return the pre-decoration text for the `index`th term, or the overall pre-decoration text if index == 0.
local function get_pre_decorations(container, args, index)
if index > 0 then
-- per term decorations are handled at the subitem level, by full_link().
return nil, nil
end
local val = get_val(container, args, index)
return val("l"), val("q")
end
-- Return the post-decoration text for the `index`th term, or the overall post-decoration text if index == 0.
local function get_post_decorations(container, args, index, lang)
local val = get_val(container, args, index)
local boolean_labels = {}
if val("inh") then
insert(boolean_labels, "diwariskan")
end
if val("lbor") then
insert(boolean_labels, "terpelajar")
end
if val("slb") then
insert(boolean_labels, "terpelajar separa")
end
if val("translit") then
insert(boolean_labels, "transliterasi")
end
if val("clq") then
insert(boolean_labels, "pinjaman terjemahan")
end
if val("pclq") then
insert(boolean_labels, "pinjaman terjemahan separa")
end
if val("sml") then
insert(boolean_labels, "pinjaman semantik")
end
if index > 0 then
-- per term decorations are handled at the subitem level, by full_link().
return boolean_labels
else
local quals, dash_labels
quals = val("qq")
if val("ll") then
local labels = require(labels_module).show_labels {
lang = lang,
labels = val("ll"),
nocat = true,
open = false,
close = false,
no_track_already_seen = true,
ok_to_destructively_modify = true, -- doesn't apply to `labels`
}
if labels ~= "" then
dash_labels = " — " .. labels
end
end
return boolean_labels, quals, dash_labels
end
end
local function desc_or_desc_tree(frame, desc_tree)
local params
local boolean = {type = "boolean"}
if desc_tree then
params = {
[1] = {required = true, type = "language", family = true, default = "gem-pro"},
[2] = {required = true, list = true, allow_holes = true, default = "*fuhsaz"},
notext = boolean,
noalts = boolean,
noparent = boolean,
}
else
params = {
[1] = {required = true, type = "language", family = true, default = "en"},
[2] = {list = true, allow_holes = true, template_default = "word"},
alts = boolean,
}
end
-- Add other single params.
params.sclang = boolean
params.sclb = {replaced_by = "sclang", reason = "untuk mengelakkan kekeliruan dengan 'labels' seperti dalam [[Template:lb]]"}
params.nolang = boolean
params.nolb = {replaced_by = "nolang", reason = "to avoid confusion with 'labels' as in [[Template:lb]]"}
local parent_args
if frame.args[1] then
parent_args = frame.args
else
parent_args = frame:getParent().args
end
-- Error to catch most uses of old-style parameters.
if ine(parent_args[4]) and not ine(parent_args[3]) and not ine(parent_args.tr2) and not ine(parent_args.ts2)
and not ine(parent_args.t2) and not ine(parent_args.gloss2) and not ine(parent_args.g2)
and not ine(parent_args.alt2) then
error("Anda menentukan istilah dalam 4= tetapi bukan dalam 3=. Anda mungkin bermaksud menggunakan t= untuk menentukan glos. "
.. "Jika anda bermaksud menentukan dua istilah, letakkan istilah kedua dalam 3=.")
end
if not ine(parent_args[3]) and not ine(parent_args.alt2) and not ine(parent_args.tr2) and not ine(parent_args.ts2)
and ine(parent_args.g2) then
error("Anda menentukan jantina dalam g2= tetapi tiada istilah dalam 3=. Anda mungkin cuba menentukan dua jantina bagi "
.. "satu istilah. Untuk berbuat demikian, letakkan kedua-dua jantina dalam g=, dipisahkan dengan koma.")
end
local m_param_utils = require(parameter_utilities_module)
local param_mods = m_param_utils.construct_param_mods {
{group = {"link", "ref", "l", "q"}},
{param = "lb", replaced_by = false, instead = "gunakan 'l' untuk label kiri atau 'll' untuk label kanan"},
{param = bortypes, type = "boolean", overall = true, separate_no_index = true},
{param = calque_aliases, alias_of = "clq"},
{param = partial_calque_aliases, alias_of = "pclq"},
{param = semi_learned_borrowing_aliases, alias_of = "slb"},
}
local groups, args, globalprops = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = parent_args,
termarg = 2,
-- Need some work to support this.
-- parse_lang_prefix = true,
track_module = "descendant",
-- Due to allowing families as langs and substituting 'und', it's easier to do this later.
-- lang = function() ... end
sc = "sc.default",
splitchar = "[,~]",
subitem_separator_map = {[","] = " / ", ["~"] = " ~ "},
pre_normalize_modifiers = function(data)
local modtext = data.modtext
modtext = modtext:match("^<(.*)>$")
if not modtext then
error(("Internal error: Passed-in modifier isn't surrounded by angle brackets: %s"):format(
data.modtext))
end
if bortype_set[modtext] or calque_alias_set[modtext] or partial_calque_alias_set[modtext] or semi_learned_borrowing_alias_set[modtext] then
modtext = modtext .. ":1"
end
return "<" .. modtext .. ">"
end,
}
local lang = args[1]
local namespace = mw.title.getCurrentTitle().nsText
if (namespace == "" or namespace == "Rekonstruksi") and (
lang:hasType("appendix-constructed") and not lang:hasType("regular")) then
error("Istilah dalam bahasa binaan lampiran-sahaja tidak boleh diberikan sebagai keturunan.")
end
local fetch_alt_forms = desc_tree and not args.noalts or not desc_tree and args.alts
local m_desctree
if desc_tree or fetch_alt_forms then
m_desctree = require(descendants_tree_module)
end
if lang:getCode() ~= lang:getFullCode() then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/etymological]]
track("etymological")
track("etymological/" .. lang:getCode())
end
local is_family = lang:hasType("family")
local proxy_lang
if is_family then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/family]]
track("family")
track("family/" .. lang:getCode())
proxy_lang = require(languages_module).getByCode("und")
else
proxy_lang = lang
end
local langname
if is_family then
-- The display form for families includes the word "languages", which we probably don't want to
-- display.
langname = lang:getCanonicalName()
else
langname = lang:getDisplayForm()
end
local langtag
if args.sclang then
local sc_to_use = args.sc.default
if not sc_to_use then
local first_termobj = groups[1] and groups[1].terms[1]
if not first_termobj then
error("sclang= diberikan tetapi tiada istilah untuk memaparkan nama tulisan")
end
sc_to_use = first_termobj.sc
if not sc_to_use then
local first_term = first_termobj.term or first_termobj.alt
if not first_term then
error("sclang= diberikan tetapi item pertama yang dinyatakan tiada istilah atau bentuk paparan untuk memaparkan nama tulisan")
end
if first_termobj.lang then
sc_to_use = first_termobj.lang:findBestScript(first_term)
elseif is_family then
sc_to_use = require(scripts_module).findBestScriptWithoutLang(first_term, "none is last resort")
else
sc_to_use = lang:findBestScript(first_term)
end
end
end
langtag = sc_to_use:getDisplayForm(lang)
else
langtag = langname
end
local terms_for_descendant_trees = {}
-- Keep track of descendants whose descendant tree we fetch. Don't fetch the same descendant tree twice (which
-- can happen especially with Arabic-script terms with the same unvocalized spelling but differing vocalization).
-- This happens e.g. with Ottoman Turkish [[پورتقال]], which has {{desctree|fa-cls|پُرْتُقَال|پُرْتِقَال|bor=1}}, with
-- two terms that have the same unvocalized spelling.
local terms_and_ids_fetched = {}
local descendant_terms_seen = {}
local parts = {}
for i, group in ipairs(groups) do
local group_parts = {}
local terms_for_alt_forms = {}
for _, item in ipairs(group.terms) do
local link = ""
item.lang = item.lang or proxy_lang
item.track_sc = true
-- Construct a link out of `item`. Also add the term to the list of descendant trees and/or alternative
-- forms to fetch, if the page+ID combination hasn't already been seen.
if item.term ~= "-" then -- including term == nil
link = require(links_module).full_link(item, nil, true)
if item.term and (desc_tree or fetch_alt_forms) then
local m_links = require(links_module)
-- Fetches information under entry. If term is of type A//B, it checks A.
local entry_name = m_links.get_link_page(m_links.remove_links(mw.ustring.gsub(item.term, "//.+$", "")), lang, item.sc)
-- NOTE: We use the term and ID as the key, but not the language. This is OK currently because
-- all terms have the same language; but if we ever add support for a term-specific language,
-- we need to fix this.
local term_and_id = item.id and entry_name .. "!!!" .. item.id or entry_name
if not terms_and_ids_fetched[term_and_id] then
terms_and_ids_fetched[term_and_id] = true
local term_for_fetching = {
lang = lang, entry_name = entry_name, id = item.id
}
if desc_tree then
if is_family then
error("Tiada sokongan pada masa ini (dan mungkin tidak akan ada) untuk mendapatkan pokok keturunan apabila kod keluarga diberikan sebagai ganti kod bahasa")
end
if error_on_no_descendants then
require(table_module).insertIfNot(descendant_terms_seen,
{ term = item.term, id = item.id })
end
table.insert(terms_for_descendant_trees, term_for_fetching)
end
if fetch_alt_forms then
if is_family then
error("Tiada sokongan pada masa ini (dan mungkin tidak akan ada) untuk mendapatkan bentuk alternatif apabila kod keluarga diberikan sebagai ganti kod bahasa")
end
-- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/alts]]
track("alts")
table.insert(terms_for_alt_forms, term_for_fetching)
end
end
end
elseif item.tr or item.ts or item.gloss or item.genders then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/no term]]
track("no term")
item.term = nil
item.show_decorations = true
link = require(links_module).full_link(item, nil, true)
link = link
:gsub("<small>%[Istilah%?%]</small> ", "")
:gsub("<small>%[Istilah%?%]</small> ", "")
:gsub("%[%[Category:[^%[%]]+ term requests%]%]", "")
:gsub("%[%[Kategori:Permintaan perkataan bahasa [^%[%]]+%]%]", "")
else -- display no link at all
-- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/no term or annotations]]
track("no term or annotations")
end
if link ~= "" then
insert(group_parts, item.separator)
insert(group_parts, link)
end
end
if group_parts[1] then
for _, altterm in ipairs(terms_for_alt_forms) do
local altform = m_desctree.get_alternative_forms(altterm.lang, altterm.entry_name, altterm.id,
globalprops.use_semicolon and "; " or ", ")
if altform ~= "" then
insert(group_parts, globalprops.use_semicolon and "; " or ", ")
insert(group_parts, altform)
end
end
local group_link = concat(group_parts)
insert(parts, group.separator)
if not args.notext then
insert(parts, get_arrow(group, args, i))
end
-- no pre-qualifiers/labels and no post-qualifiers/dash-labels
local post_boolean_labels = get_post_decorations(group, args, i, proxy_lang)
if post_boolean_labels and post_boolean_labels[1] then
group_link = require(decorations_module).format_decorations {
lang = proxy_lang,
text = group_link,
ll = post_boolean_labels,
}
end
insert(parts, group_link)
end
end
local descendant_trees = {}
for _, descterm in ipairs(terms_for_descendant_trees) do
-- When I ([[User:Benwing2]]) first implemented this in Nov 2020, I had `maxmaxindex > 1` as the last argument.
-- Since then, [[User:Fytcha]] changed the last param to `true`.
local descendant_tree = m_desctree.get_descendants(descterm.lang, descterm.entry_name, descterm.id, true)
if descendant_tree and descendant_tree ~= "" then
insert(descendant_trees, descendant_tree)
end
end
if error_on_no_descendants and desc_tree and not descendant_trees[1] then
local function format_term_seen(term_seen)
if term_seen.id then
return ("[[%s]] dengan ID '%s'"):format(term_seen.term, term_seen.id)
else
return ("[[%s]]"):format(term_seen.term)
end
end
if #descendant_terms_seen == 0 then
error("[[Template:desctree]] dipanggil tetapi tiada istilah untuk mendapatkan keturunan")
elseif #descendant_terms_seen == 1 then
error(("Tiada bahagian Keturunan ditemui dalam entri %s di bawah pengepala untuk %s"):format(
format_term_seen(descendant_terms_seen[1]), lang:getFullName()))
else
for i, term_seen in ipairs(descendant_terms_seen) do
descendant_terms_seen[i] = format_term_seen(term_seen)
end
error(("Tiada bahagian Keturunan ditemui dalam mana-mana entri %s di bawah pengepala untuk %s"):format(
concat(descendant_terms_seen, ", "), lang:getFullName()))
end
end
local descendants = concat(descendant_trees)
if args.noparent then
return descendants
end
local initial_labels, initial_quals = get_pre_decorations(nil, args, 0)
local final_boolean_labels, final_quals, final_dash_labels = get_post_decorations(nil, args, 0, proxy_lang)
local all_linktext = concat(parts)
if initial_labels and initial_labels[1] or initial_quals and initial_quals[1] or
final_boolean_labels and final_boolean_labels[1] or final_quals and final_quals[1] then
all_linktext = require(decorations_module).format_decorations {
lang = proxy_lang,
text = all_linktext,
l = initial_labels,
q = initial_quals,
ll = final_boolean_labels,
qq = final_quals,
}
end
if final_dash_labels then
all_linktext = all_linktext .. final_dash_labels
end
all_linktext = all_linktext .. descendants
if args.notext then
return all_linktext
end
local initial_arrow = get_arrow(nil, args, 0)
if args.nolang then
return initial_arrow .. all_linktext
else
return concat { initial_arrow, langtag, ":", all_linktext ~= "" and " " or "", all_linktext }
end
end
function export.descendant(frame)
return desc_or_desc_tree(frame, false) .. require(template_styles_module)(etymology_style_css)
end
function export.descendants_tree(frame)
return desc_or_desc_tree(frame, true)
end
return export
mv9td2dda7ozv92gtkgfw3srfc89mc6
lugut
0
29046
376182
286869
2026-09-26T09:24:48Z
Elvaretta Vito
11512
376182
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata nama===
{{inti|dtp|kata nama}}
# bambu (utk mengambil air)
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Lugut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Melugut tanganku keno miang buluh.|Gatal merinding tanganku terkena miang bambu.}}
crb6p7spfiqpylhswb60d91h2f53tlm
agas
0
29906
375978
295752
2026-09-26T08:25:17Z
Taufik Hadris
9879
375978
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata sifat===
{{inti|dtp|kata sifat}}
# [[nasi yang tidak berapa masak]].
#:{{ux|dtp|Au oku kopio ogorot makan tu '''agas''' po ilo takano.
|Saya tidak begitu berselera makan kerana nasi '''tidak berapa masak'''.}}
===Sebutan===
* {{penyempangan|dtp|a|gas}}
* {{IPA|dtp|/a.ɡas/}}
[[File:LL-Q5317225 (dtp)-Jjurieee-agas.wav|thumb|LL-Q5317225 (dtp)-Jjurieee-agas]]
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} agas; binatang atau serangga sejenis nyamuk kecil yg apabila menggigit terasa pedih dan gatal
ismditg6vrsyw0kap2s8fdoesydqgoq
gagau
0
30414
376137
286121
2026-09-26T09:07:25Z
Elvaretta Vito
11512
376137
wikitext
text/x-wiki
==Bahasa Iban==
===Kata sifat===
{{inti|iba|kata sifat}}
# sibuk
#: {{cp|iba|Iya benung '''gagau'''.|Dia sedang '''sibuk'''.}}
==Bahasa Bajau Sama==
===Kata kerja===
{{inti|bdr|kata kerja}}
# sibuk
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Gagau <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Lamo budak tu mengagau lokan di sungai.|Lama anak itu meraba-raba mencari kerang di sungai.}}
2itvo8g3qzowwr9ncgnjcu374kh7wpk
kikik
0
30872
375966
297866
2026-09-26T08:21:51Z
Muhammad Abdi Ramadhan
9873
/* Kata sifat */
375966
wikitext
text/x-wiki
==Bahasa Kadazandusun==
===Kata sifat===
{{inti|dtp|kata sifat}}
# [[berderek]].
#: {{ux|dtp|'''Kikik''' do koirak i ama.
|Ibu tertawa '''berderek'''.}}
# berderok.
# [[kekek]].
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} pelit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu kikik.|orang itu pelit?.}}
===Sebutan===
* {{IPA|dtp|/ki.kik/}}
* {{rima|dtp|ik}}
* {{penyempangan|dtp|ki|kik}}
===Kata terbitan===
* {{l|dtp|mongikik}}
===Rujukan===
* Komoiboros DusunKadazan, Mongulud Boros Dusun Kadazan (MBDK) 1994
7ce3m3ftob2r8t75xj8934lwb6wjebx
hajap
0
32245
376071
314315
2026-09-26T08:49:58Z
Robiyatuladawiyah05
11514
/* Kata sifat */
376071
wikitext
text/x-wiki
==Bahasa Semai==
===Kata sifat===
{{inti|sea|kata sifat}}
# [[miskin]]
#: {{cp|sea|Mai '''hajap''' hodloh hitulug ru ikhlas.|Orang '''miskin''' perlu dibantu dengan ikhlas.}}
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Susah <!--Susah-->
#: {{cp|ms|hajap lah tuan.|susah lah kamu.}}
czaygc4wag698a2zngttlehe4jkenr6
Modul:languages/data/exceptional
828
33718
376210
375620
2026-09-26T09:48:25Z
Hakimi97
2668
ms-Arab > Arab
376210
Scribunto
text/plain
local m_langdata = require("Module:languages/data")
-- Loaded on demand, as it may not be needed (depending on the data).
local function u(...)
u = require("Module:string utilities").char
return u(...)
end
local c = m_langdata.chars
local p = m_langdata.puaChars
local s = m_langdata.shared
local m = {}
m["aav-khs-pro"] = {
"Khasi Purba",
116773216,
"aav-khs",
"Latn",
type = "reconstructed",
}
m["aav-nic-pro"] = {
"Nicobar Purba",
116773793,
"aav-nic",
"Latn",
type = "reconstructed",
}
m["aav-pkl-pro"] = {
"Pnar-Khasi-Lyngngam Purba",
116773259,
"aav-pkl",
"Latn",
type = "reconstructed",
}
m["aav-pro"] = { -- mkh-pro will merge into this
"Austroasia Purba",
116773186,
"aav",
"Latn",
type = "reconstructed",
}
m["afa-pro"] = {
"Afroasia Purba",
269125,
"afa",
"Latn",
type = "reconstructed",
}
m["alg-aga"] = {
"Agawam",
nil,
"alg-eas",
"Latn",
}
m["alg-pro"] = {
"Algonquian Purba",
7251834,
"alg",
"Latn",
type = "reconstructed",
sort_key = {remove_diacritics = "·"},
}
m["alv-ama"] = {
"Amasi",
4740400,
"nic-grs",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron},
}
m["alv-bgu"] = {
"Bainouk Gubeeher",
17002646,
"alv-bny",
"Latn",
}
m["alv-bua-pro"] = {
"Bua Purba",
116773723,
"alv-bua",
"Latn",
type = "reconstructed",
}
m["alv-cng-pro"] = {
"Cangin Purba",
116773726,
"alv-cng",
"Latn",
type = "reconstructed",
}
m["alv-edo-pro"] = {
"Edoid Purba",
116773206,
"alv-edo",
"Latn",
type = "reconstructed",
}
m["alv-fli-pro"] = {
"Fali Purba",
116773754,
"alv-fli",
"Latn",
type = "reconstructed",
}
m["alv-gbe-pro"] = {
"Gbe Purba",
116773208,
"alv-gbe",
"Latn",
type = "reconstructed",
}
m["alv-gng-pro"] = {
"Guang Purba",
116773757,
"alv-gng",
"Latn",
type = "reconstructed",
}
m["alv-gtm-pro"] = {
"Togo Tengah Purba",
116773732,
"alv-gtm",
"Latn",
type = "reconstructed",
}
m["alv-gwa"] = {
"Gwara",
16945580,
"nic-pla",
"Latn",
}
m["alv-hei-pro"] = {
"Heiban Purba",
116773760,
"alv-hei",
"Latn",
type = "reconstructed",
}
m["alv-ido-pro"] = {
"Idomoid Purba",
116773764,
"alv-ido",
"Latn",
type = "reconstructed",
}
m["alv-igb-pro"] = {
"Igboid Purba",
116773765,
"alv-igb",
"Latn",
type = "reconstructed",
}
m["alv-kwa-pro"] = {
"Kwa Purba",
116773780,
"alv-kwa",
"Latn",
type = "reconstructed",
}
m["alv-mum-pro"] = {
"Mumuye Purba",
116773791,
"alv-mum",
"Latn",
type = "reconstructed",
}
m["alv-nup-pro"] = {
"Nupoid Purba",
116773795,
"alv-nup",
"Latn",
type = "reconstructed",
}
m["alv-pro"] = {
"Atlantik-Congo Purba",
116732838,
"alv",
"Latn",
type = "reconstructed",
}
m["alv-edk-pro"] = {
"Edekiri Purba",
nil,
"alv-edk",
"Latn",
type = "reconstructed",
}
m["alv-yor-pro"] = {
"Yoruba Purba",
nil,
"alv-yor",
"Latn",
type = "reconstructed",
}
m["alv-yrd-pro"] = {
"Yoruboid Purba",
116773824,
"alv-yrd",
"Latn",
type = "reconstructed",
}
m["alv-von-pro"] = {
"Volta-Niger Purba",
116773820,
"alv-von",
"Latn",
type = "reconstructed",
}
m["apa-pro"] = {
"Apache Purba",
116773135,
"apa",
"Latn",
type = "reconstructed",
}
m["aql-pro"] = {
"Algik Purba",
18389588,
"aql",
"Latn",
type = "reconstructed",
sort_key = {remove_diacritics = "·"},
}
m["art-adu"] = {
"Adûni",
1232159,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-bel"] = {
"Kreol Belter",
108055510,
"art",
"Latn",
type = "appendix-constructed",
sort_key = {
remove_diacritics = c.acute,
from = {"ɒ"},
to = {"a"},
},
}
m["art-blk"] = {
"Bolak",
2909283,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-bsp"] = {
"Bahasa Hitam",
686210,
"art",
"Latn, Teng",
type = "appendix-constructed",
}
m["art-com"] = {
"Communicationssprache",
35227,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-dtk"] = {
"Dothraki",
2914733,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-elo"] = {
"Eloi",
nil,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-gld"] = {
"Goa'uld",
19823,
"art",
"Latn, Egyp, Mero",
type = "appendix-constructed",
}
m["art-lap"] = {
"Lapine",
6488195,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-man"] = {
"Mandalorian",
54289,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-mun"] = {
"Mundolinco",
851355,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-nav"] = {
"Naʼvi",
316939,
"art",
"Latn",
type = "appendix-constructed",
}
m["art-vlh"] = {
"Valyria Tinggi",
64483808,
"art",
"Latn",
type = "appendix-constructed",
}
m["ath-nic"] = {
"Nicola",
20609,
"ath-nor",
"Latn",
}
m["ath-pro"] = {
"Athabaska Purba",
104841722,
"ath",
"Latn",
type = "reconstructed",
}
m["auf-pro"] = {
"Arawa Purba",
116773706,
"auf",
"Latn",
type = "reconstructed",
}
m["aus-alu"] = {
"Alungul",
16827670,
"aus-pmn",
"Latn",
}
m["aus-and"] = {
"Andjingith",
4754509,
"aus-pmn",
"Latn",
}
m["aus-ang"] = {
"Angkula",
16828520,
"aus-pmn",
"Latn",
}
m["aus-arn-pro"] = {
"Arnhem Purba",
116773720,
"aus-arn",
"Latn",
type = "reconstructed",
}
m["aus-bra"] = {
"Barranbinya",
4863220,
"aus-pmn",
"Latn",
}
m["aus-brm"] = {
"Barunggam",
4865914,
"aus-pmn",
"Latn",
}
m["aus-cww-pro"] = {
"New South Wales Tengah Purba",
116773199,
"aus-cww",
"Latn",
type = "reconstructed",
}
m["aus-dal-pro"] = {
"Daly Purba",
116773743,
"aus-dal",
"Latn",
type = "reconstructed",
}
m["aus-guw"] = {
"Guwar",
6652138,
"aus-pam",
"Latn",
}
m["aus-lsw"] = {
"Little Swanport",
6652138,
"qfa-unc",
"Latn",
}
m["aus-mbi"] = {
"Mbiywom",
6799701,
"aus-pmn",
"Latn",
}
m["aus-ngk"] = {
"Ngkoth",
7022405,
"aus-pmn",
"Latn",
}
m["aus-nyu-pro"] = {
"Nyulnyulan Purba",
116773797,
"aus-nyu",
"Latn",
type = "reconstructed",
}
m["aus-pam-pro"] = {
"Pama-Nyunga Purba",
33942,
"aus-pam",
"Latn",
type = "reconstructed",
}
m["aus-tul"] = {
"Tulua",
16938541,
"aus-pam",
"Latn",
}
m["aus-uwi"] = {
"Uwinymil",
7903995,
"aus-arn",
"Latn",
}
m["aus-wdj-pro"] = {
"Iwaidjan Purba",
116773767,
"aus-wdj",
"Latn",
type = "reconstructed",
}
m["aus-won"] = {
"Wong-gie",
nil,
"aus-pam",
"Latn",
}
m["aus-wul"] = {
"Wulguru",
8039196,
"aus-dyb",
"Latn",
}
m["aus-ynk"] = { -- contrast nny
"Yangkaal",
3913770,
"aus-tnk",
"Latn",
}
m["awd-amc-pro"] = {
"Amuesha-Chamicuro Purba",
nil,
"awd",
"Latn",
type = "reconstructed",
}
m["awd-kmp-pro"] = {
"Kampa Purba",
nil,
"awd",
"Latn",
type = "reconstructed",
}
m["awd-prw-pro"] = {
"Paresi-Waura Purba",
nil,
"awd",
"Latn",
type = "reconstructed",
}
m["awd-ama"] = {
"Amarizana",
16827787,
"awd",
"Latn",
}
m["awd-ana"] = {
"Anauyá",
16828252,
"awd",
"Latn",
}
m["awd-apo"] = {
"Apolista",
16916645,
"awd",
"Latn",
}
m["awd-cab"] = {
"Cabre",
16850160,
"awd",
"Latn",
}
m["awd-gnu"] = {
"Guinau",
3504087,
"awd",
"Latn",
}
m["awd-kar"] = {
"Cariay",
16920253,
"awd",
"Latn",
}
m["awd-kaw"] = {
"Kawishana",
6379993,
"awd-nwk",
"Latn",
}
m["awd-kus"] = {
"Kustenau",
5196293,
"awd",
"Latn",
}
m["awd-man"] = {
"Manao",
6746920,
"awd",
"Latn",
}
m["awd-mar"] = {
"Marawan",
6755108,
"awd",
"Latn",
}
m["awd-mpr"] = {
"Maipure",
6736872,
"awd",
"Latn",
}
m["awd-mrt"] = {
"Mariaté",
16910017,
"awd-nwk",
"Latn",
}
m["awd-nwk-pro"] = {
"Nawiki Purba",
116773234,
"awd-nwk",
"Latn",
type = "reconstructed",
}
m["awd-pai"] = {
"Paikoneka",
128807835,
"awd",
"Latn",
}
m["awd-pas"] = {
"Pasé",
7143168,
"awd-nwk",
"Latn",
}
m["awd-pro"] = {
"Arawak Purba",
97573478,
"awd",
"Latn",
type = "reconstructed",
}
m["awd-she"] = {
"Shebayo",
7492248,
"awd",
"Latn",
}
m["awd-taa-pro"] = {
"Ta-Arawak Purba",
116773282,
"awd-taa",
"Latn",
type = "reconstructed",
}
m["awd-wai"] = {
"Wainumá",
16910017,
"awd-nwk",
"Latn",
}
m["awd-war"] = {
"Warekena Kuno",
105320180,
"awd-nwk",
"Latn",
}
m["awd-yum"] = {
"Yumana",
8061062,
"awd-nwk",
"Latn",
}
m["azc-caz"] = {
"Cazcan",
5055514,
"azc",
"Latn",
}
m["azc-cup-pro"] = {
"Cupan Purba",
116773738,
"azc-cup",
"Latn",
type = "reconstructed",
}
m["azc-ktn"] = {
"Kitanemuk",
3197558,
"azc-tak",
"Latn",
}
m["azc-nah-pro"] = {
"Nahua Purba",
7251860,
"azc-nah",
"Latn",
type = "reconstructed",
}
m["azc-nic"] = {
"Nicoleño",
50241488,
"azc",
"Latn",
}
m["azc-num-pro"] = {
"Numik Purba",
116773247,
"azc-num",
"Latn",
type = "reconstructed",
}
m["azc-pro"] = {
"Uto-Aztek Purba",
96400333,
"azc",
"Latn",
type = "reconstructed",
}
m["azc-tak-pro"] = {
"Takik Purba",
116773283,
"azc-tak",
"Latn",
type = "reconstructed",
}
m["azc-tat"] = {
"Tataviam",
743736,
"azc",
"Latn",
}
m["ber-pro"] = {
"Berber Purba",
2855698,
"ber",
"Latn",
type = "reconstructed",
}
m["ber-fog"] = {
"Fogaha",
107610173,
"ber",
"Latn",
}
m["ber-zuw"] = {
"Zuwara",
4117169,
"ber",
"Latn",
}
m["bnt-bal"] = {
"Balong",
93935237,
"bnt-bbo",
"Latn",
}
m["bnt-bon"] = {
"Boma Nkuu",
nil,
"bnt",
"Latn",
}
m["bnt-boy"] = {
"Boma Yumu",
nil,
"bnt",
"Latn",
}
m["bnt-bwa"] = {
"Bwala",
128810345,
"bnt-tek",
"Latn",
}
m["bnt-cmw"] = {
"Chimwiini",
4958328,
"bnt-swh",
"Latn",
}
m["bnt-ind"] = {
"Indanga",
51412803,
"bnt",
"Latn",
}
m["bnt-lal"] = {
"Lala (Afrika Selatan)",
6480154,
"bnt-ngu",
"Latn",
}
m["bnt-mpi"] = {
"Mpiin",
93937013,
"bnt-bdz",
"Latn",
}
m["bnt-mpu"] = {
"Mpuono", -- not to be confused with Mbuun zmp
36056,
"bnt",
"Latn",
}
m["bnt-ngu-pro"] = {
"Nguni Purba",
961559,
"bnt-ngu",
"Latn",
type = "reconstructed",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.caron},
}
m["bnt-phu"] = {
"Phuthi",
33796,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute},
}
m["bnt-pro"] = {
"Bantu Purba",
3408025,
"bnt",
"Latn",
type = "reconstructed",
sort_key = "bnt-pro-sortkey",
}
m["bnt-sab-pro"] = {
"Sabaki Purba",
nil, -- Q2209395 is the code for the Sabaki family
"bnt-sab",
"Latn",
type = "reconstructed",
}
m["bnt-sbo"] = {
"Boma Selatan",
nil,
"bnt",
"Latn",
}
m["bnt-sts-pro"] = {
"Sotho-Tswana Purba",
116773278,
"bnt-sts",
"Latn",
type = "reconstructed",
}
m["btk-pro"] = {
"Batak Purba",
116773191,
"btk",
"Latn",
type = "reconstructed",
}
m["cau-abz-pro"] = {
"Abkhaz-Abaza Purba",
7251831,
"cau-abz",
"Latn",
type = "reconstructed",
}
m["cau-and-pro"] = {
"Andi Purba",
nil,
"cau-and",
"Latn",
type = "reconstructed",
}
m["cau-ava-pro"] = {
"Avar-Andi Purba",
116773187,
"cau-ava",
"Latn",
type = "reconstructed",
}
m["cau-cir-pro"] = {
"Circassia Purba",
7251838,
"cau-cir",
"Latn",
type = "reconstructed",
}
m["cau-drg-pro"] = {
"Dargwa Purba",
116773205,
"cau-drg",
"Latn",
type = "reconstructed",
}
m["cau-lzg-pro"] = {
"Lezghi Purba",
116773223,
"cau-lzg",
"Latn",
type = "reconstructed",
}
m["cau-nec-pro"] = {
"Kaukasia Timur Laut Purba",
116773244,
"cau-nec",
"Latn",
type = "reconstructed",
}
m["cau-nkh-pro"] = {
"Nakh Purba",
108032840,
"cau-nkh",
"Latn",
type = "reconstructed",
}
m["cau-nwc-pro"] = {
"Kaukasia Barat Laut Purba",
7251861,
"cau-nwc",
"Latn",
type = "reconstructed",
}
m["cau-tsz-pro"] = {
"Tsez Purba",
116773287,
"cau-tsz",
"Latn",
type = "reconstructed",
}
m["cba-ata"] = {
"Atanques",
4812783,
"cba",
"Latn",
}
m["cba-cat"] = {
"Catío Chibcha",
7083619,
"cba",
"Latn",
}
m["cba-dor"] = {
"Dorasque",
5297532,
"cba",
"Latn",
}
m["cba-dui"] = {
"Duit",
3041061,
"cba",
"Latn",
}
m["cba-hue"] = {
"Huetar",
35514,
"cba",
"Latn",
}
m["cba-nut"] = {
"Nutabe",
7070405,
"cba",
"Latn",
}
m["cba-pro"] = {
"Chibchan Purba",
116773203,
"cba",
"Latn",
type = "reconstructed",
}
m["ccs-pro"] = {
"Kartvelia Purba",
2608203,
"ccs",
"Latn",
type = "reconstructed",
strip_diacritics = {
from = {"q̣", "p̣", "ʓ", "ċ"},
to = {"q̇", "ṗ", "ʒ", "c̣"}
},
}
m["ccs-gzn-pro"] = {
"Georgia-Zan Purba",
23808119,
"ccs-gzn",
"Latn",
type = "reconstructed",
strip_diacritics = {
from = {"q̣", "p̣", "ʓ", "ċ"},
to = {"q̇", "ṗ", "ʒ", "c̣"}
},
}
m["cdc-cbm-pro"] = {
"Chadik Tengah Purba",
116773197,
"cdc-cbm",
"Latn",
type = "reconstructed",
}
m["cdc-mas-pro"] = {
"Masa Purba",
116773789,
"cdc-mas",
"Latn",
type = "reconstructed",
}
m["cdc-pro"] = {
"Chadik Purba",
116773201,
"cdc",
"Latn",
type = "reconstructed",
}
m["cdd-pro"] = {
"Caddoan Purba",
116773725,
"cdd",
"Latn",
type = "reconstructed",
}
m["cel-bry-pro"] = {
"Britonik Purba",
1248800,
"cel-bry",
"Latn, Polyt",
sort_key = {
Latn = "cel-bry-pro-sortkey",
},
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["cel-gal"] = {
"Gallaecia",
3094789,
"cel-his",
}
m["cel-gau"] = {
"Gaul",
29977,
"cel",
"Latn, Polyt, Ital",
strip_diacritics = {
Latn = {remove_diacritics = c.macron .. c.breve .. c.diaer},
},
sort_key = {
Latn = "cel-bry-pro-sortkey",
},
-- Ital translit in [[Module:scripts/data]]
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["cel-pro"] = {
"Keltik Purba",
653649,
"cel",
"Latn",
type = "reconstructed",
sort_key = "cel-pro-sortkey",
}
m["chi-pro"] = {
"Chimakuan Purba",
116773734,
"chi",
"Latn",
type = "reconstructed",
}
m["chm-pro"] = {
"Mari Purba",
116773788,
"chm",
"Latn",
type = "reconstructed",
}
m["cmc-pro"] = {
"Chamik Purba",
114793834,
"cmc",
"Latn",
type = "reconstructed",
}
m["crp-bip"] = {
"Pijin Basque-Iceland",
810378,
"crp",
"Latn",
ancestors = "eu",
}
m["crp-cpr"] = {
"Pijin Rusia-China",
nil,
"crp",
"Hani, Cyrl, Latn",
ancestors = "ru, zh",
translit = {Cyrl = "ru-translit"},
strip_diacritics = {
Cyrl = {remove_diacritics = c.acute .. c.grave .. c.macron},
},
}
m["crp-gep"] = {
"Pijin Greenland Barat",
17036301,
"crp",
"Latn",
ancestors = "kl",
}
m["crp-kia"] = {
"Pijin Jerman Kiautschou",
108314615,
"crp",
"Latn",
ancestors = "de",
}
m["crp-mar"] = {
"Bahasa Roh Maroon",
1093206,
"crp",
"Latn",
ancestors = "en",
}
m["crp-mpp"] = {
"Pijin Portugis Macau",
128804537,
"crp",
"Hant, Latn",
ancestors = "pt",
sort_key = {Hant = "Hani-sortkey"},
}
m["crp-rsn"] = {
"Russenorsk",
505125,
"crp",
"Cyrl, Latn",
ancestors = "nn, ru",
translit = {Cyrl = "ru-translit"},
}
m["crp-spp"] = {
"Pijin Ladang Samoa",
7409948,
"crp",
"Latn",
ancestors = "en",
}
m["crp-slb"] = {
"Inggeris Solombala",
7558525,
"crp",
"Cyrl, Latn",
ancestors = "en, ru",
translit = {Cyrl = "ru-translit"},
}
m["crp-tpr"] = {
"Pijin Rusia Taimyr",
16930506,
"crp",
"Cyrl",
ancestors = "ru",
translit = "ru-translit",
}
m["csu-bba-pro"] = {
"Bongo-Bagirmi Purba",
116773722,
"csu-bba",
"Latn",
type = "reconstructed",
}
m["csu-maa-pro"] = {
"Mangbetu Purba",
116773786,
"csu-maa",
"Latn",
type = "reconstructed",
}
m["csu-pro"] = {
"Sudan Tengah Purba",
116773730,
"csu",
"Latn",
type = "reconstructed",
}
m["csu-sar-pro"] = {
"Sara Purba",
116773809,
"csu-sar",
"Latn",
type = "reconstructed",
}
m["cus-ash"] = {
"Ashraaf",
4805855,
"cus-som",
"Latn",
}
m["cus-hec-pro"] = {
"Kusyi Timur Tanah Tinggi Purba",
116773761,
"cus-hec",
"Latn",
type = "reconstructed",
}
m["cus-som-pro"] = {
"Somaloid Purba",
nil,
"cus-som",
"Latn",
type = "reconstructed",
}
m["cus-sou-pro"] = {
"Kusyi Selatan Purba",
126081567,
"cus-sou",
"Latn",
type = "reconstructed",
}
m["cus-pro"] = {
"Kusyi Purba",
116773204,
"cus",
"Latn",
type = "reconstructed",
}
m["dmn-dam"] = {
"Dama (Sierra Leone)",
19601574,
"dmn",
"Latn",
}
m["dra-bry"] = {
"Beary",
1089116,
"qfa-mix",
"Mlym, Knda",
ancestors = "ml, tcy",
-- Knda translit in [[Module:scripts/data]]
-- Mlym translit in [[Module:scripts/data]]
}
m["dra-cen-pro"] = {
"Dravidia Tengah Purba",
nil,
"dra-cen",
"Latn",
type = "reconstructed",
}
m["dra-mkn"] = {
"Kannada Pertengahan",
128810572,
"dra-kan",
"Knda",
-- Knda translit in [[Module:scripts/data]]
}
m["dra-nor-pro"] = {
"Dravidia Utara Purba",
124433593,
"dra-nor",
"Latn",
type = "reconstructed",
}
m["dra-okn"] = {
"Kannada Kuno",
15723156,
"dra-kan",
"Knda",
-- Knda translit in [[Module:scripts/data]]
}
m["dra-ote"] = {
"Telugu Kuno",
126720868,
"dra-tel",
"Telu",
translit = "te-translit",
}
m["dra-pro"] = {
"Dravidia Purba",
1702853,
"dra",
"Latn",
type = "reconstructed",
}
m["dra-sdo-pro"] = {
"Dravidia Selatan I Purba",
104847952, -- Wikipedia's "Proto-South Dravidian" is Proto-South Dravidian I in this scheme.
"dra-sdo",
"Latn",
type = "reconstructed",
}
m["dra-sdt-pro"] = {
"Dravidia Selatan II Purba",
128885257,
"dra-sdt",
"Latn",
type = "reconstructed",
}
m["dra-sou-pro"] = {
"Dravidia Selatan Purba",
128886121,
"dra-sou",
"Latn",
type = "reconstructed",
}
m["egx-dem"] = {
"Mesir Demotik",
36765,
"egx",
"Latn, Egyd, Polyt",
sort_key = {
Latn = {
remove_diacritics = "'%-%s",
from = {"ꜣ", "j", "e", "ꜥ", "y", "w", "b", "p", "f", "m", "n", "r", "l", "ḥ", "ḫ", "h̭", "ẖ", "h", "š", "s", "q", "k", "g", "ṱ", "ṯ", "t", "ḏ", "%.", "⸗"},
to = {p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[15], p[16], p[16], p[17], p[14], p[19], p[18], p[20], p[21], p[22], p[23], p[24], p[23], p[25], p[26], p[26]}
},
},
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["dmn-pro"] = {
"Mande Purba",
116773785,
"dmn",
"Latn",
type = "reconstructed",
}
m["dmn-mdw-pro"] = {
"Mande Barat Purba",
116773822,
"dmn-mdw",
"Latn",
type = "reconstructed",
}
m["dru-pro"] = {
"Rukai Purba",
116773807,
"map",
"Latn",
type = "reconstructed",
}
m["ero-gsz"] = {
"Geshiza",
nil,
"ero",
"Latn",
}
m["ero-nya"] = {
"Nyagrong Minyag",
nil,
"ero",
"Latn",
}
m["ero-tau"] = {
"Stau",
nil,
"ero",
"Latn",
}
m["esx-esk-pro"] = {
"Eskimo Purba",
7251842,
"esx-esk",
"Latn",
type = "reconstructed",
}
m["esx-ink"] = {
"Inuktun",
1671647,
"esx-inu",
"Latn",
}
m["esx-inq"] = {
"Inuinnaqtun",
28070,
"esx-inu",
"Latn",
}
m["esx-inu-pro"] = {
"Inuit Purba",
60785588,
"esx-inu",
"Latn",
type = "reconstructed",
}
m["esx-pro"] = {
"Eskimo-Aleut Purba",
7251843,
"esx",
"Latn",
type = "reconstructed",
}
m["esx-tut"] = {
"Tunumiisut",
15665389,
"esx-inu",
"Latn",
}
m["euq-pro"] = {
"Basque Purba",
938011,
"euq",
"Latn",
type = "reconstructed",
}
m["gba-pro"] = {
"Gbaya Purba",
nil,
"gba",
"Latn",
type = "reconstructed",
}
m["gem-pro"] = {
"Jermanik Purba",
669623,
"gem",
"Latn",
type = "reconstructed",
sort_key = "gem-pro-sortkey",
}
m["gme-bur"] = {
"Burgundia",
47625,
"gme",
"Latn",
}
m["gme-cgo"] = {
"Goth Crimea",
36211,
"gme",
"Latn",
}
m["gmq-gut"] = {
"Gutnish",
1256646,
"gmq",
"Latn",
ancestors = "gmq-ogt",
}
m["gmq-jmk"] = {
"Jamtish",
35512,
"gmq-eas",
"Latn",
}
m["gmq-mno"] = {
"Norway Pertengahan",
3417070,
"gmq-wes",
"Latn",
}
m["gmq-oda"] = {
"Denmark Kuno",
12330003,
"gmq-eas",
"Latn, Runr",
strip_diacritics = {remove_diacritics = c.macron},
}
m["gmq-ogt"] = {
"Gutnish Kuno",
1133488,
"gmq",
"Latn, Runr",
ancestors = "non",
}
m["gmq-osw"] = {
"Sweden Kuno",
2417210,
"gmq-eas",
"Latn, Runr",
strip_diacritics = {remove_diacritics = c.macron},
}
m["gmq-pro"] = {
"Norse Purba",
1671294,
"gmq",
"Runr",
translit = "Runr-translit",
}
m["gmq-scy"] = {
"Scanian",
768017,
"gmq-eas",
"Latn",
}
m["gmw-bgh"] = {
"Bergish",
329030,
"gmw-frk",
"Latn",
}
m["gmw-cfr"] = {
"Franconia Tengah",
572197,
"gmw-hgm",
"Latn",
ancestors = "gmh",
wikimedia_codes = "ksh",
}
m["gmw-ecg"] = {
"Jerman Tengah Timur",
499344, -- subsumes Q699284, Q152965
"gmw-hgm",
"Latn",
ancestors = "gmh",
}
m["gmw-fin"] = {
"Fingallian",
3072588,
"gmw-ian",
"Latn",
}
m["gmw-gts"] = {
"Gottscheerish",
533109,
"gmw-hgm",
"Latn",
ancestors = "bar",
}
m["gmw-jdt"] = {
"Belanda Jersey",
1687911,
"gmw-frk",
"Latn",
ancestors = "nl",
}
m["gmw-msc"] = {
"Scots Pertengahan",
3327000,
"gmw-ang",
"Latn",
ancestors = "enm-esc",
}
m["gmw-pro"] = {
"Jermanik Barat Purba",
78079021,
"gmw",
"Latn, Runr",
-- type = "reconstructed",
-- largely but not entirely reconstructed (like Proto-Norse); see April '24 BP, set back to reconstructed (?) if 'anti-asterisk' is added
sort_key = "gmw-pro-sortkey",
}
m["gmw-rfr"] = {
"Franconia Rhine",
707007,
"gmw-hgm",
"Latn",
ancestors = "gmh",
}
m["gmw-stm"] = {
"Schwaben Szatmár",
2223059,
"gmw-hgm",
"Latn",
ancestors = "swg",
}
m["gmw-tsx"] = {
"Saxon Transylvania",
260942,
"gmw-hgm",
"Latn",
ancestors = "gmw-cfr",
}
m["gmw-vog"] = {
"Jerman Volga",
312574,
"gmw-hgm",
"Latn",
ancestors = "gmw-rfr",
}
m["gmw-zps"] = {
"Jerman Zipser",
205548,
"gmw-hgm",
"Latn",
ancestors = "gmh",
}
m["gn-cls"] = {
"Guarani Klasik",
17478065,
"gn",
"Latn",
}
m["grk-cal"] = {
"Yunani Calabria",
1146398,
"grk",
"Latn, Grek",
ancestors = "grk-ita",
translit = {
Grek = "el-translit",
},
-- Grek display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["grk-car"] = {
"Cargesian Greek",
16549443,
"grk",
"Latn, Grek",
ancestors = "gkm",
}
m["grk-ita"] = {
"Yunani Italiot",
19720507,
"grk",
"Latn, Grek",
ancestors = "gkm",
translit = {
Grek = "el-translit",
},
-- Grek display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["grk-mar"] = {
"Yunani Mariupol",
4400023,
"grk",
"Cyrl, Latn, Grek",
ancestors = "gkm",
translit = {
Cyrl = "grk-mar-translit",
Grek = "grk-mar-translit",
},
override_translit = true,
strip_diacritics = {
Cyrl = {remove_diacritics = c.acute},
},
-- Grek display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["grk-pro"] = {
"Hellenik Purba",
1231805,
"grk",
"Latn, Polyt",
type = "reconstructed",
sort_key = {Latn = {
from = {"ʰ", "ʷ"},
to = {"h", "w"},
remove_diacritics = c.grave .. c.acute .. c.macron .. c.breve .. c.caron .. c.CGJ
}},
display_text = {Latn = {
from = {"([dlLt])" .. c.caron},
to = {"%1" .. c.CGJ .. c.caron},
}},
strip_diacritics = {Latn = {
from = {"([dlLt])" .. c.caron},
to = {"%1" .. c.CGJ .. c.caron},
}},
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
-- NOTE: formerly no translit specified for Polyt; presumably an accidental omission; if not, set Polyt = false in
-- the translit section
}
m["hmn-pro"] = {
"Hmongik Purba",
116773210,
"hmn",
"Latn",
type = "reconstructed",
}
m["hmx-mie-pro"] = {
"Mienik Purba",
116773229,
"hmx-mie",
"Latn",
type = "reconstructed",
}
m["hmx-pro"] = {
"Hmong-Mien Purba",
7251846,
"hmx",
"Latn",
type = "reconstructed",
}
m["hyx-pro"] = {
"Armenia Purba",
3848498,
"hyx",
"Latn",
type = "reconstructed",
}
m["iir-nur-pro"] = {
"Nuristani Purba",
116773248,
"iir-nur",
"Latn",
type = "reconstructed",
}
m["iir-pro"] = {
"Indo-Iran Purba",
966439,
"iir",
"Latn",
type = "reconstructed",
}
m["ijo-pro"] = {
"Ijoid Purba",
116773766,
"ijo",
"Latn",
type = "reconstructed",
}
m["inc-apa"] = {
"Apabhramsa",
616419,
"inc-mid",
"Deva, Shrd, Sidd",
ancestors = "pra",
translit = {
Deva = "sa-translit",
-- Shrd translit in [[Module:scripts/data]]
-- Sidd translit in [[Module:scripts/data]]
},
}
m["inc-ash"] = {
"Prakrit Ashoka",
104854379,
"inc-mid",
"Brah, Khar",
ancestors = "sa",
translit = {
-- Brah translit in [[Module:scripts/data]]
Khar = "Khar-translit",
},
}
m["inc-dng-pro"] = {
"Dangari Purba",
nil,
"inc-dng",
"Latn",
type = "reconstructed",
}
m["inc-kam"] = {
"Prakrit Kamarupi",
6356097,
"inc-bas",
"Brah, Sidd",
-- Brah, Sidd translit in [[Module:scripts/data]]
}
m["inc-kho"] = {
"Kholosi",
24952008,
"inc-snd",
"Latn",
}
m["inc-khr"] = {
"Khortha",
13406670,
"inc-sad",
"Deva, Kthi",
translit = {
Deva = "bho-translit",
Kthi = "bho-Kthi-translit",
},
}
m["inc-krd-pro"] = {
"Kamta Purba",
128816843,
"inc-bas",
"Latn",
ancestors = "inc-kam",
type = "reconstructed",
}
m["inc-mas"] = {
"Assam Pertengahan",
128806836,
"inc-bas",
"as-Beng",
ancestors = "inc-oas",
translit = "inc-mas-translit",
}
m["inc-mbn"] = {
"Benggali Pertengahan",
113559927,
"inc-bas",
"Beng",
ancestors = "inc-obn",
translit = "inc-mbn-translit",
}
m["inc-mgu"] = {
"Gujarati Pertengahan",
24907429,
"inc-wes",
"Deva",
ancestors = "inc-ogu",
}
m["inc-mor"] = {
"Odia Pertengahan",
128810882,
"inc-eas",
"Orya",
ancestors = "inc-oor",
}
m["inc-oas"] = {
"Assam Awal",
85758237,
"inc-bas",
"as-Beng",
ancestors = "inc-kam",
translit = "inc-oas-translit",
}
m["inc-oaw"] = {
"Awadhi Kuno",
nil,
"inc-hie",
"Deva, Kthi, Aran",
strip_diacritics = {
from = {"هٔ", "ۂ"}, -- character "ۂ" code U+06C2 to "ه" and "هٔ" (U+0647 + U+0654) to "ه"
to = {"ہ", "ہ"},
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef
},
translit = {
Deva = "sa-translit",
Kthi = "sa-Kthi-translit",
Aran = "inc-ohi-translit",
},
}
m["inc-obn"] = {
"Benggali Kuno",
113559926,
"inc-bas",
"Beng",
}
m["inc-ogu"] = {
"Gujarati Kuno",
24907427,
"inc-wes",
"Deva",
translit = "sa-translit",
}
m["inc-ohi"] = {
"Hindi Kuno",
48767781,
"inc-hiw",
"Deva, Aran",
strip_diacritics = {
from = {"هٔ", "ۂ"}, -- character "ۂ" code U+06C2 to "ه" and "هٔ" (U+0647 + U+0654) to "ه"
to = {"ہ", "ہ"},
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef
},
translit = {
Deva = "sa-translit",
Aran = "inc-ohi-translit",
},
}
m["inc-oor"] = {
"Odia Kuno",
128807801,
"inc-eas",
"Orya",
}
m["inc-opa"] = {
"Punjabi Kuno",
115270971,
"inc-pan",
"Guru, Aran",
translit = {
Guru = "inc-opa-Guru-translit",
Aran = "pa-Aran-translit",
},
strip_diacritics = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun},
}
m["inc-pro"] = {
"Indo-Arya Purba",
23808344,
"inc",
"Latn",
type = "reconstructed",
}
m["inc-sar"] = {
"Sarazi",
85799728,
"him",
"Aran, Deva, Takr",
strip_diacritics = {
from = {"هٔ", "ۂ"}, -- character "ۂ" code U+06C2 to "ه" and "هٔ" (U+0647 + U+0654) to "ه"
to = {"ہ", "ہ"},
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef
},
translit = {
Aran = "ur-translit",
Deva = "hi-translit",
-- Takr = "Takr-translit",
},
}
m["ine-ana-pro"] = {
"Anatolia Purba",
7251833,
"ine-ana",
"Latn",
type = "reconstructed",
}
m["ine-bsl-pro"] = {
"Balto-Slavik Purba",
1703347,
"ine-bsl",
"Latn",
type = "reconstructed",
sort_key = {
from = {"[áā]", "[éēḗ]", "[íī]", "[óōṓ]", "[úū]", c.acute, c.macron, "ˀ"},
to = {"a", "e", "i", "o", "u"}
},
}
m["ine-kal"] = {
"Kalašma",
122770439,
"ine-ana",
"Xsux",
}
m["ine-pae"] = {
"Paeonia",
2705672,
"ine",
"Polyt",
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["ine-pro"] = {
"Indo-Eropah Purba",
37178,
"ine",
"Latn",
type = "reconstructed",
sort_key = {
from = {"[áā]", "[éēḗ]", "[íī]", "[óōṓ]", "[úū]", "ĺ", "ḿ", "ń", "ŕ", "ǵ", "ḱ", "ʰ", "ʷ", "₁", "₂", "₃", c.ringbelow, c.acute, c.macron},
to = {"a", "e", "i", "o", "u", "l", "m", "n", "r", "g'", "k'", "¯h", "¯w", "1", "2", "3"}
},
}
m["ine-toc-pro"] = {
"Tocharia Purba",
104841462,
"ine-toc",
"Latn",
type = "reconstructed",
}
m["xme-old"] = {
"Median Kuno",
36461,
"xme",
"Polyt, Latn",
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["xme-mid"] = {
"Median Pertengahan",
12836150,
"xme",
"Latn",
}
m["xme-ker"] = {
"Kerman",
129850,
"xme",
"Arab, Latn, Hebr",
ancestors = "xme-mid",
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["xme-taf"] = {
"Tafreshi",
nil,
"xme",
"Arab, Latn",
ancestors = "xme-mid",
}
m["xme-ttc-pro"] = {
"Tatik Purba",
122973870,
"xme-ttc",
"Latn",
ancestors = "xme-mid",
}
m["xme-kls"] = {
"Kalasuri",
nil,
"xme-ttc",
ancestors = "xme-ttc-nor",
}
m["xme-klt"] = {
"Kilit",
3612452,
"xme-ttc",
"Cyrl", -- and Arab?
}
m["xme-ott"] = {
"Tati Kuno",
434697,
"xme-ttc",
"Arab, Latn",
}
m["ira-kms-pro"] = {
"Komisenia Purba",
116773777,
"ira-kms",
"Latn",
type = "reconstructed",
}
m["ira-mpr-pro"] = {
"Medo-Parthia Purba",
116773227,
"ira-mpr",
"Latn",
type = "reconstructed",
}
m["ira-pat-pro"] = {
"Pathan Purba",
116773255,
"ira-pat",
"Latn",
type = "reconstructed",
}
m["ira-pro"] = {
"Iran Purba",
4167865,
"ira",
"Latn",
type = "reconstructed",
}
m["ira-zgr-pro"] = {
"Zaza-Gorani Purba",
116775031,
"ira-zgr",
"Latn",
type = "reconstructed",
}
m["xsc-pro"] = {
"Scythia Purba",
116773273,
"xsc",
"Latn",
type = "reconstructed",
}
m["xsc-sar-pro"] = {
"Sarmatia Purba",
116773249,
"xsc-sar",
"Latn",
type = "reconstructed",
}
m["xsc-skw-pro"] = {
"Saka-Wakhi Purba",
116773267,
"xsc-skw",
"Latn",
type = "reconstructed",
}
m["xsc-sak-pro"] = {
"Saka Purba",
116773264,
"xsc-sak",
"Latn",
type = "reconstructed",
}
m["ira-sym-pro"] = {
"Shughni-Yazghulami-Munji Purba",
116773813,
"ira-sym",
"Latn",
type = "reconstructed",
}
m["ira-sgi-pro"] = {
"Sanglechi-Ishkashimi Purba",
116773808,
"ira-sgi",
"Latn",
type = "reconstructed",
}
m["ira-mny-pro"] = {
"Munji-Yidgha Purba",
116773792,
"ira-mny",
"Latn",
type = "reconstructed",
}
m["ira-shy-pro"] = {
"Shughni-Yazghulami Purba",
116773812,
"ira-shy",
"Latn",
type = "reconstructed",
}
m["ira-shr-pro"] = {
"Shughni-Roshani Purba",
116773811,
"ira-shr",
"Latn",
type = "reconstructed",
}
m["ira-sgc-pro"] = {
"Sogdia Purba",
116773276,
"ira-sgc",
"Latn",
type = "reconstructed",
}
m["ira-wnj"] = {
"Vanji",
3398419,
"ira-shy",
"Latn",
}
m["iro-ere"] = {
"Erie",
5388365,
"iro-nor",
"Latn",
}
m["iro-min"] = {
"Mingo",
128531,
"iro-nor",
"Latn",
ietf_subtag = "i-mingo", -- grandfathered IETF tag
}
m["iro-nor-pro"] = {
"Iroquois Utara Purba",
116773242,
"iro-nor",
"Latn",
type = "reconstructed",
}
m["iro-pro"] = {
"Iroquois Purba",
7251852,
"iro",
"Latn",
type = "reconstructed",
}
m["itc-pro"] = {
"Italik Purba",
17102720,
"itc",
"Latn",
type = "reconstructed",
}
m["itc-psa"] = {
"Pra-Samnit",
7239186,
"itc-sbl",
"Ital, Polyt, Latn",
-- Ital translit in [[Module:scripts/data]] (NOTE: formerly not present, probably an accidental omission)
-- Polyt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["jpx-hcj"] = {
"Hachijō",
5637049,
"jpx",
"Jpan",
ancestors = "ojp-eas",
translit = s["jpx-translit"],
display_text = s["jpx-displaytext"],
strip_diacritics = s["jpx-stripdiacritics"],
sort_key = s["jpx-sortkey"],
}
m["jpx-pro"] = {
"Jepunik Purba",
3924309,
"jpx",
"Latn",
type = "reconstructed",
}
m["jpx-ryu-pro"] = {
"Ryukyu Purba",
56349069,
"jpx-ryu",
"Latn",
type = "reconstructed",
}
m["kar-pro"] = {
"Karen Purba",
85794783,
"kar",
"Latn",
type = "reconstructed",
}
m["kca-eas"] = {
"Khanty Timur",
30304622,
"kca",
"Cyrl",
translit = "kca-translit",
override_translit = true,
-- TODO temporary until MediaWiki supports Unicode 16 (probably requires a PHP update from their side)
sort_key = { Cyrl = { from = {""}, to = {""} } },
}
m["kca-nor"] = {
"Khanty Utara",
30304527,
"kca",
"Cyrl",
translit = "kca-translit",
override_translit = true,
-- TODO temporary until MediaWiki supports Unicode 16 (probably requires a PHP update from their side)
sort_key = { Cyrl = { from = {""}, to = {""} } },
}
m["kca-pro"] = {
"Khanty Purba",
127505171,
"kca",
"Latn",
type = "reconstructed",
}
m["kca-sou"] = {
"Khanty Selatan",
30304618,
"kca",
"Cyrl",
translit = "kca-translit",
override_translit = true,
}
m["khi-kho-pro"] = {
"Khoe Purba",
116773218,
"khi-kho",
"Latn",
type = "reconstructed",
}
m["khi-kun"] = {
"ǃKung",
32904,
"khi-kxa",
"Latn",
}
m["ko-ear"] = {
"Korea Moden Awal",
756014,
"qfa-kor",
"Kore",
ancestors = "okm",
translit = "okm-translit",
-- Kore strip_diacritics in [[Module:scripts/data]]
}
m["kro-pro"] = {
"Kru Purba",
116773778,
"kro",
"Latn",
type = "reconstructed",
}
m["ku-pro"] = {
"Kurdi Purba",
116773221,
"ku",
"Latn",
type = "reconstructed",
}
m["map-ata-pro"] = {
"Atayalik Purba",
116773151,
"map-ata",
"Latn",
type = "reconstructed",
}
m["map-bms"] = {
"Banyumasan",
33219,
"map",
"Latn, Java",
}
m["map-pro"] = {
"Austronesia Purba",
49230,
"map",
"Latn",
type = "reconstructed",
}
m["mis-hkl"] = {
"Hokkien Peranakan Kelantan",
108794818,
"qfa-mix",
ancestors = "nan-hbl, sou, mfa",
}
m["mis-idn"] = {
"Idiom Neutral",
35847,
"art",
"Latn",
type = "appendix-constructed",
}
m["mis-isa"] = {
"Isauria",
16956868,
nil,
-- "Xsux, Hluw, Latn",
}
m["mis-jie"] = {
"Jie",
124424186,
nil,
"Hani",
sort_key = "Hani-sortkey",
}
m["mis-jzh"] = {
"Jizhao",
45242758,
"qfa-bej",
"Latn",
}
m["mis-kas"] = {
"Kassite",
35612,
nil,
"Xsux",
}
m["mis-mmd"] = {
"Mimi Decorse",
6862206,
nil,
"Latn",
}
m["mis-mmn"] = {
"Mimi Nachtigal",
6862207,
nil,
"Latn",
}
m["mis-phi"] = {
"Filistin",
2230924,
nil,
"Phnx",
-- Phnx translit in [[Module:scripts/data]] (NOTE: not present before, presumably an accidental omission)
}
m["mis-rou"] = {
"Rouran",
48816637,
"qfa-xgx",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mis-tdl"] = {
"Turdulia",
133176492,
}
m["mis-tdt"] = {
"Turdetania",
133176461,
}
m["mis-tnw"] = {
"Tangwang",
7683179,
"qfa-mix",
"Latn",
ancestors = "cmn, sce",
}
m["mis-tuh"] = {
"Tuyuhun",
48816625,
"qfa-xgx",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mis-tuo"] = {
"Tuoba",
48816629,
"qfa-xgx",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mis-wuh"] = {
"Wuhuan",
118976867,
"qfa-xgx",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mis-xbi"] = {
"Xianbei",
4448647,
"qfa-xgx",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mis-xnu"] = {
"Xiongnu",
10901674,
nil,
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mjg-mgl"] = {
"Mongghul",
53765528,
"mjg",
"Latn", -- also Mong, Cyrl ?
}
m["mjg-mgr"] = {
"Mangghuer",
56285392,
"mjg",
"Latn", -- also Mong, Cyrl ?
}
m["mkh-asl-pro"] = {
"Asli Purba",
55630680,
"mkh-asl",
"Latn",
type = "reconstructed",
}
m["mkh-ban-pro"] = {
"Bahnar Purba",
116773189,
"mkh-ban",
"Latn",
type = "reconstructed",
}
m["mkh-kat-pro"] = {
"Katuik Purba",
116773772,
"mkh-kat",
"Latn",
type = "reconstructed",
}
m["mkh-khm-pro"] = {
"Khmuik Purba",
116773774,
"mkh-khm",
"Latn",
type = "reconstructed",
}
m["mkh-kmr-pro"] = {
"Khmer Purba",
55630684,
"mkh-kmr",
"Latn",
type = "reconstructed",
}
m["mkh-mmn"] = {
"Mon Pertengahan",
121337926,
"mkh-mnc",
"Latn, Mymr", --and also Pallava
ancestors = "omx",
}
m["mkh-mnc-pro"] = {
"Monik Purba",
116773231,
"mkh-mnc",
"Latn",
type = "reconstructed",
}
m["mkh-mvi"] = {
"Vietnam Pertengahan",
9199,
"mkh-vie",
"Hani, Latn",
sort_key = {Hani = "Hani-sortkey"},
}
m["mkh-pal-pro"] = {
"Palaungik Purba",
104847372,
"mkh-pal",
"Latn",
type = "reconstructed",
}
m["mkh-pea-pro"] = {
"Pearik Purba",
116773804,
"mkh-pea",
"Latn",
type = "reconstructed",
}
m["mkh-pkn-pro"] = {
"Pakanik Purba",
116773803,
"mkh-pkn",
"Latn",
type = "reconstructed",
}
m["mkh-pro"] = { --This will be merged into 2015 aav-pro.
"Mon-Khmer Purba",
7251859,
"mkh",
"Latn",
type = "reconstructed",
}
m["mnw-tha"] = { -- To be removed.
"Mon Thailand",
nil,
"mkh-mnc",
"Mymr, Thai",
ancestors = "mkh-mmn",
sort_key = {
from = {"[%p]", "ျ", "ြ", "ွ", "ှ", "ၞ", "ၟ", "ၠ", "ၚ", "ဿ", "[็-๎]", "([เแโใไ])([ก-ฮ])ฺ?"},
to = {"", "္ယ", "္ရ", "္ဝ", "္ဟ", "္န", "္မ", "္လ", "င", "သ္သ", "", "%2%1"}
},
}
m["mkh-vie-pro"] = {
"Vietik Purba",
109432616,
"mkh-vie",
"Latn",
type = "reconstructed",
}
m["mns-cen"] = {
"Mansi Tengah",
128810384,
"mns",
"Cyrl",
translit = "mns-translit",
override_translit = true,
}
m["mns-nor"] = {
"Mansi Utara",
30304537,
"mns",
"Cyrl",
translit = "mns-translit",
override_translit = true,
}
m["mns-pro"] = {
"Mansi Purba",
128883093,
"mns",
"Latn",
type = "reconstructed",
}
m["mns-sou"] = {
"Mansi Selatan",
30304629,
"mns",
"Cyrl",
translit = "mns-translit",
override_translit = true,
}
m["mun-pro"] = {
"Munda Purba",
105102373,
"mun",
"Latn",
type = "reconstructed",
}
m["myn-chl"] = { -- the stage after ''emy''
"Ch'olti'",
873995,
"myn",
"Latn",
}
m["myn-pro"] = {
"Maya Purba",
3321532,
"myn",
"Latn",
type = "reconstructed",
}
m["nai-ala"] = {
"Alazapa",
128810233,
nil,
"Latn",
}
m["nai-bay"] = {
"Bayogoula",
1563704,
nil,
"Latn",
}
m["nai-cal"] = {
"Calusa",
51782,
nil,
"Latn",
}
m["nai-chi"] = {
"Chiquimulilla",
25339627,
"nai-xin",
"Latn",
}
m["nai-chu-pro"] = {
"Chumash Purba",
116773736,
"nai-chu",
"Latn",
type = "reconstructed",
}
m["nai-cig"] = {
"Ciguayo",
20741700,
nil,
"Latn",
}
m["nai-ckn-pro"] = {
"Chinook Purba",
116773735,
"nai-ckn",
"Latn",
type = "reconstructed",
}
m["nai-guz"] = {
"Guazacapán",
19572028,
"nai-xin",
"Latn",
}
m["nai-hit"] = {
"Hitchiti",
1542882,
"nai-mus",
"Latn",
}
m["nai-ipa"] = {
"Ipai",
3027474,
"nai-yuc",
"Latn",
}
m["nai-jtp"] = {
"Jutiapa",
nil,
"nai-xin",
"Latn",
}
m["nai-jum"] = {
"Jumaytepeque",
25339626,
"nai-xin",
"Latn",
}
m["nai-kat"] = {
"Kathlamet",
6376639,
"nai-ckn",
"Latn",
}
m["nai-klp-pro"] = {
"Kalapuya Purba",
116773771,
"nai-klp",
"Latn",
type = "reconstructed",
}
m["nai-knm"] = {
"Konomihu",
3198734,
"nai-shs",
"Latn",
}
m["nai-kum"] = {
"Kumeyaay",
4910139,
"nai-yuc",
"Latn",
}
m["nai-mac"] = {
"Macoris",
21070851,
nil,
"Latn",
}
m["nai-mdu-pro"] = {
"Maidu Purba",
116773784,
"nai-mdu",
"Latn",
type = "reconstructed",
}
m["nai-miz-pro"] = {
"Mixe-Zoque Purba",
7251858,
"nai-miz",
"Latn",
type = "reconstructed",
}
m["nai-mus-pro"] = {
"Muskogi Purba",
116775368,
"nai-mus",
"Latn",
type = "reconstructed",
}
m["nai-nao"] = {
"Naolan",
6964594,
nil,
"Latn",
}
m["nai-nrs"] = {
"Shasta Sungai Baru",
7011254,
"nai-shs",
"Latn",
}
m["nai-okw"] = {
"Okwanuchu",
3350126,
"nai-shs",
"Latn",
}
m["nai-per"] = {
"Pericú",
3375369,
nil,
"Latn",
}
m["nai-pic"] = {
"Picuris",
7191257,
"nai-kta",
"Latn",
}
m["nai-plp-pro"] = {
"Penuti Penara Purba",
116773806,
"nai-plp",
"Latn",
type = "reconstructed",
}
m["nai-pom-pro"] = {
"Pomo Purba",
116773262,
"nai-pom",
"Latn",
type = "reconstructed",
}
m["nai-qng"] = {
"Quinigua",
36360,
nil,
"Latn",
}
m["nai-sca-pro"] = { -- NB 'sio-pro' "Proto-Siouan" which is Proto-Western Siouan
"Siouan-Catawba Purba",
116773275,
"nai-sca",
"Latn",
type = "reconstructed",
}
m["nai-sin"] = {
"Sinacantán",
24190249,
"nai-xin",
"Latn",
}
m["nai-sln"] = {
"Lenca Salvador",
3229434,
"nai-len",
"Latn",
}
m["nai-spt"] = {
"Sahaptin",
3833015,
"nai-shp",
"Latn",
}
m["nai-tap"] = {
"Tapachultec",
7684401,
"nai-miz",
"Latn",
}
m["nai-taw"] = {
"Tawasa",
7689233,
nil,
"Latn",
}
m["nai-teq"] = {
"Tequistlatec",
2964454,
"nai-tqn",
"Latn",
}
m["nai-tip"] = {
"Tipai",
3027471,
"nai-yuc",
"Latn",
}
m["nai-tot-pro"] = {
"Totozoquean Purba",
116773285,
"nai-tot",
"Latn",
type = "reconstructed",
}
m["nai-tsi-pro"] = {
"Tsimshianik Purba",
nil,
"nai-tsi",
"Latn",
type = "reconstructed",
}
m["nai-utn-pro"] = {
"Utik Purba",
116773290,
"nai-utn",
"Latn",
type = "reconstructed",
}
m["nai-wai"] = {
"Waikuri",
3118702,
nil,
"Latn",
}
m["nai-wji"] = {
"Jicaque Barat",
3178610,
"nai-jcq",
"Latn",
}
m["nai-yup"] = {
"Yupiltepeque",
25339628,
"nai-xin",
"Latn",
}
m["nan-dat"] = {
"Min Datian",
19855572,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
sort_key = "Hani-sortkey",
}
m["nan-hbl"] = {
"Hokkien",
1624231,
"zhx-nan",
"Hants, Latn, Bopo, Kana",
wikimedia_codes = "zh-min-nan",
generate_alternants = "zh-generatealternants",
sort_key = {
Hani = "Hani-sortkey",
Kana = "Kana-sortkey"
},
}
m["nan-hlh"] = {
"Min Hailufeng",
120755728,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
sort_key = "Hani-sortkey",
}
m["nan-lnx"] = {
"Min Longyan",
6674568,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
sort_key = "Hani-sortkey",
}
m["nan-tws"] = {
"Teochew",
36759,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
translit = "zh-translit",
sort_key = "Hani-sortkey",
}
m["nan-zhe"] = {
"Min Zhenan",
3846710,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
sort_key = "Hani-sortkey",
}
m["nan-zsh"] = {
"Min Sanxiang",
7420769,
"zhx-nan",
"Hants",
generate_alternants = "zh-generatealternants",
sort_key = "Hani-sortkey",
}
m["ngf-bin-pro"] = {
"Binandere Purba",
137881672,
"ngf-bin",
"Latn",
type = "reconstructed",
}
m["ngf-pro"] = {
"Trans-New Guinea Purba",
85794785,
"ngf",
"Latn",
type = "reconstructed",
}
m["nic-bco-pro"] = {
"Benue-Congo Purba",
116773194,
"nic-bco",
"Latn",
type = "reconstructed",
}
m["nic-bod-pro"] = {
"Bantoid Purba",
116773190,
"nic-bod",
"Latn",
type = "reconstructed",
}
m["nic-eov-pro"] = {
"Oti-Volta Timur Purba",
116773753,
"nic-eov",
"Latn",
type = "reconstructed",
}
m["nic-gns-pro"] = {
"Gurunsi Purba",
116773759,
"nic-gns",
"Latn",
type = "reconstructed",
}
m["nic-grf-pro"] = {
"Grassfields Purba",
116773755,
"nic-grf",
"Latn",
type = "reconstructed",
}
m["nic-gur-pro"] = {
"Gur Purba",
116773758,
"nic-gur",
"Latn",
type = "reconstructed",
}
m["nic-jkn-pro"] = {
"Jukunoid Purba",
116773769,
"nic-jkn",
"Latn",
type = "reconstructed",
}
m["nic-lcr-pro"] = {
"Cross River Hilir Purba",
116773782,
"nic-lcr",
"Latn",
type = "reconstructed",
}
m["nic-ogo-pro"] = {
"Ogoni Purba",
116773799,
"nic-ogo",
"Latn",
type = "reconstructed",
}
m["nic-ovo-pro"] = {
"Oti-Volta Purba",
116773802,
"nic-ovo",
"Latn",
type = "reconstructed",
}
m["nic-plt-pro"] = {
"Plateau Purba",
116773805,
"nic-plt",
"Latn",
type = "reconstructed",
}
m["nic-pro"] = {
"Niger-Congo Purba",
108000748,
"nic",
"Latn",
type = "reconstructed",
}
m["nic-ubg-pro"] = {
"Ubangi Purba",
116773818,
"nic-ubg",
"Latn",
type = "reconstructed",
}
m["nic-ucr-pro"] = {
"Cross River Hulu Purba",
116773819,
"nic-ucr",
"Latn",
type = "reconstructed",
}
m["nic-vco-pro"] = {
"Volta-Congo Purba",
116773293,
"nic-vco",
"Latn",
type = "reconstructed",
}
m["njo-jgl"] = {
"Ao Chungli",
55607615,
"njo",
"Latn",
}
m["njo-mng"] = {
"Ao Mongsen",
85383221,
"njo",
"Latn",
}
m["nub-har"] = {
"Haraza",
19572059,
"nub",
"Arab, Latn",
}
m["nub-pro"] = {
"Nubia Purba",
116773246,
"nub",
"Latn",
type = "reconstructed",
}
m["omq-cha-pro"] = {
"Chatino Purba",
116773202,
"omq-cha",
"Latn",
type = "reconstructed",
}
m["omq-maz-pro"] = {
"Mazatec Purba",
116773790,
"omq-maz",
"Latn",
type = "reconstructed",
}
m["omq-mix-pro"] = {
"Mixtecan Purba",
21573423,
"omq-mix",
"Latn",
type = "reconstructed",
}
m["omq-mxt-pro"] = {
"Mixtec Purba",
21573424,
"omq-mxt",
"Latn",
type = "reconstructed",
}
m["omq-otp-pro"] = {
"Oto-Pamean Purba",
116773251,
"omq-otp",
"Latn",
type = "reconstructed",
}
m["omq-pro"] = {
"Oto-Manguean Purba",
33669,
"omq",
"Latn",
type = "reconstructed",
}
m["omq-sjq"] = {
"Chatino San Juan Quiahije",
138330751,
"omq-cha",
"Latn",
}
m["omq-tel"] = {
"Mixtec Teposcolula",
nil,
"omq-mxt",
"Latn",
}
m["omq-teo"] = {
"Chatino Teojomulco",
25340451,
"omq-cha",
"Latn",
}
m["omq-tri-pro"] = {
"Triqui Purba",
116773817,
"omq-tri",
"Latn",
type = "reconstructed",
}
m["omq-zap-pro"] = {
"Zapotecan Purba",
116773297,
"omq-zap",
"Latn",
type = "reconstructed",
}
m["omq-zpc-pro"] = {
"Zapotec Purba",
116773296,
"omq-zpc",
"Latn",
type = "reconstructed",
}
m["omv-aro-pro"] = {
"Aroid Purba",
116773721,
"omv-aro",
"Latn",
type = "reconstructed",
}
m["omv-diz-pro"] = {
"Dizoid Purba",
116773750,
"omv-diz",
"Latn",
type = "reconstructed",
}
m["omv-pro"] = {
"Omotik Purba",
116773800,
"omv",
"Latn",
type = "reconstructed",
}
m["oto-otm-pro"] = {
"Otomi Purba",
5908710,
"oto-otm",
"Latn",
type = "reconstructed",
}
m["oto-pro"] = {
"Otomian Purba",
116773252,
"oto",
"Latn",
type = "reconstructed",
}
m["paa-kmn"] = {
"Kómnzo",
18344310,
"paa-wko",
"Latn",
}
m["paa-kwn"] = {
"Kuwani",
6449056,
"qfa-unc", -- poorly attested, possibly the same as or related to Kalabra
"Latn",
}
m["paa-lei"] = {
"Leitre",
85776228,
"paa-isk",
}
m["paa-nha-pro"] = {
"Halmahera Utara Purba",
116773241,
"paa-nha",
"Latn",
type = "reconstructed"
}
m["paa-nun"] = {
"Nungon",
128807788,
"ngf-ynu",
"Latn",
}
m["phi-din"] = {
"Agta Dinapigue",
16945774,
"phi",
"Latn",
}
m["phi-kal-pro"] = {
"Kalamian Purba",
116773213,
"phi-kal",
"Latn",
type = "reconstructed",
}
m["phi-nag"] = {
"Agta Nagtipunan",
16966111,
"phi",
"Latn",
}
m["phi-pro"] = {
"Filipina Purba",
18204898,
"phi",
"Latn",
type = "reconstructed",
}
m["poz-abi"] = {
"Abai",
19570729,
"poz-san",
"Latn",
}
m["poz-bal"] = {
"Baliledo",
4850912,
"poz",
"Latn",
}
m["poz-btk-pro"] = {
"Bungku-Tolaki Purba",
116773724,
"poz-btk",
"Latn",
type = "reconstructed",
}
m["poz-cet-pro"] = {
"Melayu-Polinesia Tengah-Timur Purba",
2269883,
"poz-cet",
"Latn",
type = "reconstructed",
}
m["poz-hce-pro"] = {
"Halmahera-Cenderawasih Purba",
116773209,
"poz-hce",
"Latn",
type = "reconstructed",
}
m["poz-lgx-pro"] = {
"Lampung Purba",
116773222,
"poz-lgx",
"Latn",
type = "reconstructed",
}
m["poz-mcm-pro"] = {
"Melayu-Chamik Purba",
116773225,
"poz-mcm",
"Latn",
type = "reconstructed",
}
m["poz-mic-pro"] = {
"Mikronesia Purba",
111939079,
"poz-mic",
"Latn",
type = "reconstructed",
}
m["poz-mly-pro"] = {
"Melayik Purba",
98057728,
"poz-mly",
"Latn",
type = "reconstructed",
}
m["poz-msa-pro"] = {
"Melayu-Sumbawa Purba",
116773226,
"poz-msa",
"Latn",
type = "reconstructed",
}
m["poz-nes"] = {
"Nese",
2157412,
"poz-vnc",
"Latn",
}
m["poz-oce-pro"] = {
"Oceania Purba",
141741,
"poz-oce",
"Latn",
type = "reconstructed",
}
m["poz-pcc-pro"] = {
"Pasifik Tengah Purba",
111962726,
"poz-pcc",
"Latn",
type = "reconstructed",
}
m["poz-pep-pro"] = {
"Polinesia Timur Purba",
113988745,
"poz-pep",
"Latn",
type = "reconstructed",
}
m["poz-pnp-pro"] = {
"Polinesia Teras Purba",
113988746,
"poz-pnp",
"Latn",
type = "reconstructed",
}
m["poz-pol-pro"] = {
"Polinesia Purba",
1658709,
"poz-pol",
"Latn",
type = "reconstructed",
}
m["poz-pro"] = {
"Melayu-Polinesia Purba",
3832960,
"poz",
"Latn",
type = "reconstructed",
}
m["poz-sml"] = {
"Melayu Sarawak",
4251702,
"poz-mly",
"Latn, Arab",
}
m["poz-ssw-pro"] = {
"Sulawesi Selatan Purba",
116773279,
"poz-ssw",
"Latn",
type = "reconstructed",
}
m["poz-swa-pro"] = {
"Sarawak Utara Purba",
116773243,
"poz-swa",
"Latn",
type = "reconstructed",
}
m["poz-ter"] = {
"Melayu Terengganu",
4207412,
"poz-mly",
"Latn, Arab",
}
m["pqe-pro"] = {
"Melayu-Polinesia Timur Purba",
2269883,
"pqe",
"Latn",
type = "reconstructed",
}
m["pra-niy"] = {
"Prakrit Niya",
11991601,
"inc-mid",
"Khar",
ancestors = "inc-ash",
translit = "Khar-translit",
}
m["qfa-adm-pro"] = {
"Andaman Besar Purba",
116773756,
"qfa-adm",
"Latn",
type = "reconstructed",
}
m["qfa-bet-pro"] = {
"Be-Tai Purba",
116773193,
"qfa-bet",
"Latn",
type = "reconstructed",
}
m["qfa-cka-pro"] = {
"Chukotko-Kamchatka Purba",
7251837,
"qfa-cka",
"Latn",
type = "reconstructed",
}
m["qfa-hur-pro"] = {
"Hurro-Urartia Purba",
116773211,
"qfa-hur",
"Latn",
type = "reconstructed",
}
m["qfa-kad-pro"] = {
"Kadu Purba",
116773770,
"qfa-kad",
"Latn",
type = "reconstructed",
}
m["qfa-kms-pro"] = {
"Kam-Sui Purba",
55630682,
"qfa-kms",
"Latn",
type = "reconstructed",
}
m["qfa-kor-pro"] = {
"Korea Purba",
467883,
"qfa-kor",
"Latn",
type = "reconstructed",
}
m["qfa-kra-pro"] = {
"Kra Purba",
7251854,
"qfa-kra",
"Latn",
type = "reconstructed",
}
m["qfa-lic-pro"] = {
"Hlai Purba",
7251845,
"qfa-lic",
"Latn",
type = "reconstructed",
}
m["qfa-onb-pro"] = {
"Be Purba",
116773192,
"qfa-onb",
"Latn",
type = "reconstructed",
}
m["qfa-ong-pro"] = {
"Onga Purba",
116773801,
"qfa-ong",
"Latn",
type = "reconstructed",
}
m["qfa-tak-pro"] = {
"Kra-Dai Purba",
104901616,
"qfa-tak",
"Latn",
type = "reconstructed",
}
m["qfa-yen-pro"] = {
"Yenisei Purba",
27639,
"qfa-yen",
"Latn",
type = "reconstructed",
}
m["qfa-yuk-pro"] = {
"Yukaghir Purba",
116773294,
"qfa-yuk",
"Latn",
type = "reconstructed",
}
m["qwe-kch"] = {
"Kichwa",
1740805,
"qwe",
"Latn",
ancestors = "qu",
}
m["qwe-pro"] = {
"Quechua Purba",
5575757,
"qwe",
"Latn",
type = "reconstructed",
}
m["roa-ang"] = {
"Angevin",
56782,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-bbn"] = {
"Bourbonnais-Berrichon",
2899128,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-brg"] = {
"Bourguignon",
508332,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-can"] = {
"Cantabrian",
917021,
"roa-asl",
"Latn",
}
m["roa-cha"] = {
"Champenois",
430018,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-fcm"] = {
"Franc-Comtois",
510561,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-gal"] = {
"Gallo",
37300,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-gib"] = {
"Gallo-Italik Basilicata",
3094838,
"roa-git",
ancestors = "pms-old",
"Latn",
}
m["roa-gis"] = {
"Gallo-Italik Sicily",
2629019,
"roa-git",
"Latn",
ancestors = "pms-old",
}
m["roa-leo"] = {
"Leon",
34108,
"roa-asl",
"Latn",
}
m["roa-lor"] = {
"Lorrain",
671198,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-oca"] = {
"Catalonia Kuno",
15478520,
"roa-ocr",
"Latn",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla .. "·"},
}
m["roa-ole"] = {
"Leon Kuno",
125977465,
"roa-asl",
"Latn",
}
m["roa-ona"] = {
"Navarro-Aragon Kuno",
2736184,
"roa-nar",
"Latn",
}
m["roa-opt"] = {
"Galicia-Portugis Kuno",
1072111,
"roa-gap",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ},
}
m["roa-orl"] = {
"Orléanais",
28497058,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-poi"] = {
"Poitevin-Saintongeais",
514123,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["roa-tar"] = {
"Tarantino",
695526,
"roa-itr",
"Latn",
wikimedia_codes = "roa-tara",
}
m["sai-all"] = {
"Allentiac",
19570789,
"sai-hrp",
"Latn",
}
m["sai-and"] = { -- not to be confused with 'cbc' or 'ano'
"Andoquero",
16828359,
"sai-wit",
"Latn",
}
m["sai-ayo"] = {
"Ayomán",
16937754,
"sai-jir",
"Latn",
}
m["sai-bae"] = {
"Baenan",
3401998,
"qfa-unc", -- extinct, poorly attested; only known through 9 words
"Latn",
}
m["sai-bag"] = {
"Bagua",
5390321,
"qfa-unc", -- extinct, poorly attested; possibly Cariban
"Latn",
}
m["sai-bet"] = {
"Betoi",
926551,
"qfa-iso",
"Latn",
}
m["sai-bor-pro"] = {
"Bora Purba",
nil,
"sai-bor",
"Latn",
}
m["sai-cac"] = {
"Cacán",
945482,
"qfa-unc", -- extinct, poorly attested; no consensus on classification
"Latn",
}
m["sai-caq"] = {
"Caranqui",
2937753,
"sai-bar",
"Latn",
}
m["sai-car-pro"] = {
"Carib Purba",
116773196,
"sai-car",
"Latn",
type = "reconstructed",
}
m["sai-cat"] = {
"Catacao",
5051136,
"sai-ctc",
"Latn",
}
m["sai-cer-pro"] = {
"Cerrado Purba",
116773200,
"sai-cer",
"Latn",
type = "reconstructed",
}
m["sai-chi"] = {
"Chirino",
5390321,
"qfa-unc", -- extinct, only four words known; possibly related to Candoshi-Shapra (cbu)
"Latn",
}
m["sai-chn"] = {
"Chaná",
5072718,
"sai-crn",
"Latn",
}
m["sai-chp"] = {
"Chapacura",
5072884,
"sai-cpc",
"Latn",
}
m["sai-chr"] = {
"Charrua",
5086680,
"sai-crn",
"Latn",
}
m["sai-chu"] = {
"Churuya",
5118339,
"sai-guh",
"Latn",
}
m["sai-cje-pro"] = {
"Jê Tengah Purba",
116773198,
"sai-cje",
"Latn",
type = "reconstructed",
}
m["sai-cmg"] = {
"Comechingon",
6644203,
"qfa-unc", -- extinct, poorly attested; no consensus on classification
"Latn",
}
m["sai-cno"] = {
"Chono",
5104704,
"qfa-unc", -- extinct, poorly attested; no consensus on classification, possibly spurious
"Latn",
}
m["sai-cnr"] = {
"Cañari",
5055572,
"qfa-unc", -- extinct, poorly attested; possibly Chimuan or Barbacoan
"Latn",
}
m["sai-coe"] = {
"Coeruna",
6425639,
"sai-wit",
"Latn",
}
m["sai-col"] = {
"Colán",
5141893,
"sai-ctc",
"Latn",
}
m["sai-cop"] = {
"Copallén",
5390321,
"qfa-unc", -- extinct, only four words attested; possibly Cholonan
"Latn",
}
m["sai-crd"] = {
"Coroado Puri",
24191321,
"sai-mje",
"Latn",
}
m["sai-ctq"] = {
"Catuquinaru",
16858455,
"qfa-unc", -- extinct, poorly attested; vocabulary does not resemble other languages
"Latn",
}
m["sai-cul"] = {
"Culli",
2879660,
"qfa-unc", -- extinct, poorly attested; often considered an isolate
"Latn",
}
m["sai-cva"] = {
"Cueva",
5192644,
"qfa-unc", -- extinct, poorly attested; possibly Chocoan
"Latn",
}
m["sai-esm"] = {
"Esmeralda",
3058083,
"qfa-unc", -- extinct, poorly attested; possibly related to Yaruro
"Latn",
}
m["sai-ewa"] = {
"Ewarhuyana",
16898104,
nil,
"Latn",
}
m["sai-gam"] = {
"Gamela",
5403661,
"qfa-unc", -- extinct, poorly attested; possibly an isolate
"Latn",
}
m["sai-gay"] = {
"Gayón",
5528902,
"sai-jir",
"Latn",
}
m["sai-gmo"] = {
"Guamo",
5613495,
"qfa-unc", -- extinct; "Kaufman (1990) finds a connection with the Chapacuran languages convincing." [Wikipedia] Considered an isolate by Campbell (2024).
"Latn",
}
m["sai-gua"] = {
"Guachí",
5613172,
"sai-guc",
"Latn",
}
m["sai-gue"] = {
"Güenoa",
5626799,
"sai-crn",
"Latn",
}
m["sai-hau"] = {
"Haush",
3128376,
"sai-cho",
"Latn",
}
m["sai-jee-pro"] = {
"Jê Purba",
116773212,
"sai-jee",
"Latn",
type = "reconstructed",
}
m["sai-jko"] = {
"Jeikó",
6176527,
"sai-mje",
"Latn",
}
m["sai-jrj"] = {
"Jirajara",
6202966,
"sai-jir",
"Latn",
}
m["sai-kat"] = { -- contrast xoo, kzw, sai-xoc
"Katembri",
6375925,
"qfa-unc", -- extinct, poorly attested; "Kaufman (1990) has linked it with the nearly extinct Taruma, although this has not been accepted by other scholars." [Wikipedia]
"Latn",
}
m["sai-krp"] = {
"Karipuna (Panoan)",
136296616,
"sai-pan",
"Latn",
}
m["sai-mal"] = {
"Malalí",
6741212,
"sai-mje", -- considered the most divergent Maxakalían language (a subdivision of Macro-Jê), for which we have no entry
"Latn",
}
m["sai-mar"] = {
"Maratino",
6755055,
"qfa-unc", -- extinct, poorly attested; possibly Uto-Aztecan
"Latn",
}
m["sai-mat"] = {
"Matanawi",
6786047,
"qfa-unc", -- extinct; either an isolate or distantly related to the Muran languages; Campbell (2024) lists it as an isolate, Glottolog gives it as unclassified
"Latn",
}
m["sai-mcn"] = {
"Mocana",
3402048,
"qfa-unc", -- extinct, poorly attested; given as part of the Malibu languages (geographic grouping; not a clade)
"Latn",
}
m["sai-men"] = {
"Menien",
16890110,
"sai-mje",
"Latn",
}
m["sai-mil"] = {
"Millcayac",
19573012,
"sai-hrp",
"Latn",
}
m["sai-mlb"] = {
"Malibu",
134374036,
"qfa-unc", -- extinct, poorly attested; given as part of the Malibu languages (geographic grouping; not a clade)
"Latn",
}
m["sai-msk"] = {
"Masakará",
6782426,
"sai-mje",
"Latn",
}
m["sai-muc"] = {
"Mucuchí",
6931290,
nil, -- generally considered Timotean, for which we have no entry
"Latn",
}
m["sai-mue"] = {
"Muellama",
16886936,
"sai-bar",
"Latn",
}
m["sai-muz"] = {
"Muzo",
6644203,
"qfa-unc", -- extinct language of Colombia, poorly attested; may be Pijao (Cariban)
"Latn",
}
m["sai-mys"] = {
"Maynas",
16919393,
"sai-cah", -- per Campbell (2024); formerly considered unclassified
"Latn",
}
m["sai-nat"] = {
"Natú",
9006749,
"qfa-unc", -- extinct, poorly attested; "only Greenberg dares to classify [it]".[Wikipedia, quoting Moseley, Christopher; Asher, R. E.; Tait, Mary (1994), Atlas of the world's languages]
"Latn",
}
m["sai-nje-pro"] = {
"Jê Utara Purba",
116773245,
"sai-nje",
"Latn",
type = "reconstructed",
}
m["sai-opo"] = {
"Opón",
7099152,
"sai-car",
"Latn",
}
m["sai-oto"] = {
"Otomaco",
16879234,
"sai-otm",
"Latn",
}
m["sai-pal"] = {
"Palta",
3042978,
"qfa-unc", -- extinct, unclassified; possibly Chicham
"Latn",
}
m["sai-pam"] = {
"Pamigua",
5908689,
"sai-tin",
"Latn",
}
m["sai-par"] = {
"Paratió",
16890038,
"qfa-unc", -- extinct, poorly attested; possibly Xukuruan
"Latn",
}
m["sai-ptx"] = {
"Pataxó",
7144304,
"sai-mje",
"Latn",
}
m["sai-peb"] = {
"Peba",
3373890,
"sai-pey",
"Latn",
}
m["sai-pnz"] = {
"Panzaleo",
3123275,
"qfa-unc", -- extinct, unclassified; possibly Paezan
"Latn",
}
m["sai-prh"] = {
"Puruhá",
3410994,
"qfa-unc", -- extinct, poorly attested; possibly in a famil with Cañari
"Latn",
}
m["sai-ptg"] = {
"Patagón",
128807870,
"sai-tar", -- extinct, only known from 4 words, which suggest Cariban lineage (Campbell 2024)
"Latn",
}
m["sai-pur"] = {
"Purukotó",
7261622,
"sai-pem",
"Latn",
}
m["sai-pyg"] = {
"Payaguá",
7156643,
"sai-guc",
"Latn",
}
m["sai-pyk"] = {
"Pykobjê",
98113977,
"sai-nje",
"Latn",
}
m["sai-qmb"] = {
"Quimbaya",
7272043,
"qfa-unc", -- extinct, might not exist; few known words
"Latn",
}
m["sai-qtm"] = {
"Quitemo",
7272651,
"sai-cpc",
"Latn",
}
m["sai-rab"] = {
"Rabona",
6644203,
"qfa-unc", -- extinct, poorly attested, mostly plant names; possibly Candoshi-Shapra
"Latn",
}
m["sai-ram"] = {
"Ramanos",
16902824,
"qfa-unc", -- extinct, poorly attested, possibly an isolate; per Glottolog: "the minuscule wordlist ... shows no convincing resemblances to surrounding languages"
"Latn",
}
m["sai-sac"] = {
"Sácata",
5390321,
"qfa-unc", -- extinct, only 3 words known; possibly Candoshí or Arawakan
"Latn",
}
m["sai-san"] = {
"Sanaviron",
16895999,
"qfa-unc", -- extinct, unclassified; no consensus on classification
"Latn",
}
m["sai-sap"] = {
"Sapará",
7420922,
"sai-car",
"Latn",
}
m["sai-sec"] = {
"Sechura",
7442912,
"qfa-unc", -- extinct, poorly attested; possibly Catacaoan
"Latn",
}
m["sai-sin"] = {
"Sinúfana",
7525275,
"qfa-unc", -- moribund, poorly attested; possibly Chocoan
"Latn",
}
m["sai-sje-pro"] = {
"Jê Selatan Purba",
116773814,
"sai-sje",
"Latn",
type = "reconstructed",
}
m["sai-tab"] = {
"Tabancale",
5390321,
"qfa-unc", -- extinct, only 5 words known; no obvious connections, might be an isolate
"Latn",
}
m["sai-tal"] = {
"Tallán",
16910468,
"qfa-unc", -- extinct, poorly attested; might be Catacaoan
"Latn",
}
m["sai-tap"] = {
"Tapayuna",
30719984,
"sai-nje",
"Latn",
}
m["sai-tar-pro"] = {
"Taranoan Purba",
116773816,
"sai-tar",
"Latn",
type = "reconstructed",
}
m["sai-teu"] = {
"Teushen",
3519243,
"qfa-unc", -- probably extinct by the 1950's; possibly Chonan
"Latn",
}
m["sai-tim"] = {
"Timote",
7806995,
nil, -- possibly in a small Timotean family
"Latn",
}
m["sai-tpr"] = {
"Taparita",
7684460,
"sai-otm",
"Latn",
}
m["sai-trr"] = {
"Tarairiú",
7685313,
"qfa-unc", -- extinct, too poorly attested to classify
"Latn",
}
m["sai-wai"] = {
"Waitaká",
16918610,
"qfa-unc", -- extinct, possibly Purian
"Latn",
}
m["sai-way"] = {
"Wayumara",
7960726,
"sai-car",
"Latn",
}
m["sai-wit-pro"] = {
"Witotoan Purba",
116773823,
"sai-wit",
"Latn",
type = "reconstructed",
}
m["sai-wnm"] = {
"Wanham",
16879440,
"sai-cpc",
"Latn",
}
m["sai-xoc"] = { -- contrast xoo, kzw, sai-kat
"Xocó",
12953620,
"qfa-unc", -- extinct and poorly attested; not clear if one or three languages
"Latn",
}
m["sai-yao"] = {
"Yao (Amerika Selatan)",
16979655,
"sai-ven",
"Latn",
}
m["sai-yar"] = { -- not the same family as 'suy'
"Yarumá",
3505859,
"sai-pek",
"Latn",
}
m["sai-yri"] = {
"Yuri",
2669157,
"sai-tyu",
"Latn",
}
m["sai-yup"] = {
"Yupua",
8061430,
"sai-tuc",
"Latn",
}
m["sai-yur"] = {
"Yurumanguí",
1281291,
"qfa-unc", -- extinct, too poorly attested to classify
"Latn",
}
m["sal-pro"] = {
"Salish Purba",
116773269,
"sal",
"Latn",
type = "reconstructed",
}
m["sdv-daj-pro"] = {
"Daju Purba",
116773739,
"sdv-daj",
"Latn",
type = "reconstructed",
}
m["sdv-eje-pro"] = {
"Jebel Timur Purba",
116773751,
"sdv-eje",
"Latn",
type = "reconstructed",
}
m["sdv-nil-pro"] = {
"Nilotik Purba",
116773794,
"sdv-nil",
"Latn",
type = "reconstructed",
}
m["sdv-nyi-pro"] = {
"Nyima Purba",
116773796,
"sdv-nyi",
"Latn",
type = "reconstructed",
}
m["sdv-tmn-pro"] = {
"Taman Purba",
116773815,
"sdv-tmn",
"Latn",
type = "reconstructed",
}
m["sel-nor"] = {
"Selkup Utara",
30304565,
"sel",
"Cyrl",
translit = "sel-nor-translit",
}
m["sel-pro"] = {
"Selkup Purba",
128884235,
"sel",
"Latn",
type = "reconstructed",
}
m["sel-sou"] = {
"Selkup Selatan",
30304639,
"sel",
"Cyrl",
translit = "sel-sou-translit",
}
m["sem-amm"] = {
"Ammon",
279181,
"sem-can",
"Phnx",
-- Phnx translit in [[Module:scripts/data]]
}
m["sem-amo"] = {
"Amor",
35941,
"sem-nwe",
"Xsux, Latn",
}
m["sem-cha"] = {
"Chaha",
35543,
"sem-eth",
"Ethi",
translit = "Ethi-translit",
}
m["sem-dad"] = {
"Dadan",
21838040,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-dum"] = {
"Dumait",
128810397,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-has"] = {
"Hasait",
3541433,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-his"] = {
"Hisma",
22948260,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-mhr"] = {
"Muher",
33743,
"sem-eth",
"Latn",
}
m["sem-pro"] = {
"Samiah Purba",
1658554,
"sem",
"Latn",
type = "reconstructed",
}
m["sem-saf"] = {
"Safait",
472586,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-sam"] = {
"Samal",
85847147,
"sem-nwe",
"Phnx",
-- Phnx translit in [[Module:scripts/data]]
}
m["sem-srb"] = {
"Arab Selatan Kuno",
35025,
"sem-osa",
"Sarb",
-- Sarb translit in [[Module:scripts/data]]
}
m["sem-tay"] = {
"Tayman",
24912301,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-tha"] = {
"Thamud",
843030,
"sem-cen",
"Narb",
-- Narb translit in [[Module:scripts/data]]
}
m["sem-wes-pro"] = {
"Samiah Barat Purba",
98021726,
"sem-wes",
"Latn",
type = "reconstructed",
}
m["sio-pro"] = { -- NB this is not Proto-Siouan-Catawban 'nai-sca-pro'
"Sioux Purba",
34181,
"sio",
"Latn",
type = "reconstructed",
}
m["sit-aao-pro"] = {
"Naga Tengah Purba",
nil,
"sit-aao",
"Latn",
type = "reconstructed",
}
m["sit-bai-pro"] = {
"Bai Purba",
nil,
"sit-bai",
"Latn",
type = "reconstructed",
}
m["sit-ban"] = {
"Bangru",
56071779,
"sit-hrs",
"Latn",
}
m["sit-bdi-pro"] = {
"Bodish Purba",
nil,
"sit-bdi",
"Latn",
type = "reconstructed",
}
m["sit-bok"] = {
"Bokar",
4938727,
"sit-tan",
"Latn, Tibt",
override_translit = true,
-- Tibt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["sit-cai"] = {
"Caijia",
5017528,
"sit-cln",
"Latn"
}
m["sit-cha"] = {
"Chairel",
5068066,
"sit-luu",
"Latn",
}
m["sit-ers-pro"] = {
"Ersu Purba",
nil,
"sit-ers",
"Latn",
type = "reconstructed",
}
m["sit-hrs-pro"] = {
"Hrusish Purba",
116773762,
"sit-hrs",
"Latn",
type = "reconstructed",
}
m["sit-jap"] = {
"Japhug",
3162245,
"sit-egy",
"Latn",
}
m["sit-kha-pro"] = {
"Kham Purba",
116773773,
"sit-kha",
"Latn",
type = "reconstructed",
}
m["sit-khb-pro"] = {
"Kho-Bwa Purba",
nil,
"sit-khb",
"Latn",
type = "reconstructed",
}
m["sit-khp-pro"] = {
"Puroik Purba",
nil,
"sit-khb",
"Latn",
type = "reconstructed",
}
m["sit-khw-pro"] = {
"Kho-Bwa Barat Purba",
nil,
"sit-khw",
"Latn",
type = "reconstructed",
}
m["sit-kon-pro"] = {
"Naga Utara Purba",
nil,
"sit-kon",
"Latn",
type = "reconstructed",
}
m["sit-liz"] = {
"Lizu",
6660653,
"sit-ers",
"Latn", -- and Ersu Shaba
}
m["sit-lnj"] = {
"Longjia",
17096251,
"sit-cln",
"Latn"
}
m["sit-lrn"] = {
"Luren",
16946370,
"sit-cln",
"Latn"
}
m["sit-luu-pro"] = {
"Luish Purba",
116773783,
"sit-luu",
"Latn",
type = "reconstructed",
}
m["sit-nas-pro"] = {
"Naish Purba",
nil,
"sit-nas",
"Latn",
type = "reconstructed",
}
m["sit-prn"] = {
"Puiron",
7259048,
"sit-zem",
}
m["sit-pro"] = {
"Sino-Tibet Purba",
24839178,
"sit",
"Latn",
type = "reconstructed",
}
m["sit-sit"] = {
"Situ",
19840830,
"sit-egy",
"Latn",
}
m["sit-tam-pro"] = {
"Tamang Purba",
117469295,
"sit-tam",
"Latn",
type = "reconstructed",
}
m["sit-tan-pro"] = {
"Tani Purba",
116773284,
"sit-tan",
"Latn", -- needs verification
type = "reconstructed",
}
m["sit-tgm"] = {
"Tangam",
17041370,
"sit-tan",
"Latn",
}
m["sit-tng-pro"] = {
"Tangkhul Purba",
nil,
"sit-tng",
"Latn",
type = "reconstructed"
}
m["sit-tos"] = {
"Tosu",
7827899,
"sit-ers",
"Latn", -- also Ersu Shaba
}
m["sit-tsh"] = {
"Tshobdun",
19840950,
"sit-egy",
"Latn",
}
m["sit-zbu"] = {
"Zbu",
19841106,
"sit-egy",
"Latn",
}
m["sla-pro"] = {
"Slavik Purba",
747537,
"sla",
"Latn",
type = "reconstructed",
strip_diacritics = {
remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve,
remove_exceptions = {'ś'},
},
sort_key = {
from = {"č", "ď", "ě", "ę", "ь", "ľ", "ň", "ǫ", "ř", "š", "ś", "ť", "ъ", "ž"},
to = {"c²", "d²", "e²", "e³", "i²", "l²", "nj", "o²", "r²", "s²", "s³", "t²", "u²", "z²"},
}
}
m["smi-pro"] = {
"Sami Purba",
7251862,
"smi",
"Latn",
type = "reconstructed",
sort_key = {
from = {"ā", "č", "δ", "[ëē]", "ŋ", "ń", "ō", "š", "θ", "%([^()]+%)"},
to = {"a", "c²", "d", "e", "n²", "n³", "o", "s²", "t²"}
},
}
m["son-pro"] = {
"Songhai Purba",
116773277,
"son",
"Latn",
type = "reconstructed",
}
m["sqj-pro"] = {
"Albania Purba",
18210846,
"sqj",
"Latn",
type = "reconstructed",
}
m["ssa-klk-pro"] = {
"Kuliak Purba",
116773779,
"ssa-klk",
"Latn",
type = "reconstructed",
}
m["ssa-kom-pro"] = {
"Koma Purba",
116773775,
"ssa-kom",
"Latn",
type = "reconstructed",
}
m["ssa-pro"] = {
"Nilo-Sahara Purba",
116773236,
"ssa",
"Latn",
type = "reconstructed",
}
m["syd-pro"] = {
"Samoyed Purba",
7251863,
"syd",
"Latn",
type = "reconstructed",
}
m["tai-pro"] = {
"Tai Purba",
6583709,
"tai",
"Latn",
type = "reconstructed",
}
m["tai-swe-pro"] = {
"Tai Barat Daya Purba",
116773280,
"tai-swe",
"Latn",
type = "reconstructed",
}
m["tbq-bdg-pro"] = {
"Bodo-Garo Purba",
116773195,
"tbq-bdg",
"Latn",
type = "reconstructed",
}
m["tbq-blg"] = {
"Bailang",
2879843,
"tbq-lob",
"Hani",
sort_key = "Hani-sortkey",
}
m["tbq-brm-pro"] = {
"Burma Purba",
nil,
"tbq-brm",
"Latn",
type = "reconstructed",
}
m["tbq-gkh"] = {
"Gokhy",
5578069,
"tbq-sil",
"Latn",
}
m["tbq-kuk-pro"] = {
"Kuki-Chin Purba",
116773220,
"tbq-kuk",
"Latn",
type = "reconstructed",
}
m["tbq-lal-pro"] = {
"Lalo Purba",
116773781,
"tbq-lal",
"Latn",
type = "reconstructed",
}
m["tbq-laz"] = {
"Laze",
17007626,
"sit-nas",
"Latn",
}
m["tbq-lob-pro"] = {
"Lolo-Burma Purba",
116773224,
"tbq-lob",
"Latn",
type = "reconstructed",
}
m["tbq-lol-pro"] = {
"Lolo Purba",
7251855,
"tbq-lol",
"Latn",
type = "reconstructed",
}
m["tbq-mil"] = {
"Milang",
6850761,
"sit-gsi",
"Deva, Latn",
}
m["tbq-mor"] = {
"Moran",
6909216,
"tbq-bdg",
"Latn",
}
m["tbq-ngo"] = {
"Ngochang",
56582,
"tbq-brm",
"Latn",
}
-- tbq-pro is now etymology-only
m["trk-dkh"] = {
"Dukhan",
12809273,
"trk-ssb",
"Latn, Cyrl, Mong",
-- Mong translit, display_text and strip_diacritics in [[Module:scripts/data]]
}
-- As described in Mahmud al-Kashgari's 11th century ''Dīwān Lughāt al-Turk''.
m["trk-eog"] = {
"Oghuz Kuno Awal",
nil,
"trk-ogz",
"Arab",
strip_diacritics = {Arab = "ar-stripdiacritics"},
}
m["trk-oat"] = {
"Turki Anatolia Kuno",
7083390,
"trk-ogz",
"Arab",
strip_diacritics = {Arab = "ar-stripdiacritics"},
ancestors = "trk-eog",
}
m["trk-pro"] = {
"Turkik Purba",
3657773,
"trk",
"Latn",
type = "reconstructed",
standard_chars = {
Latn = " ()-abdegiklmnoprstuxyzïöüāčēīĺŋōŕšūǖȫẹ" .. c.macron,
}
}
m["tup-gua-pro"] = {
"Tupi-Guarani Purba",
116773288,
"tup-gua",
"Latn",
type = "reconstructed",
}
m["tup-kab"] = {
"Kabishiana",
15302988,
"tup",
"Latn",
}
m["tup-kaw"] = {
"Kawahiva",
6346712,
"tup-gua",
"Latn",
}
m["tup-pro"] = {
"Tupi Purba",
10354700,
"tup",
"Latn",
type = "reconstructed",
}
m["tuw-alk"] = {
"Alchuka",
113553616,
"tuw-jrc",
"Latn, Hans",
sort_key = {Hans = "Hani-sortkey"},
}
m["tuw-bal"] = {
"Bala",
86730632,
"tuw-jrc",
"Latn, Hans",
sort_key = {Hans = "Hani-sortkey"},
}
m["tuw-kkl"] = {
"Kyakala",
118875708,
"tuw-jrc",
"Latn, Hans",
sort_key = {Hans = "Hani-sortkey"},
}
m["tuw-kli"] = {
"Kili",
6406892,
"tuw-ewe",
"Cyrl",
}
m["tuw-pro"] = {
"Tungus Purba",
85872335,
"tuw",
"Latn",
type = "reconstructed",
}
m["tuw-sol"] = {
"Solon",
30004,
"tuw-ewe",
}
m["urj-fin-pro"] = {
"Finnik Purba",
11883720,
"urj-fin",
"Latn",
type = "reconstructed",
}
m["urj-koo"] = {
"Komi Kuno",
86679962,
"kv",
"Perm, Cyrs",
translit = "urj-koo-translit",
-- Cyrs strip_diacritics, sort_key in [[Module:scripts/data]]; previously, Cyrs strip_diacritics not present
}
m["urj-kuk"] = {
"Kukkuzi",
107410460,
"urj-fin",
"Latn",
ancestors = "vot",
}
m["urj-kya"] = {
"Komi-Yazva",
2365210,
"kv",
"Cyrl",
translit = "kv-translit",
override_translit = true,
strip_diacritics = {remove_diacritics = c.acute},
}
m["urj-mdv-pro"] = {
"Mordvinik Purba",
116773232,
"urj-mdv",
"Latn",
type = "reconstructed",
}
m["urj-prm-pro"] = {
"Permik Purba",
116773257,
"urj-prm",
"Latn",
type = "reconstructed",
}
m["urj-pro"] = {
"Uralik Purba",
288765,
"urj",
"Latn",
type = "reconstructed",
}
m["urj-ugr-pro"] = {
"Ugrik Purba",
156631,
"urj-ugr",
"Latn",
type = "reconstructed",
}
m["xnd-pro"] = {
"Na-Dene Purba",
116773233,
"xnd",
"Latn",
type = "reconstructed",
}
m["xgn-pro"] = {
"Mongol Purba",
2493677,
"xgn",
"Latn",
type = "reconstructed",
sort_key = {
from = {"č", "i", "ï", "ǰ", "ŋ", "ö", "š", "ü"},
to = {"c", "i" .. p[1], "i", "j", "n" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1]},
},
}
m["yok-bvy"] = {
"Yokuts Buena Vista",
4985474,
"yok",
"Latn",
}
m["yok-dly"] = {
"Yokuts Delta",
70923266,
"yok",
"Latn",
}
m["yok-gsy"] = {
"Yokuts Gashowu",
3098708,
"yok",
"Latn",
}
m["yok-kry"] = {
"Yokuts Sungai Kings",
6413014,
"yok",
"Latn",
}
m["yok-nvy"] = {
"Yokuts Lembah Utara",
85789777,
"yok",
"Latn",
}
m["yok-ply"] = {
"Yokuts Palewyami",
2387391,
"yok",
"Latn",
}
m["yok-svy"] = {
"Yokuts Lembah Selatan",
12642473,
"yok",
"Latn",
}
m["yok-tky"] = {
"Yokuts Tule-Kaweah",
7851988,
"yok",
"Latn",
}
m["ypk-pro"] = {
"Yupik Purba",
116773295,
"ypk",
"Latn",
type = "reconstructed",
}
m["yrk-for"] = {
"Nenets Hutan",
1295107,
"yrk",
"Cyrl",
translit = "yrk-for-translit",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.macron .. c.breve .. c.dotabove},
}
m["yrk-tun"] = {
"Nenets Tundra",
36452,
"yrk",
"Cyrl",
strip_diacritics = {
from = {"ӑ", "а̄", "э̇", "ӣ", "ы̄", "ӯ", "ю̄", "я̆", "я̄"},
to = {"а", "а", "э", "и", "ы", "у", "ю", "я", "я"},
},
translit = "yrk-tun-translit",
}
m["zhx-min-pro"] = {
"Min Purba",
19646347,
"zhx-min",
"Latn",
type = "reconstructed",
}
m["zhx-sht"] = {
"Tuhua Shaozhou",
1920769,
"zhx",
"Nshu, Hants",
generate_alternants = "zh-generatealternants",
sort_key = {Hani = "Hani-sortkey"},
}
m["zhx-sic"] = {
"Sichuan",
2278732,
"zhx-man",
"Hants",
generate_alternants = "zh-generatealternants",
translit = "zh-translit",
sort_key = "Hani-sortkey",
}
m["zhx-tai"] = {
"Taishan",
2208940,
"zhx-yue",
"Hants",
generate_alternants = "zh-generatealternants",
translit = "zh-translit",
sort_key = "Hani-sortkey",
}
m["zle-ono"] = {
"Novgorod Kuno",
162013,
"zle",
"Cyrs, Glag",
translit = {Cyrs = "Cyrs-translit", Glag = "Glag-translit"},
-- Cyrs strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["zle-ort"] = {
"Ruthenia Kuno",
13211,
"zle",
"Arab, Cyrs, Latn",
ancestors = "orv",
translit = {
Cyrs = "zle-ort-translit",
Arab = "zle-ort-Arab-translit",
},
strip_diacritics = {
Cyrs = {
remove_diacritics = m_langdata.chars_substitutions["Cyrs_remove_diacritics"],
remove_exceptions = {"Ї", "ї"},
},
Arab = "ar-stripdiacritics",
},
-- Cyrs sort_key in [[Module:scripts/data]]
}
m["zls-chs"] = {
"Slav Gereja",
33251,
"zls",
"Cyrs, Glag, Latn",
ancestors = "cu",
translit = {
Cyrs = "Cyrs-translit",
Glag = "Glag-translit"
},
-- Cyrs strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["zlw-ocs"] = {
"Czech Kuno",
593096,
"zlw",
"Latn",
}
m["zlw-opl"] = {
"Poland Kuno",
149838,
"zlw-lch",
"Latn",
strip_diacritics = {remove_diacritics = c.ringabove},
}
m["zlw-osk"] = {
"Slovak Kuno",
12776676,
"zlw",
"Latn",
}
m["zlw-slv"] = {
"Slovincia",
36822,
"zlw-pom",
"Latn",
strip_diacritics = {remove_diacritics = c.macron .. c.breve},
}
-- Kod tambahan untuk bahasa-bahasa yang digunakan di Malaysia, yang tidak wujud di Wikikamus Bahasa Inggeris
m["zlm-coa"] = {
"Melayu Terengganu Pesisir",
4207412,
"poz-mly",
"Latn, Arab",
}
m["zlm-pah"] = {
"Melayu Pahang",
7310370,
"poz-mly",
"Latn",
}
return require("Module:languages").finalizeData(m, "language")
sn5xe3e5p1nmso8wplgnkun153dt75k
Modul:gender and number/data
828
33823
375930
375354
2026-09-26T08:06:09Z
SNN95
2113
kemaskini dan terjemah. "Genus" bukanlah "gender/jantina"
375930
Scribunto
text/plain
local data = {}
local insert = table.insert
-- Senarai semua kemungkinan "bahagian" yang mana sesuatu spesifikasi boleh dibuat. Untuk setiap bahagian, kami menyenaraikan kelasnya
-- (jantina, kebernyawaan, dll.), kategori yang berkaitan (jika ada) dan bentuk paparan. Dalam spesifikasi jantina/bilangan yang diberikan, hanya
-- satu bahagian daripada setiap kelas dibenarkan. `display` ialah cara kod dipaparkan kepada pengguna dan kebiasaannya patut dibalut
-- dalam <abbr title="tooltip">...</abbr> dengan petua alat penerangan. Jika tidak, ia akan dibalut secara automatik dengan
-- cara ini. Jika `req` adalah benar, kategori "Permintaan untuk TYPE dalam entri LANG" akan dijana, kecuali untuk kod "?",
-- yang mempunyai kes khas; TYPE ialah "jantina" melainkan POS ialah "kata kerja", dalam kes itu ia ialah "aspek".
data.codes = {
["?"] = {type = "other", req = true, display = '<abbr title="jantina tidak lengkap">?</abbr>'},
-- BAIKI: Yang berikut sepatutnya sama ada dihapuskan untuk memihak kepada g! atau ditukar kepada bentuk umum "jantina/bilangan tidak diperakui".
["?!"] = {type = "other", display = "jantina tidak diperakui"},
-- Jantina
["m"] = {type = "gender", cat = "POS maskulin", display = '<abbr title="jantina maskulin">m</abbr>'},
["f"] = {type = "gender", cat = "POS feminin", display = '<abbr title="jantina feminin">f</abbr>'},
["n"] = {type = "gender", cat = "POS neuter", display = '<abbr title="jantina neuter">n</abbr>'},
["c"] = {type = "gender", cat = "POS jantina umum", display = '<abbr title="jantina umum">c</abbr>'},
["gneut"] = {type = "gender", cat = "POS neutral jantina", display = "neutral jantina"},
["g!"] = {type = "gender", display = "jantina tidak diperakui"},
["g?"] = {type = "gender", req = true, display = "jantina tidak dinyatakan"},
-- Kehidupan
-- Hidup = sama ada haiwan atau manusia (untuk bahasa Rusia, dll.)
["an"] = {type = "animacy", cat = "POS hidup", display = '<abbr title="hidup">hid</abbr>'},
["in"] = {type = "animacy", cat = "POS tidak hidup", display = '<abbr title="tidak hidup">t.hid</abbr>'},
-- Haiwan (untuk bahasa Ukraine, Belarus, Poland, dll.)
["anml"] = {type = "animacy", cat = "POS haiwan", display = "haiwan"},
-- Manusia (untuk bahasa Ukraine, Belarus, Poland, dll.)
["pr"] = {type = "animacy", cat = "POS manusia", display = '<abbr title="manusia">manu</abbr>'},
["np"] = {type = "animacy", cat = "POS bukan manusia", display = '<abbr title="bukan manusia">b.manu</abbr>'},
["an!"] = {type = "animacy", display = "kebernyawaan tidak diperakui"},
["an?"] = {type = "animacy", req = true, display = "kebernyawaan tidak dinyatakan"},
-- Ketentuan
["def"] = {type = "definiteness", cat = "POS tentu", display = '<abbr title="tentu">ten</abbr>'},
["indef"] = {type = "definiteness", cat = "POS tidak tentu", display = '<abbr title="tidak tentu">t.ten</abbr>'},
-- Viriliti (untuk bahasa Poland)
["vr"] = {type = "virility", cat = "POS viril", display = '<abbr title="viril (= maskulin manusia)">vir</abbr>'},
["nv"] = {type = "virility", cat = "POS bukan viril", display = '<abbr title="bukan viril (= selain maskulin manusia)">b.vir</abbr>'},
-- Bilangan
["s"] = {type = "number", display = '<abbr title="bilangan tunggal">sg</abbr>'},
["d"] = {type = "number", cat = "dualia tantum", display = '<abbr title="bilangan duaan">b.dua</abbr>'},
["p"] = {type = "number", cat = "pluralia tantum", display = '<abbr title="bilangan jamak">b.jam</abbr>'},
["num!"] = {type = "number", display = "bilangan tidak diperakui"},
["num?"] = {type = "number", req = true, display = "bilangan tidak dinyatakan"},
-- Kelayakan kata kerja
["impf"] = {type = "aspect", cat = "POS tidak sempurna", display = '<abbr title="aspek tidak sempurna">t.semp</abbr>'},
["pf"] = {type = "aspect", cat = "POS sempurna", display = '<abbr title="aspek sempurna">semp</abbr>'},
["asp!"] = {type = "aspect", display = "aspek tidak diperakui"},
["asp?"] = {type = "aspect", req = true, display = "aspek tidak dinyatakan"},
}
-- Kod gabungan yang setara dengan memberikan berbilang spesifikasi. `mf` adalah sama dengan menentukan dua spesifikasi yang berasingan,
-- satu dengan `m` di dalamnya dan satu lagi dengan `f`. `mfbysense` adalah serupa tetapi digunakan untuk kata nama yang boleh sama ada maskulin
-- atau feminin mengikut sama ada ia merujuk kepada makhluk maskulin atau feminin.
local combinations = {
["biasp"] = {codes = {"impf", "pf"}},
["anin"] = {codes = {"an", "in"}}, -- "bianimate" tidak wujud sebagai istilah linguistik
}
for _, comb in ipairs{"mf", "mn", "fm", "fn", "cn", "nm", "nf", "nc", "mfn", "mnf", "fmn", "fnm", "nmf", "nfm"} do
local codes = {}
for ch in comb:gmatch(".") do
insert(codes, ch)
end
combinations[comb] = {codes = codes}
combinations[comb .. "equiv"] = {codes = codes, display = '<abbr title="jantina berbeza tidak menjejaskan makna">makna sama</abbr>'}
if comb == "mf" or comb == "fm" then
combinations[comb .. "bysense"] = {codes = codes, cat = "POS maskulin dan feminin mengikut erti",
display = '<abbr title="mengikut jantina rujukan">mengikut erti</abbr>'}
end
end
data.combinations = combinations
-- Kategori apabila berbilang kod jantina/bilangan daripada jenis tertentu berlaku dalam spesifikasi yang berbeza (dua atau lebih
-- daripada jenis yang sama tidak boleh wujud dalam satu spesifikasi).
data.multicode_cats = {
["gender"] = "POS dengan berbilang jantina",
["animacy"] = "POS dengan berbilang kebernyawaan",
["aspect"] = "POS dwiaspek",
}
return data
36ydq7z2s7gaeh08joza8mun32oydwt
tugal
0
37613
376197
285310
2026-09-26T09:34:26Z
Elvaretta Vito
11512
376197
wikitext
text/x-wiki
==Bahasa Bajau Sama ==
===Kata nama===
{{inti|bdr|kata nama}}
# tugal
==Bahasa Iban ==
===Kata nama===
{{inti|iba|kata nama}}
# alat untuk membuat lubang untuk menanam anak padi
==Bahasa Melayu ==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Tugal <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Esok kito mulai menugal di ladang ujung.|Besok kita mulai melubangi tanah untuk tanam benih di ladang ujung.}}
5f46rm6qc13iauu2azdtinou0d6p0nx
kojo
0
38037
375917
331097
2026-09-26T07:55:14Z
Muhammad Abdi Ramadhan
9873
/* Kata kerja */
375917
wikitext
text/x-wiki
==Bahasa Bugis==
===Kurus===
====Kata nama====
{{inti|bug|kata nama}}
kojo la'de
kurus sangat
==Bahasa Melayu Negeri Sembilan==
===Kata kerja===
{{inti|zmi|kata kerja}}
# kerja; bekerja
==Bahasa Melayu==
===kojo===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} kerja <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ko aku sodang kojo.|ini aku sedang kerja.}}
6av6hkvxkfxj8ymycgv1r1ty9rbjutz
lapa
0
39346
375906
221033
2026-09-26T07:32:31Z
Muhammad Abdi Ramadhan
9873
/* Bahasa Melayu Negeri Sembilan */
375906
wikitext
text/x-wiki
==Bahasa Iban==
===Takrifan===
====Kata tanya====
{{inti|iba|kata tanya}}
# kenapa
#: {{cp|iba|'''Lapa''' enggau nuan tu Keling ?|'''Kenapa''' dengan kamu ini Keling ?}}
==Bahasa Melayu Negeri Sembilan==
===Takrifan===
====Kata sifat====
{{inti|zmi|kata sifat}}
#{{l|ms|lapar}}
==Bahasa Melayu==
===lapa===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku lapa bona ha.|aku sangat lapar.}}
fh6bwguhhcp2692rh6bfb5wemgldu28
Modul:labels/doc
828
41360
375905
155200
2026-09-26T07:25:10Z
SNN95
2113
375905
wikitext
text/x-wiki
{{label/example|grc:Attic|ms:Loteng|caption=Label khusus untuk {{code|lua|"grc"}} (Yunani Purba)|header=1}}
1lw5f5r0dcyhxpbgqh119lc45ymnq45
osah
0
42608
376052
246093
2026-09-26T08:45:28Z
Robiyatuladawiyah05
11514
/* Adverba */
376052
wikitext
text/x-wiki
==Bahasa Melayu Negeri Sembilan==
===Takrifan===
====Adverba====
{{inti|zmi|adverba}}
# memang; betul {{cp|zmi|osah mada eh kucing ni, nangkap tikuih pon tak ghoti.|Kucing ini bodoh betul. Tangkap tikus pun tidak tahu.}}
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Pasti <!--Pasti-->
#: {{cp|ms|memang osah.|memang pasti.}}
p45w45uklys08b2husi4piv64miv3vh
kubak
0
43554
376183
317459
2026-09-26T09:26:09Z
Thurama
11516
376183
wikitext
text/x-wiki
==Bahasa Bajau Sama ==
===Kata sifat===
{{inti|bdr|kata sifat }}
# usang
==Bahasa Urak Lawoi'==
===Tarkifan===
====Kata nama====
{{inti|urk|kata nama}}
# [[tasik]]
# [[kolam]]
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Pekanbaru}} kupas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
c1y271kmradugr19vq5rkeeznxdfmpj
bilo
0
44525
376098
160449
2026-09-26T08:57:00Z
Robiyatuladawiyah05
11514
/* Takrifan */
376098
wikitext
text/x-wiki
==Bahasa Melayu==
===Takrifan===
====Kata tanya====
{{inti|ms|kata tanya}}
# {{lb|ms|Serdang Bedagai}} kapan
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Kapan <!--Kapan-->
#: {{cp|ms|bilo poi?.|kapan pergi?.}}
me4evvj8nkvs4uv0i0bg9tabo1ecg1z
ondak
0
44550
376092
339533
2026-09-26T08:55:10Z
Robiyatuladawiyah05
11514
/* Kata sifat */
376092
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{inti|ms|kata sifat}}
# {{lb|ms|Riau}} mau
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Mau <!--Mau-->
#: {{cp|ms|aku ondak poi.|aku mau pergi.}}
9k708joqvtm5lsljgftj9y7tf4hwyqr
lamo
0
44565
376088
338577
2026-09-26T08:54:21Z
Robiyatuladawiyah05
11514
/* Kata sifat */
376088
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{inti|ms|kata sifat}}
# {{lb|ms|Serdang Bedagai}} lama
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Lama <!--Lama-->
#: {{cp|ms|lamo tuan.|lama kamu.}}
5tllizk40t3h3ic0fuh0wid3ka3m1lz
bonang
0
44586
376014
336640
2026-09-26T08:35:29Z
Muhammad Abdi Ramadhan
9873
/* Kata benda */
376014
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{inti|ms|kata benda}}
# {{lb|ms|Serdang Bedagai}} benang
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan hulu}} benang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|dak ado bonang aku noh.|benangku tidak ada.}}
10llapaisk6zdhyrlep1d0s13g5viwy
376019
376014
2026-09-26T08:37:00Z
Muhammad Abdi Ramadhan
9873
/* Kata benda */
376019
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{inti|ms|kata benda}}
# {{lb|ms|Serdang Bedagai}} benang
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan hulu}} benang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|dak ado bonang aku noh.|benangku tidak ada.}}
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} berenag <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku indo pandai bonang noh.|aku tidak bisa berenang}}
rs5yi5plezvgzzonexrw28e2mhv37fp
togak
0
44602
376065
328817
2026-09-26T08:47:43Z
Robiyatuladawiyah05
11514
/* Kata sifat */
376065
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{inti|ms|kata sifat}}
# {{lb|ms|Riau}} tegak
==Bahasa Minangkabau==
===Kata sifat===
{{inti|min|kata sifat}}
# {{lb|min|Payakumbuh}} [[tegak]]
#:{{cp|min|ayah togak di topi tobek|ayah tegah di tepian tebat}}
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Tegak <!--Tegak-->
#: {{cp|ms|moh togak.|ayo tegak.}}
ddavrggx3cv1zm16wqojvk03ufsh7wz
ponah
0
44681
376066
340271
2026-09-26T08:48:35Z
Robiyatuladawiyah05
11514
/* Kata kerja */
376066
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{inti|ms|kata kerja}}
# {{lb|ms|Batu bara}} pernah
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Pernah <!--Pernah-->
#: {{cp|ms|dah ponah.|sudah pernah.}}
gmodqhlo34manejwnakvacfw6d0gx7m
tangkok
0
44816
376056
329499
2026-09-26T08:46:10Z
SY Reski
10853
376056
wikitext
text/x-wiki
==Bahasa Kensiu==
===Kata nama===
{{inti|kns|kata nama}}
# katak
#:'''Tangkok''' on nembek.
#::'''Katak''' itu besar.
===Sebutan===
*{{penyempangan|kns|tang|kok}}
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} tangkok <!--tangkap-->
#:{{cp|ms|inyo poi manangkok boluik .|dia pergi menangkap belut.}}
a8px7iak750d1gdt91vi2phklu3wshz
miso
0
45500
376147
290065
2026-09-26T09:12:08Z
Thurama
11516
376147
wikitext
text/x-wiki
==Bahasa Kadazan==
===Kata kerja===
{{inti|kzj|kata kerja}}
# berpadu
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|pekanbary}} Mie Soto; olahan mie, bihun, suiran ayam dipadukan dengan kuah soto <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
1bsujqs2pb22e7avn42fdpab60l13m9
376152
376147
2026-09-26T09:13:02Z
Thurama
11516
/* Kata benda */
376152
wikitext
text/x-wiki
==Bahasa Kadazan==
===Kata kerja===
{{inti|kzj|kata kerja}}
# berpadu
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|pekanbaru}} Mie Soto; olahan mie, bihun, suiran ayam dipadukan dengan kuah soto <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
rp25l9r9p3bee9bu90iw956hyl4eqg3
376153
376152
2026-09-26T09:13:45Z
Thurama
11516
/* Kata benda */
376153
wikitext
text/x-wiki
==Bahasa Kadazan==
===Kata kerja===
{{inti|kzj|kata kerja}}
# berpadu
==Bahasa Melayu==
===Kata benda===
{{lb|ms|miso}}
# {{lb|ms|pekanbaru}} Mie Soto; olahan mie, bihun, suiran ayam dipadukan dengan kuah soto <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
a38fi7b4zd0gfdp1e4k80g8jsy8knu3
Löwe
0
49336
375974
322687
2026-09-26T08:24:02Z
Muhammad Abdi Ramadhan
9873
/* Kata nama */
375974
wikitext
text/x-wiki
==Bahasa Jerman==
{{Wikipedia|lang=de}}
===Kata nama===
{{de-noun|m.weak}}
# [[singa]]
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} lebar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|lanpangan tu lowe|lapangan itu lebar}}
===Etimologi===
{{dercat|de|la|grc|sem}}
Daripada {{inh|de|gmh|lewe}}, {{m|gmh|löuwe}}, {{m|gmh|lauwe}}, daripada {{inh|de|goh|lewo}}, {{m|goh|lēo}}, daripada {{inh|de|gmw-pro|*lēwō|*lewo, *lēwo|t=singa}}.
===Sebutan===
* {{IPA|de|/ˈløːvə/}}
* {{audio|de|De-Löwe.ogg|audio}}
* {{audio|de|De-Löwe2.ogg|audio}}
* {{hyph|de|Lö|we}}
bypffjyr1cxko4r81sc6f70gbag8m1y
Wikikamus:Senarai keluarga bahasa
4
50642
375867
187438
2026-09-25T12:40:14Z
Hakimi97
2668
Hakimi97 telah memindahkan laman [[Wikikamus:Senarai keluarga]] ke [[Wikikamus:Senarai keluarga bahasa]]: Penamaan semula, lebih tepat
187438
wikitext
text/x-wiki
{{shortcut|WT:FAMLIST|WT:LOF|WT:LF}}
{{main|Wikikamus:Keluarga bahasa}}
Halaman ini menyenaraikan semua kod keluarga bahasa yang diiktiraf oleh Wikikamus. Kandungan halaman ini dijana terus daripada [[Module:families]], dan sebarang perubahan pada modul itu akan dipaparkan secara automatik pada halaman ini, sebaik sahaja perisian menyegar semula.
Untuk mencari kod keluarga dengan cepat, tambahkan kod pada URL anda sebagai pautan bahagian. Contohnya,[[Wiktionary:Senarai keluarga#gmw]] dan memaut terus ke keluarga bahasa Jermanik Barat.
Lihat juga [[Wiktionary:Senarai bahasa]] dan [[Wiktionary:Senarai tulisan]].
Jika anda menjalankan bot atau alat automasi lain yang perlu mengakses data Wikikamus, sila lihat [[Module:JSON data]].
==Kod umum==
{{#invoke:list of families|show|three-letter code|with_stats=1}}
==Kod kekecualian==
{{#invoke:list of families|show|exceptional|with_stats=1}}
==Kod khas==
Kod yang dipaparkan di sini bukannya berkaitan kod keluarga bahasa, tetapi boleh digunakan seolah-olah seperti ia kod keluarga bahasa dalam beberapa keadaan.
{{#invoke:list of families|show|special|with_stats=1}}
[[Category:Semua keluarga bahasa]]
8u9anyu2plwmaaczgucnkw47jn0q7uh
375869
375867
2026-09-25T12:41:59Z
Hakimi97
2668
Betulkan kod
375869
wikitext
text/x-wiki
{{shortcut|WT:FAMLIST|WT:LOF|WT:LF}}
{{main|Wikikamus:Keluarga bahasa}}
Halaman ini menyenaraikan semua kod keluarga bahasa yang diiktiraf oleh Wikikamus. Kandungan halaman ini dijana terus daripada [[Module:families]], dan sebarang perubahan pada modul itu akan dipaparkan secara automatik pada halaman ini, sebaik sahaja perisian menyegar semula.
Untuk mencari kod keluarga dengan cepat, tambahkan kod pada URL anda sebagai pautan bahagian. Contohnya,[[Wiktionary:Senarai keluarga bahasa#gmw]] dan memaut terus ke keluarga bahasa Jermanik Barat.
Lihat juga [[Wiktionary:Senarai bahasa]] dan [[Wiktionary:Senarai tulisan]].
Jika anda menjalankan bot atau alat automasi lain yang perlu mengakses data Wikikamus, sila lihat [[Module:JSON data]].
==Kod umum==
{{#invoke:list of families|show|three-letter code|with_stats=1}}
==Kod kekecualian==
{{#invoke:list of families|show|exceptional|with_stats=1}}
==Kod khas==
Kod yang dipaparkan di sini bukannya berkaitan kod keluarga bahasa, tetapi boleh digunakan seolah-olah seperti ia kod keluarga bahasa dalam beberapa keadaan.
{{#invoke:list of families|show|special|with_stats=1}}
[[Category:Semua keluarga bahasa]]
3k5q6c5gyfhywepjx13vzd5efh9coxx
Modul:pages
828
57817
375899
373500
2026-09-26T06:28:49Z
Hakimi97
2668
Pembetulan: Module > Modul in regex
375899
Scribunto
text/plain
local export = {}
local string_utilities_module = "Modul:string utilities"
local concat = table.concat
local find = string.find
local format = string.format
local getmetatable = getmetatable
local get_current_section -- defined below
local get_namespace_shortcut -- defined below
local get_pagetype -- defined below
local gsub = string.gsub
local insert = table.insert
local is_internal_title -- defined below
local is_title -- defined below
local lower = string.lower
local match = string.match
local new_title = mw.title.new
local require = require
local sub = string.sub
local title_equals = mw.title.equals
local tonumber = tonumber
local type = type
local ufind = mw.ustring.find
local unstrip_nowiki = mw.text.unstripNoWiki
--[==[
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 decode_entities(...)
decode_entities = require(string_utilities_module).decode_entities
return decode_entities(...)
end
local function ulower(...)
ulower = require(string_utilities_module).lower
return ulower(...)
end
local function trim(...)
trim = require(string_utilities_module).trim
return trim(...)
end
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local current_frame
local function get_current_frame()
current_frame, get_current_frame = mw.getCurrentFrame(), nil
return current_frame
end
local parent_frame
local function get_parent_frame()
parent_frame, get_parent_frame = (current_frame or get_current_frame()):getParent(), nil
return parent_frame
end
local namespace_shortcuts
local function get_namespace_shortcuts()
namespace_shortcuts, get_namespace_shortcuts = {
[4] = "WT",
[10] = "T",
[14] = "CAT",
[100] = "AP",
[110] = "WS",
[118] = "RC",
[828] = "MOD",
}, nil
return namespace_shortcuts
end
do
local transcluded
--[==[
Returns {true} if the current {{tl|#invoke:}} is being transcluded, or {false} if not. If the current {{tl|#invoke:}} is part of a template, for instance, this template will therefore return {true}.
Note that if a template containing an {{tl|#invoke:}} is used on its own page (e.g. to display a demonstration), this function is still able to detect that this is transclusion. This is an improvement over the other method for detecting transclusion, which is to check the parent frame title against the current page title, which fails to detect transclusion in that instance.]==]
function export.is_transcluded()
if transcluded == nil then
transcluded = (parent_frame or get_parent_frame()) and parent_frame:preprocess("<includeonly>1</includeonly>") == "1" or false
end
return transcluded
end
end
do
local preview
--[==[
Returns {true} if the page is currently being viewed in preview, or {false} if not.]==]
function export.is_preview()
if preview == nil then
preview = (current_frame or get_current_frame()):preprocess("{{REVISIONID}}") == ""
end
return preview
end
end
--[==[
Returns {true} if the input is a title object, or {false} if not. This therefore '''includes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_internal_title` below.]==]
function export.is_title(val)
if not (val and type(val) == "table") then
return false
end
local mt = getmetatable(val)
-- There's no foolproof method for checking for a title object, but the
-- __eq metamethod should be mw.title.equals unless the object has been
-- seriously messed around with.
return mt and
type(mt) == "table" and
getmetatable(mt) == nil and
mt.__eq == title_equals and
true or false
end
is_title = export.is_title
--[==[
Returns {true} if the input is an internal title object, or {false} if not. An internal title object is a title object for a page on this wiki, such as [[example]]. This therefore '''excludes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_title` above.]==]
function export.is_internal_title(title)
-- Note: Mainspace titles starting with "#" should be invalid, but a bug in mw.title.new and mw.title.makeTitle means a title object is returned that has the empty string for prefixedText, so they need to be filtered out.
return is_title(title) and #title.prefixedText > 0 and #title.interwiki == 0
end
is_internal_title = export.is_internal_title
--[==[
Returns {true} if the input string is a valid link target, or {false} if not. This therefore '''includes''' link targets to other wikis, such as [[w:Example]], unlike `is_valid_page_name` below.]==]
function export.is_valid_link_target(target)
local target_type = type(target)
if target_type == "string" then
return is_title(new_title(target))
end
error(format("bad argument #1 to 'is_valid_link_target' (string expected, got %s)", target_type), 2)
end
--[==[
Returns {true} if the input string is a valid page name on this wiki, or {false} if not. This therefore '''excludes''' page names on other wikis, such as [[w:Example]], unlike `is_valid_link_target` above.]==]
function export.is_valid_page_name(name)
local name_type = type(name)
if name_type == "string" then
return is_internal_title(new_title(name))
end
error(format("bad argument #1 to 'is_valid_page_name' (string expected, got %s)", name_type), 2)
end
--[==[
Given a title object, returns a full link target which will always unambiguously link to it.
For instance, the input {"foo"} (for the page [[foo]]) returns {":foo"}, as a leading colon always refers to mainspace, even when other namespaces might be assumed (e.g. when transcluding using `{{ }}` syntax).
If `shortcut` is set, then the returned target will use the namespace shortcut, if any; for example, the title for `Templat:foo` would return {"T:foo"} instead of {"Templat:foo"}.]==]
function export.get_link_target(title, shortcut)
if not is_title(title) then
error(format("bad argument #1 to 'is_valid_link_target' (title object expected, got %s)", type(title)))
elseif title.interwiki ~= "" then
return title.fullText
elseif shortcut then
local fragment = title.fragment
if fragment == "" then
return get_namespace_shortcut(title) .. ":" .. title.text
end
return get_namespace_shortcut(title) .. ":" .. title.text .. "#" .. fragment
elseif title.namespace == 0 then
return ":" .. title.fullText
end
return title.fullText
end
do
local function find_sandbox(text)
return find(text, "^Pengguna:.") or find(lower(text), "kotak pasir", 1, true)
end
local function get_transclusion_subtypes(title, main_type, documentation, page_suffix)
local text, subtypes = title.text, {main_type}
-- Any template/module with "sandbox" in the title. These are impossible
-- to screen for more accurately, as there's no consistent pattern. Also
-- any user sandboxes in the form (e.g.) "Templat:User:...".
local sandbox = find_sandbox(text)
if sandbox then
insert(subtypes, "kotak pasir")
end
-- Any template/module testcases (which can be labelled and/or followed
-- by further subpages).
local testcase = find(text, "./[Tt]estcases?%f[%L]")
if testcase then
-- Order "testcase" and "sandbox" based on where the patterns occur
-- in the title.
local n = sandbox and sandbox < testcase and 3 or 2
insert(subtypes, n, "kes ujian")
end
-- Any template/module documentation pages.
if documentation then
insert(subtypes, "pendokumenan")
end
local final = subtypes[#subtypes]
if not (final == main_type and not page_suffix or final == "sandbox") then
insert(subtypes, "laman")
end
return concat(subtypes, " ")
end
local function get_snippet_subtypes(title, main_type, documentation)
local ns = title.namespace
return get_transclusion_subtypes(title, main_type .. (
ns == 2 and " pengguna" or
ns == 8 and match(title.text, "^Gadget-.") and " gajet" or
""
), documentation)
end
--[==[
Returns the page type of the input title object in a format which can be used in running text.]==]
function export.get_pagetype(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
-- If possibly a documentation page, get the base title and set the
-- `documentation` flag.
local content_model, text, documentation = title.contentModel
if content_model == "wikitext" then
text = title.text
if title.isSubpage and title.subpageText == "doc" then
local base_title = title.basePageTitle
if base_title then
title, content_model, text, documentation = base_title, base_title.contentModel, base_title.text, true
end
end
end
-- Content models have overriding priority, as they can appear in
-- nonstandard places due to page content model changes.
if content_model == "css" or content_model == "sanitized-css" then
return get_snippet_subtypes(title, "lembaran gaya", documentation)
elseif content_model == "javascript" then
return get_snippet_subtypes(title, "skrip", documentation)
elseif content_model == "json" then
return get_snippet_subtypes(title, "data JSON", documentation)
elseif content_model == "MassMessageListContent" then
return get_snippet_subtypes(title, "senarai penghantaran mesej massa", documentation)
-- Modules.
elseif content_model == "Scribunto" then
return get_transclusion_subtypes(title, "modul", documentation, false)
elseif content_model == "text" then
return "laman" -- ???
-- Otherwise, the content model is "wikitext", so check namespaces.
elseif title.isTalkPage then
return "laman perbincangan"
end
local ns = title.namespace
-- Main namespace.
if ns == 0 then
return "entri"
-- Wiktionary:
elseif ns == 4 then
return find_sandbox(title.text) and "kotak pasir" or "laman projek"
-- Templat:
elseif ns == 10 then
return get_transclusion_subtypes(title, "templat", documentation, false)
end
-- Convert the namespace to lowercase, unless it contains a capital
-- letter after the initial letter (e.g. MediaWiki, TimedText). Also
-- normalize any underscores.
local ns_text = gsub(title.nsText, "_", " ")
if ufind(ns_text, "^%U*$", 2) then
ns_text = ulower(ns_text)
end
-- User:
if ns == 2 then
return (title.isSubpage and "sublaman" or "laman") .. " " .. ns_text
-- Category: and Appendix:
elseif ns == 14 or ns == 100 then
return ns_text
-- Thesaurus: and Reconstruction:
elseif ns == 110 or ns == 118 then
return "entri " .. ns_text
end
return "laman " .. ns_text
end
get_pagetype = export.get_pagetype
end
--[==[
Returns {true} if the input title object is for a content page, or {false} if not. A content page is a page that is considered part of the dictionary itself, and excludes pages for discussion, administration, maintenance etc.]==]
function export.is_content_page(title)
if not is_internal_title(title) then
error(mw.dumpObject(title.fullText) .. " is not a valid page name.")
end
local ns = title.namespace
-- (main), Appendix, Thesaurus, Citations, Reconstruction.
return (ns == 0 or ns == 100 or ns == 110 or ns == 114 or ns == 118) and
title.contentModel == "wikitext"
end
--[==[
Returns {true} if the input title object is for a documentation page, or {false} if not.]==]
function export.is_documentation(title)
return match(get_pagetype(title), "%f[%w]doc%f[%W]") and true or false
end
--[==[
Returns {true} if the input title object is for a sandbox, or {false} if not.
By default, sandbox documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_sandbox(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]sandbox%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]doc%f[%W]")
) and true or false
end
--[==[
Returns {true} if the input title object is for a testcase page, or {false} if not.
By default, testcase documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==]
function export.is_testcase_page(title, include_documentation)
local pagetype = get_pagetype(title)
return match(pagetype, "%f[%w]testcase%f[%W]") and (
include_documentation or
not match(pagetype, "%f[%w]doc%f[%W]")
) and true or false
end
--[==[
Returns the namespace shortcut for the input title object, or else the namespace text. For example, a `Templat:` title returns {"T"}, a `Modul:` title returns {"MOD"}, and a `User:` title returns {"User"}.]==]
function export.get_namespace_shortcut(title)
return (namespace_shortcuts or get_namespace_shortcuts())[title.namespace] or title.nsText
end
get_namespace_shortcut = export.get_namespace_shortcut
do
local function check_level(lvl)
if type(lvl) ~= "number" then
error("Heading levels must be numbers.")
elseif lvl < 1 or lvl > 6 or lvl % 1 ~= 0 then
error("Heading levels must be integers between 1 and 6.")
end
return lvl
end
--[==[
A helper function which iterates over the headings in `text`, which should be the content of a page or (main) section.
Each iteration returns three values: `sec` (the section title), `lvl` (the section level) and `loc` (the index of the section in the given text, from the first equals sign). The section title will be automatically trimmed, and any HTML entities will be resolved.
The optional parameter `a` (which should be an integer between 1 and 6) can be used to ensure that only headings of the specified level are iterated over. If `b` is also given, then they are treated as a range.
The optional parameters `a` and `b` can be used to specify a range, so that only headings with levels in that range are returned.]==]
local function find_headings(text, a, b)
a = a and check_level(a) or nil
b = b and check_level(b) or a or nil
local start, loc, lvl, sec = 1
return function()
repeat
loc, lvl, sec, start = match(text, "()%f[^%z\n](==?=?=?=?=?)([^\n]+)%2[\t ]*%f[%z\n]()", start)
lvl = lvl and #lvl
until not (sec and a) or (lvl >= a and lvl <= b)
return sec and trim(decode_entities(sec)) or nil, lvl, loc
end
end
local function _get_section(content, name, level)
if not (content and name) then
return nil
elseif find(name, "\n", 1, true) then
error("Heading name cannot contain a newline.")
end
level = level and check_level(level) or nil
name = trim(decode_entities(name))
local start
for sec, lvl, loc in find_headings(content, level and 1 or nil, level) do
if start and lvl <= level then
return sub(content, start, loc - 1)
elseif not start and (not level or lvl == level) and sec == name then
start, level = loc, lvl
end
end
return start and sub(content, start)
end
--[==[
A helper function to return the content of a page section.
`content` is raw wikitext, `name` is the requested section, and `level` is an optional parameter that specifies
the required section heading level. If `level` is not supplied, then the first section called `name` is returned.
`name` can either be a string or table of section names. If a table, each name represents a section that has the
next as a subsection. For example, { {"Spanish", "Noun"}} will return the first matching section called "Noun"
under a section called "Spanish". These do not have to be at adjacent levels ("Noun" might be L4, while "Spanish"
is L2). If `level` is given, it refers to the last name in the table (i.e. the name of the section to be returned).
The returned section includes all of its subsections. If no matching section is found, return {nil}.]==]
function export.get_section(content, names, level)
if type(names) ~= "table" then
return _get_section(content, names, level)
end
local i = 1
local name = names[i]
if not name then
error("Must specify at least 1 section.")
end
while true do
local nxt_i = i + 1
local nxt = names[nxt_i]
if nxt == nil then
return _get_section(content, name, level)
end
content = _get_section(content, name)
if content == nil then
return nil
elseif i == 6 then
error("Not possible specify more than 6 sections: headings only go up to level 6.")
end
i = nxt_i
name = names[i]
end
return content
end
end
--[==[
Convert a physical pagename (or the current pagename, if {nil} is passed in) to its logical equivalent, but only if
the physical pagename refers to one of the splits of a mammoth page such as [[a]]. Otherwise this simply returns the
subpage (the part after the last slash in namespace other than the main one, otherwise the same as passed in), unless
`include_base` is specified, in which case the return value will be the whole pagename minus the namespace, including
the base (the part before the final slash).
FIXME: This should be augmented with logic to handle unsupported titles, which is currently in process_page() in
[[Modul:headword/page]], so that it is a general physical-to-logical conversion function.
Examples:
* {physical_to_logical_pagename_if_mammoth("a")} → {"a"}
* {physical_to_logical_pagename_if_mammoth("a/languages A to L")} → {"a"} (since [[a]] is marked as a mammoth page in [[Modul:links/data]])
* {physical_to_logical_pagename_if_mammoth("50/50")} → {"50/50"} (since [[50/50]] is in the main namespace)
* {physical_to_logical_pagename_if_mammoth("Appendix:Lojban/a")} → "a"
* {physical_to_logical_pagename_if_mammoth("Appendix:Lojban/a", true)} → "Lojban/a"
* {physical_to_logical_pagename_if_mammoth("Reconstruction:Proto-Slavic/a")} → "a"
* {physical_to_logical_pagename_if_mammoth("Reconstruction:Proto-Slavic/a", true)} → "Proto-Slavic/a"
* {physical_to_logical_pagename_if_mammoth("User:Example/sandbox/foo")} → "foo"
* {physical_to_logical_pagename_if_mammoth("User:Example/sandbox/foo", true)} → "Example/sandbox/foo"
]==]
function export.physical_to_logical_pagename_if_mammoth(title, include_base)
if title == nil then
title = mw.title.getCurrentTitle()
elseif not is_title(title) then
title = mw.title.new(title)
end
if title.nsText == "" then
-- Formerly we checked for the specific known subpages of a given mammoth split page, e.g. we would convert
-- [[a/languages M to Z]] to [[a]] assuming that [[a/languages M to Z]] was one of the splits, but not
-- [[a/languages N to Z]]. To simplify this, we just convert anything with the right mammoth split page format
-- on the assumption that it's unlikely we will ever have a legitimate non-mammoth-split pagename of this sort.
local pagename = title.text
local mammoth_root_page = pagename:match("^(.*)/languages [A-Z] to [A-Z]$")
if mammoth_root_page then
pagename = mammoth_root_page
end
return pagename
elseif include_base then
return title.text
else
return title.subpageText
end
end
--[==[
Obsolete name for `physical_to_logical_pagename_if_mammoth`. FIXME: Replace all uses and remove.
]==]
function export.safe_page_name(title)
return export.physical_to_logical_pagename_if_mammoth(title)
end
do
local current_section
--[==[
A function which returns the number of the page section which contains the current {#invoke}, or {0} if the section can't be determined.]==]
function export.get_current_section()
if current_section ~= nil then
return current_section
end
local frame = parent_frame or get_parent_frame()
while frame do
if find(frame:getTitle(), "^Modul:") then
current_section = 0
return 0
end
frame = frame:getParent()
end
local extension_tag = (current_frame or get_current_frame()).extensionTag
-- We determine the section via the heading strip marker count, since they're numbered sequentially, but the only way to do this is to generate a fake heading via frame:preprocess(). The native parser assigns each heading a unique marker, but frame:preprocess() will return copies of older markers if the heading is identical to one further up the page, so the fake heading has to be unique to the page. The best way to do this is to feed it a heading containing a nowiki marker (which we will need later), since those are always unique.
local nowiki_marker = extension_tag(current_frame, "nowiki")
-- Note: heading strip markers have a different syntax to the ones used for tags.
local h = tonumber(match(
current_frame:preprocess("=" .. nowiki_marker .. "="),
"\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127"
))
-- For some reason, [[Special:ExpandTemplates]] doesn't generate a heading strip marker, so if that happens we simply abort early.
if not h then
return 0
end
-- The only way to get the section number is to increment the heading count, so we store the offset in nowiki strip markers which can be retrieved by procedurally unstripping nowiki markers, counting backwards until we find a match.
local n, offset = tonumber(match(
nowiki_marker,
"\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127"
), 16)
while not offset and n > 0 do
n = n - 1
offset = match(
unstrip_nowiki(format("\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127", n)),
"^HEADING\1(%d+)" -- Prefix "HEADING\1" prevents collisions.
)
end
offset = offset and (offset + 1) or 0
extension_tag(current_frame, "nowiki", "HEADING\1" .. offset)
current_section = h - offset
return current_section
end
get_current_section = export.get_current_section
end
do
local L2_sections, current_L2
local function get_L2_sections()
L2_sections, get_L2_sections = mw.loadData("Modul:headword/data").page.L2_sections, nil
return L2_sections
end
--[==[
A function which returns the name of the L2 language section which contains the current {#invoke}.]==]
function export.get_current_L2()
if current_L2 ~= nil then
return current_L2 or nil -- Return nil if current_L2 is false (i.e. there's no L2).
end
local section = get_current_section()
while section > 0 do
local L2 = (L2_sections or get_L2_sections())[section]
if L2 then
current_L2 = L2
return L2
end
section = section - 1
end
current_L2 = false
return nil
end
end
return export
1hsdomr0saf79jwx07a7egijos96bz6
Modul:etymon
828
57903
376194
375859
2026-09-26T09:32:11Z
Hakimi97
2668
Menyetempatkan pemadanan nama bahasa di peringkat L2 dengan kod (nama bahasa)
376194
Scribunto
text/plain
--[=[
This module implements the {{etymon}} template for structured etymology data on Wiktionary.
It enables the creation of etymology trees and text by parsing etymon chains,
scraping linked pages for their own {{etymon}} data, and recursively building a tree
of derivational relationships.
Authors:
- Original implementation: [[User:Ioaxxere]]
- Full refactor (September 2025): [[User:Fenakhay]] ([[Special:Diff/86717746]])
Modules:
- [[Module:etymon]]: main module handling parsing, validation, tree building, and page scraping
- [[Module:etymon/data]]: keyword definitions, configuration, and status constants
- [[Module:etymon/tree]]: etymology tree rendering
- [[Module:etymon/text]]: etymology text generation
- [[Module:etymon/categories]]: category generation logic
- [[Module:etymon/tracking]]: tracking
]=]
local export = {}
local __state = {
cached_etymon_args = {},
cached_etymon_pages = {},
cached_descendants_checks = {},
senseid_parent_etymon = {},
available_etymon_ids = {},
single_etymons = {},
entry_title = nil,
entry_lang_code = nil,
current_page_has_inline_etymology = false,
current_page_has_redundant_etymology = false,
used_idless_etymon = false,
toplevel_has_inline_etymology = false,
toplevel_redundant_etymology = false,
toplevel_idless_etymon = false,
has_mismatched_id = false,
linked_page_multiple_etymons_idless = false,
linked_page_partial_etymology_sections = false,
partial_etymology_targets = {},
skip_partial_etymology_category = false,
max_depth_reached = 0,
total_nodes = 0,
language_count = {},
toplevel_keyword_stats = {},
id_stats = nil,
warnings = {},
}
local function reset_invocation_state()
__state.current_page_has_inline_etymology = false
__state.current_page_has_redundant_etymology = false
__state.used_idless_etymon = false
__state.toplevel_has_inline_etymology = false
__state.toplevel_redundant_etymology = false
__state.toplevel_idless_etymon = false
__state.has_mismatched_id = false
__state.linked_page_multiple_etymons_idless = false
__state.linked_page_partial_etymology_sections = false
__state.max_depth_reached = 0
__state.total_nodes = 0
__state.language_count = {}
__state.toplevel_keyword_stats = {}
__state.warnings = {}
end
local M = require("Module:module loader").init({
require = {
data = "Module:etymon/data",
tree = "Module:etymon/tree",
text = "Module:etymon/text",
categories = "Module:etymon/categories",
tracking = "Module:etymon/tracking",
descendants = "Module:etymon/descendants",
anchors = "Module:anchors",
etydate = "Module:etydate",
etymology = "Module:etymology",
families = "Module:families",
languages = "Module:languages",
languages_errorgetby = "Module:languages/errorGetBy",
links = "Module:links",
pages = "Module:pages",
parameters = "Module:parameters",
string_utilities = "Module:string utilities",
template_parser = "Module:template parser",
utilities = "Module:utilities",
debug = "Module:debug",
en_utilities = "Module:en-utilities",
parameter_utilities = "Module:parameter utilities",
parse_utilities = "Module:parse utilities",
template_styles = "Module:TemplateStyles",
script_utilities = "Module:script utilities",
JSON = "Module:JSON",
yesno = "Module:yesno",
},
loadData = {
headword_data = "Module:headword/data",
parameters_data = "Module:parameters/data",
text_allowed = "Module:etymon/data/text_allowed",
},
})
local Util = {}
function Util.format_error(message, preview_only)
if preview_only and not M.pages.is_preview() then
return nil
end
return '<span class="error">' .. message .. '</span>'
end
function Util.add_warning(message, preview_only)
local formatted = Util.format_error(message, preview_only)
if formatted then
table.insert(__state.warnings, formatted)
end
end
function Util.is_text_param_allowed_for_lang(lang)
if not lang or type(lang) ~= "table" then
return false
end
local types = lang.getTypes and lang:getTypes()
if types and types.family then
local code = lang.getCode and lang:getCode()
return code and M.text_allowed.families[code] == true
end
local full_code = lang.getFullCode and lang:getFullCode()
if full_code and M.text_allowed.langs[full_code] then
return true
end
if lang.inFamily then
for family_code in pairs(M.text_allowed.families) do
if lang:inFamily(family_code) then
return true
end
end
end
return false
end
function Util.get_lang(code, no_error)
if no_error then
return M.languages.getByCode(code, nil, true)
end
return M.languages.getByCode(code, nil, true) or M.languages_errorgetby.code(code, true, true)
end
-- Match a term language against a text=:lang stop target (supports etymology-only codes).
function Util.lang_matches_stop_code(term_lang, stop_code)
if not term_lang or not stop_code or stop_code == "" then
return false
end
local stop_lang = Util.get_lang(stop_code, true)
if not stop_lang then
return false
end
if term_lang:getCode() == stop_lang:getCode() then
return true
end
if stop_lang:getFullCode() == stop_lang:getCode() then
return term_lang:getFullCode() == stop_lang:getCode()
end
return false
end
function Util.get_family(code)
return M.families.getByCode(code)
end
function Util.get_lang_exception(lang)
-- Families have no language-specific exceptions
if lang.getTypes and lang:getTypes().family then
return nil
end
local code = lang:getCode()
local lang_exceptions = M.data.config.lang_exceptions
if lang_exceptions[code] then
return lang_exceptions[code]
end
for norm_code, exc in pairs(lang_exceptions) do
if exc.normalize_to and code == exc.normalize_to then
return exc
end
if exc.normalize_from_families then
local should_normalize = false
for _, family in ipairs(exc.normalize_from_families) do
if lang:inFamily(family) then
should_normalize = true
break
end
end
if should_normalize and exc.normalize_exclude_families then
for _, family in ipairs(exc.normalize_exclude_families) do
if lang:inFamily(family) then
should_normalize = false
break
end
end
end
if should_normalize then
local ret = {}
for k, v in pairs(exc) do
ret[k] = v
end
ret.suppress_tr = nil
return ret
end
end
end
return nil
end
function Util.get_norm_lang(lang)
local exc = Util.get_lang_exception(lang)
if exc and exc.normalize_to then
return M.languages.getByCode(exc.normalize_to)
end
return lang
end
function Util.resolve_context_lang(lang, node_args)
if type(node_args) ~= "table" then return lang end
if node_args.status == M.data.STATUS.INLINE then return lang end
if not (lang.hasType and lang:hasType("etymology-only")) then return lang end
local full = lang.getFull and lang:getFull()
if not full or full:getCode() == lang:getCode() then return lang end
if full.hasAncestor and full:hasAncestor(lang) then return lang end
return full
end
-- Add default values for boolean modifiers (e.g., <unc> becomes <unc:1>)
-- This is needed because Module:parse utilities expects boolean modifiers to have explicit values
function Util.add_boolean_defaults(str, param_mods)
local result = str
for name, spec in pairs(param_mods) do
if spec.type == "boolean" then
-- Replace <name> with <name:1> (but not <name:...> which already has a value)
result = result:gsub("<" .. name .. ">", "<" .. name .. ":1>")
end
end
return result
end
local REQUEST_TEMPLATE_PARAM_MODS = {
rfe = M.parameter_utilities.construct_param_mods {
{ param = { "sort", "y", "m", "fragment", "section" } },
{ param = { "nocat", "box", "noes" }, type = "boolean" },
},
etystub = M.parameter_utilities.construct_param_mods {
{ param = "sort" },
{ param = { "nocat", "nocap", "nodot" }, type = "boolean" },
},
}
function Util.expand_request_template(frame, template_name, param_value, lang_code)
local param_mods = REQUEST_TEMPLATE_PARAM_MODS[template_name]
local with_defaults = Util.add_boolean_defaults(param_value, param_mods)
local parsed = M.parse_utilities.parse_inline_modifiers(with_defaults, {
param_mods = param_mods,
generate_obj = function(text)
if M.yesno(text, false) then
return { is_boolean = true }
end
return { text = text }
end,
})
local template_args = { [1] = lang_code }
for name in pairs(param_mods) do
template_args[name] = parsed[name]
end
if not parsed.is_boolean then
template_args[2] = parsed.text
end
return " " .. frame:expandTemplate({
title = template_name,
args = template_args,
})
end
-- Centralized term formatting: handles suppress_term (-), unknown_term (empty/+), and regular terms
function Util.format_term(term, is_toplevel, opts)
opts = opts or {}
-- suppress_term (-) returns nil
if term.suppress_term then
return nil
end
local lang = term.lang
local exc = Util.get_lang_exception(lang)
if is_toplevel then
local display_text = term.alt or term.title or ""
local sc = term.sc or lang:findBestScript(display_text)
local bold_text = tostring(mw.html.create("strong")
:addClass("selflink")
:wikitext(display_text))
return M.script_utilities.tag_text(bold_text, lang, sc, "term")
end
local link_params = { lang = lang }
link_params.term = not term.unknown_term and term.title or nil
link_params.alt = term.alt
link_params.id = (not term.unknown_term and term.id and term.id ~= "") and term.id or nil
if not (exc and exc.suppress_tr) then
link_params.tr = term.tr
link_params.ts = term.ts
else
link_params.suppress_tr = true
end
link_params.lit = (opts.lit ~= "suppress") and term.lit or nil
if opts.gloss ~= "suppress" then
link_params.gloss = term.gloss
end
link_params.genders = term.genders
if opts.pos ~= "suppress" then
link_params.pos = term.pos
link_params.ng = term.ng
link_params.infl = term.infl
end
if exc and exc.suppress_tr then
link_params.lit = nil
end
if opts.tree_ql ~= "suppress" then
if term.q then
link_params.q = term.q
end
if term.qq then
link_params.qq = term.qq
end
if term.l then
link_params.l = term.l
end
if term.ll then
link_params.ll = term.ll
end
link_params.show_decorations = term.q or term.qq or term.l or term.ll
end
return M.links.full_link(link_params, "term")
end
local __is_content_page_cached
function Util.is_content_page()
if __is_content_page_cached == nil then
__is_content_page_cached = M.pages.is_content_page(mw.title.getCurrentTitle())
end
return __is_content_page_cached
end
local __page_data_cached
function Util.get_page_data()
if not __page_data_cached then
__page_data_cached = M.headword_data.page
end
return __page_data_cached
end
-- Malay Wiktionary uses L2 headings in the form "Bahasa <language>",
-- while language objects use the bare canonical name.
local function normalize_L2_name(name)
if not name then
return nil
end
name = M.string_utilities.trim(name)
return name:match("^Bahasa%s+(.+)$") or name
end
local function L2_matches_lang(L2, lang)
if not L2 then
return false
end
local norm_lang = Util.get_norm_lang(lang)
local norm_name = norm_lang:getCanonicalName()
return normalize_L2_name(L2) == norm_name
end
-- Extract base keyword from param (without modifiers)
local function get_keyword_base(param)
if type(param) ~= "string" then return nil end
local base = param:match("^:?([^<]+)") or param:gsub("^:", "")
return base
end
local function is_keyword(param, allow_colon_less)
if type(param) ~= "string" then return false end
local keywords = M.data.keywords
if param:sub(1, 1) == ":" then
local base = get_keyword_base(param)
return keywords[base] ~= nil
end
if allow_colon_less then
local base = get_keyword_base(param)
return keywords[base] ~= nil
end
return false
end
local function get_keyword(param, allow_colon_less)
if type(param) ~= "string" then return nil end
local keywords = M.data.keywords
if param:sub(1, 1) == ":" then
return get_keyword_base(param)
end
if allow_colon_less then
local base = get_keyword_base(param)
if keywords[base] then
return base
end
end
return nil
end
local function normalize_keyword(keyword)
if keyword:sub(1, 1) == ":" then
return keyword
end
return ":" .. keyword
end
-- Resolve keyword (possibly an alias) to its canonical form. Used only at input boundaries
local function get_canonical_keyword(keyword)
if not keyword then return keyword end
return M.data.keyword_canonical[keyword] or keyword
end
local function is_affix_group_keyword(keyword)
local config = keyword and M.data.keywords[keyword]
return config and config.affix_categories or false
end
local function reject_removed_surf_keyword(param)
local base = get_keyword_base(param)
if base == "surf" then
error("The `:surf` keyword has been removed. Use `<surf>` on a formation keyword instead (e.g. `:af<surf>`, `:bor<surf>`).")
end
end
local function copy_keyword_info(source)
local copy = {}
for k, v in pairs(source) do
copy[k] = v
end
return copy
end
local function lowercase_glossary_display(text)
return text:gsub("(%[%[Appendix:Glossary#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function surf_should_keep_formation_phrase(base)
if not base.phrase then
return false
end
if base.glossary then
return true
end
return not (base.phrase == "from" and (base.text == "From" or base.text == "from"))
end
-- Runtime overrides when <surf> is present on a keyword.
local function get_effective_keyword_info(keyword, modifiers)
local base = M.data.keywords[keyword]
if not base or not modifiers or not modifiers.surf then
return base
end
local effective = copy_keyword_info(base)
local surf_text = "By [[Appendix:Glossary#surface_analysis|surface analysis]],"
local surf_phrase = "by surface analysis,"
effective.new_sentence = true
effective.invisible = "tree"
if surf_should_keep_formation_phrase(base) then
effective.phrase = surf_phrase .. " " .. base.phrase
if base.text then
effective.text = surf_text .. " " .. lowercase_glossary_display(base.text)
else
effective.text = surf_text .. " " .. base.phrase
end
else
effective.text = surf_text
effective.phrase = surf_phrase
end
return effective
end
-- Build text/phrase for nominalization with <g:code> (uses data module for codes only).
local function get_nominalization_label_for_g(code)
if not code or code == "" then return nil end
local codes = M.data.nominalization_g_codes
local adj = codes[code]
if not adj and #code == 2 then
local gender_adj = codes[code:sub(1, 1)]
local number_adj = codes[code:sub(2, 2)]
if gender_adj and number_adj then
adj = gender_adj .. " " .. number_adj
end
end
if not adj then return nil end
local text = adj:gsub("^%l", function(c) return string.upper(c) end) .. " [[Appendix:Glossary#nominalization|nominalization]] of"
local phrase = M.en_utilities.add_indefinite_article(adj .. " [[Appendix:Glossary#nominalization|nominalization]] of", false)
return { text = text, phrase = phrase }
end
local EtymonParser = {}
-- Keyword modifier definitions
EtymonParser.keyword_param_mods = M.parameter_utilities.construct_param_mods {
{ group = "ref" },
{ param = "conj" }, -- conjunction for alternatives: "and", "or", "and/or", etc.
{ param = { "unc", "surf" }, type = "boolean" },
{ param = "text", restrict = { keywords = { "from", "derived" } } },
{ param = "lit", restrict = { affix_group = true } },
{ param = "g", restrict = { keywords = { "nominalization" } } },
{ param = "senseid", restrict = { keywords = { "semantic loan" } } },
}
-- Term modifier definitions
EtymonParser.etymon_param_mods = M.parameter_utilities.construct_param_mods {
{group = {"link", "q", "l", "ref", "infl"}, exclude = {"sc"}},
{param = {"ety", "postype"}},
{param = "unc", type = "boolean"},
{param = "aftype", restrict = {affix_group = true}},
{param = {"bor", "slbor", "lbor"}, type = "boolean", restrict = {affix_group = true}},
}
local function get_clean_param_mods(param_mods)
local clean = {}
for mod_name, mod_def in pairs(param_mods) do
clean[mod_name] = {}
for key, value in pairs(mod_def) do
if key ~= "restrict" then
clean[mod_name][key] = value
end
end
end
return clean
end
function EtymonParser.check_modifier_restrictions(modifiers, current_keyword, param_mods)
for mod_name, mod_value in pairs(modifiers) do
-- Only check restrictions if the modifier has a non-false/nil value
if mod_value then
local mod_def = param_mods[mod_name]
if mod_def and mod_def.restrict then
if mod_def.restrict.affix_group then
if not is_affix_group_keyword(current_keyword) then
local mod_display = mod_value == true and "<" .. mod_name .. ">" or "<" .. mod_name .. ":" .. tostring(mod_value) .. ">"
error("The modifier `" .. mod_display .. "` is only allowed for affix-group keywords (e.g. `:af`, `:blend`, `:univ`).")
end
elseif mod_def.restrict.keywords then
local allowed_keywords = mod_def.restrict.keywords
local is_allowed = false
for _, allowed_keyword in ipairs(allowed_keywords) do
if current_keyword == allowed_keyword then
is_allowed = true
break
end
end
if not is_allowed then
local keyword_list = {}
for _, kw in ipairs(allowed_keywords) do
table.insert(keyword_list, ":" .. kw)
end
local keyword_str = table.concat(keyword_list, #keyword_list == 2 and " or " or ", ")
if #keyword_list > 2 then
-- Replace last comma with "or"
keyword_str = keyword_str:gsub(", ([^,]+)$", " or %1")
end
local mod_display = mod_value == true and "<" .. mod_name .. ">" or "<" .. mod_name .. ":" .. tostring(mod_value) .. ">"
error("The modifier `" .. mod_display .. "` is only allowed for the keyword" .. (#keyword_list > 1 and "s " or " ") .. keyword_str .. ".")
end
end
end
end
end
end
local TERM_RULE_DISALLOW = {
suppress = { field = "suppress_term", label = "suppressed" },
unknown = { field = "unknown_term", label = "unknown" },
family = { field = "is_family", label = "family" },
}
function EtymonParser.check_etymon_limits(count, limits, label, opts)
if not limits then
return
end
opts = opts or {}
local min_etymons = limits.min_etymons
if min_etymons == nil and not opts.skip_default_min then
min_etymons = 1
end
if min_etymons and count < min_etymons then
if min_etymons > 1 then
error("Detected " .. label .. " group with fewer than " .. min_etymons .. " etymons.")
else
error("Detected " .. label .. " with no etymons.")
end
end
if limits.max_etymons and count > limits.max_etymons then
local unit = (limits.max_etymons == 1) and "etymon" or "etymons"
error("Detected " .. label .. " with more than " .. limits.max_etymons .. " " .. unit .. ".")
end
end
function EtymonParser.check_term_rules(etymon_data, entry_lang, rules, label)
label = label or "term"
if rules and rules.disallow then
local disallowed = {}
for _, typ in ipairs(rules.disallow) do
local spec = TERM_RULE_DISALLOW[typ]
if spec and etymon_data[spec.field] then
table.insert(disallowed, spec.label)
end
end
if #disallowed > 0 then
error(label .. " does not support " ..
mw.text.listToText(disallowed, "or") .. " etymons.")
end
end
if etymon_data.is_family then
if rules and rules.family == "disallowed" then
error(label .. " does not support family codes" .. (rules.family_suffix or "."))
elseif not etymon_data.suppress_term then
error("Family codes require suppressed term (use family:-).")
end
end
if rules then
if rules.require_term and (not etymon_data.term or etymon_data.term == "") then
error(label .. " requires a term for each listed form.")
end
if rules.entry_lang then
if Util.get_norm_lang(etymon_data.lang):getFullCode() ~=
Util.get_norm_lang(entry_lang):getFullCode() then
error(label .. " terms must be in the entry language (" ..
entry_lang:getFullCode() .. "), got '" .. etymon_data.lang:getFullCode() .. "'.")
end
end
if rules.ancestor_check then
M.etymology.check_ancestor(entry_lang, etymon_data.lang)
end
elseif etymon_data.is_family and not etymon_data.suppress_term then
error("Family codes require suppressed term (use family:-).")
end
end
function EtymonParser.check_keyword_term(etymon_data, entry_lang, keyword)
local config = M.data.keywords[keyword]
EtymonParser.check_term_rules(etymon_data, entry_lang, config and config.term_rules, "`:" .. keyword .. "`")
end
function EtymonParser.check_supplement_term(etymon_data, entry_lang, supplement_type)
local config = M.data.supplements[supplement_type]
EtymonParser.check_term_rules(etymon_data, entry_lang, config and config.term_rules, "|" .. supplement_type .. "=")
end
-- Parse keyword with modifiers (e.g., ":bor<unc>" or ":bor<ref:{{R:example}}>")
function EtymonParser.parse_keyword_modifiers(param)
if type(param) ~= "string" then return nil, {} end
local base_keyword = get_keyword_base(param)
if not base_keyword then return nil, {} end
local canonical_keyword = get_canonical_keyword(base_keyword)
-- Check if there are any modifiers
if not param:find("<", 1, true) then
return canonical_keyword, {}
end
-- Parse modifiers using the same mechanism as etymon parsing
local rest_with_defaults = Util.add_boolean_defaults(param, EtymonParser.keyword_param_mods)
local function generate_obj(ignored)
return {}
end
local parsed = M.parse_utilities.parse_inline_modifiers(rest_with_defaults:gsub("^:?[^<]+", ""),
{ param_mods = get_clean_param_mods(EtymonParser.keyword_param_mods), generate_obj = generate_obj })
local modifiers = {
unc = parsed.unc or false,
refs = parsed.refs,
text = parsed.text,
lit = parsed.lit,
conj = parsed.conj,
g = parsed.g,
surf = parsed.surf or false,
senseid = parsed.senseid,
}
-- Validate modifiers against restrictions
EtymonParser.check_modifier_restrictions(modifiers, canonical_keyword, EtymonParser.keyword_param_mods)
return canonical_keyword, modifiers
end
local function normalize_keyword_param(keyword_with_mods)
local trimmed = M.string_utilities.trim(keyword_with_mods)
reject_removed_surf_keyword(trimmed:match("^:") and trimmed or (":" .. trimmed))
local base = get_keyword_base(trimmed)
if not base or not M.data.keywords[base] then
error("Invalid keyword '" .. trimmed .. "' in inline etymology")
end
local canonical_base = get_canonical_keyword(base)
local without_colon = trimmed:gsub("^:", "")
local mods_part = without_colon:sub(#base + 1)
local kw_param = normalize_keyword(canonical_base .. mods_part)
EtymonParser.parse_keyword_modifiers(kw_param)
return kw_param
end
local function get_keyword_mod_names()
local names = {}
for mod_name in pairs(EtymonParser.keyword_param_mods) do
names[mod_name] = true
end
return names
end
local function parse_inline_ety_run(ety_string)
local body = ety_string or ""
if body == "" then
error("Empty inline etymology")
end
local keyword_mod_names = get_keyword_mod_names()
local pos = 1
local len = #body
local function parse_err(msg)
error(msg .. " in inline etymology: '" .. body .. "'")
end
local function peek_double()
return body:sub(pos, pos + 1) == "<<"
end
local function mod_name_from_unwrapped(unwrapped)
return unwrapped:match("^<([^:>]+)")
end
local function is_keyword_mod(unwrapped)
local name = mod_name_from_unwrapped(unwrapped)
return name and keyword_mod_names[name] or false
end
local function read_double_bracket()
if not peek_double() then
return nil
end
local start = pos
pos = pos + 2
while pos <= len - 1 do
if body:sub(pos, pos + 1) == ">>" then
local token = body:sub(start, pos + 1)
pos = pos + 2
return token, token:sub(2, -2)
end
pos = pos + 1
end
parse_err("Unmatched <<")
end
local function read_angle_cell()
if body:sub(pos, pos) ~= "<" or peek_double() then
return nil
end
local open = pos
pos = pos + 1
local depth = 1
local i = pos
while i <= len do
local ch = body:sub(i, i)
if ch == "<" then
depth = depth + 1
elseif ch == ">" then
depth = depth - 1
if depth == 0 then
local inner = body:sub(open + 1, i - 1)
pos = i + 1
return inner
end
end
i = i + 1
end
parse_err("Unmatched <")
end
local function read_bare_run()
local start = pos
while pos <= len and body:sub(pos, pos) ~= "<" do
pos = pos + 1
end
return body:sub(start, pos - 1)
end
local function absorb_double_keyword_mods(keyword_str)
while peek_double() do
local saved = pos
local _, unwrapped = read_double_bracket()
if is_keyword_mod(unwrapped) then
keyword_str = keyword_str .. unwrapped
else
pos = saved
break
end
end
return keyword_str
end
local kw_start = pos
while pos <= len and body:sub(pos, pos) ~= "<" do
pos = pos + 1
end
local keyword = body:sub(kw_start, pos - 1)
if keyword:match("^%s*$") then
parse_err("Missing keyword")
end
keyword = absorb_double_keyword_mods(keyword)
local cells = {}
while pos <= len do
if peek_double() then
local _, unwrapped = read_double_bracket()
if is_keyword_mod(unwrapped) then
parse_err("Unexpected keyword modifier " .. unwrapped .. " outside of a keyword")
end
table.insert(cells, "+" .. unwrapped)
elseif body:sub(pos, pos) == "<" then
local inner = read_angle_cell()
if inner ~= "" then
table.insert(cells, inner)
end
else
local bare = read_bare_run()
if bare ~= "" then
if bare:sub(1, 1) ~= ":" then
parse_err("Unexpected bare text '" .. bare .. "' (use :keyword for nested keywords in inline etymology)")
end
if not is_keyword(bare, true) then
parse_err("Invalid keyword '" .. bare .. "' in inline etymology")
end
table.insert(cells, absorb_double_keyword_mods(bare))
end
end
end
return {
keyword = keyword,
cells = cells,
}
end
function EtymonParser.inline_ety_to_pipe(ety_string)
local run = parse_inline_ety_run(ety_string)
if not run.keyword or run.keyword:match("^%s*$") then
return "|"
end
local pipe_parts = { normalize_keyword_param(M.string_utilities.trim(run.keyword)) }
for _, segment in ipairs(run.cells) do
if is_keyword(segment, true) then
table.insert(pipe_parts, normalize_keyword_param(segment))
else
table.insert(pipe_parts, segment)
end
end
return "|" .. table.concat(pipe_parts, "|") .. "|"
end
function EtymonParser.pipe_to_inline_ety(pipe_string)
local cells = {}
for cell in pipe_string:gmatch("([^|]+)") do
if cell ~= "" then
table.insert(cells, cell)
end
end
if #cells == 0 then
return ""
end
local inline_parts = {}
for index, cell in ipairs(cells) do
local base = get_keyword_base(cell)
if base and M.data.keywords[base] then
local without_colon = cell:gsub("^:", "")
local kw_base, mods = without_colon:match("^([^<]+)(.*)$")
local inline_kw = (kw_base or without_colon) .. (mods or ""):gsub("<([^>]+)>", "<<%1>>")
if index > 1 then
inline_kw = ":" .. inline_kw
end
table.insert(inline_parts, inline_kw)
elseif cell:sub(1, 1) == "+" then
local mod = cell:sub(2)
if mod:match("^<.->$") then
mod = mod:sub(2, -2)
end
table.insert(inline_parts, "<<" .. mod .. ">>")
else
table.insert(inline_parts, "<" .. cell .. ">")
end
end
return table.concat(inline_parts, "")
end
function EtymonParser.parse_inline_ety(ety_string, context_lang)
local run = parse_inline_ety_run(ety_string)
local keyword = M.string_utilities.trim(run.keyword)
reject_removed_surf_keyword(":" .. keyword)
if not is_keyword(keyword, true) then
error("Invalid keyword '" .. keyword .. "' in inline etymology <ety:" .. keyword .. "...>")
end
local args = { context_lang:getCode(), normalize_keyword_param(keyword) }
for _, segment in ipairs(run.cells) do
if is_keyword(segment, true) then
table.insert(args, normalize_keyword_param(segment))
else
table.insert(args, segment)
end
end
return args
end
function EtymonParser.parse_etymon(param, context_lang)
if is_keyword(param) then
return nil
end
if type(param) ~= "string" then
return nil
end
local lang, rest
local is_family = false
local before_bracket = param:match("^([^<]*)") or param
local lang_code, rest_match = before_bracket:match("^([a-zA-Z][a-zA-Z0-9._-]*):(.*)$")
if lang_code then
local potential_lang = Util.get_lang(lang_code, true)
if potential_lang then
lang = potential_lang
rest = param:sub(#lang_code + 2)
else
local potential_family = Util.get_family(lang_code)
if potential_family then
lang = potential_family
rest = param:sub(#lang_code + 2)
is_family = true
else
lang = context_lang
rest = param
end
end
else
lang = context_lang
rest = param
end
M.tracking.track_term(rest)
if rest == "" or rest == "+" then
return {
lang = lang,
term = nil,
unknown_term = true,
is_family = is_family,
}
end
if rest == "-" then
return {
lang = lang,
term = nil,
suppress_term = true,
is_family = is_family,
}
end
if not rest:find("<", 1, true) then
return {
lang = lang,
term = M.string_utilities.trim(rest),
is_family = is_family,
}
end
local term_text = rest:match("^([^<]*)") or ""
local is_unknown = (term_text == "" or term_text == "+")
local is_suppress = (term_text == "-")
local function generate_obj(ignored_term)
return { term = (is_unknown or is_suppress) and nil or M.string_utilities.trim(term_text) }
end
local rest_with_defaults = Util.add_boolean_defaults(rest, EtymonParser.etymon_param_mods)
local parsed_obj = M.parse_utilities.parse_inline_modifiers(rest_with_defaults,
{ param_mods = get_clean_param_mods(EtymonParser.etymon_param_mods), generate_obj = generate_obj })
if parsed_obj.id and parsed_obj.id:match("^!") then
parsed_obj.id = parsed_obj.id:sub(2)
parsed_obj.override = true
end
parsed_obj.lang = lang
parsed_obj.is_family = is_family
if is_unknown then
parsed_obj.unknown_term = true
elseif is_suppress then
parsed_obj.suppress_term = true
end
return parsed_obj
end
function EtymonParser.validate(lang, args, id, title, pos, starts_with_lang_code)
-- id is now optional, so only validate if provided
if id then
if mw.ustring.len(id) < 2 then
error("The `id` parameter must have at least two characters.")
end
if id == title or id == Util.get_page_data().pagename then
error("The `id` parameter must not be the same as the page title.")
end
end
local valid_pos = { prefix = true, suffix = true, interfix = true, infix = true, root = true, word = true }
if pos and not valid_pos[pos] then
error("Unknown value provided for `pos`. Valid values: " .. table.concat(require("Module:table").keysToList(valid_pos), ", ") .. ".")
end
local current_keyword = "from"
local current_keyword_explicit = false
local keyword_etymons = {}
local keywords = M.data.keywords
local function checkKeyword()
local config = keywords[current_keyword]
if current_keyword == "from" and not current_keyword_explicit and #keyword_etymons == 0 then
keyword_etymons = {}
return
end
EtymonParser.check_etymon_limits(#keyword_etymons, config, "`:" .. current_keyword .. "`")
keyword_etymons = {}
end
local start_index = starts_with_lang_code and 2 or 1
for i = start_index, #args do
local param = args[i]
if type(param) ~= "string" then
elseif param:sub(1, 1) == ":" and not is_keyword(param) then
reject_removed_surf_keyword(param)
error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?")
elseif is_keyword(param) then
checkKeyword()
current_keyword = get_canonical_keyword(get_keyword(param))
current_keyword_explicit = true
else
local etymon_data = EtymonParser.parse_etymon(param, lang)
if etymon_data then
table.insert(keyword_etymons, param)
EtymonParser.check_keyword_term(etymon_data, lang, current_keyword)
-- Check modifier restrictions
EtymonParser.check_modifier_restrictions(etymon_data, current_keyword, EtymonParser.etymon_param_mods)
-- postype must be "root" or "word"
local VALID_POSTYPES = { root = true, word = true }
if etymon_data.postype and not VALID_POSTYPES[etymon_data.postype] then
error("Invalid <postype:" .. etymon_data.postype .. ">; must be \"root\" or \"word\".")
end
if etymon_data.ety then
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
EtymonParser.validate(etymon_data.lang, inline_args, nil, nil, nil, true)
end
else
table.insert(keyword_etymons, param)
end
end
end
checkKeyword()
end
local DataRetriever = {}
local function format_etymon_id_hint(id_data, idx)
local id = type(id_data) == "table" and id_data.id or id_data
local pos = type(id_data) == "table" and id_data.pos
if id and id ~= "" and id ~= "*" then
return '"' .. id .. '"'
end
if pos and pos ~= "" then
return "unnamed (|pos=" .. pos .. "|)"
end
return "etymon #" .. idx .. " (no |id= on page)"
end
local function etymon_target_page_link(page, norm_lang)
return M.links.full_link({
term = page,
lang = norm_lang,
no_generate_alternants = true,
}, "term")
end
-- Summarize {{etymon}} id slots on a linked page for preview warnings.
local function summarize_available_etymon_ids(ids)
local id_list = {}
local all_idless = true
local target_has_idless = false
local any_pos = false
for i, id_data in ipairs(ids) do
local id = type(id_data) == "table" and id_data.id or id_data
local pos = type(id_data) == "table" and id_data.pos
if id and id ~= "" and id ~= "*" then
all_idless = false
else
target_has_idless = true
end
if pos and pos ~= "" then
any_pos = true
end
table.insert(id_list, format_etymon_id_hint(id_data, i))
end
return {
id_list = id_list,
all_idless = all_idless,
target_has_idless = target_has_idless,
any_pos = any_pos,
count = #ids,
options_text = mw.text.listToText(id_list),
}
end
local function ambiguous_etymon_suggestion(page_link, summary)
if summary.all_idless then
if summary.any_pos then
return " None set `|id=` yet; add a unique `|id=` to each on " .. page_link
.. ", then `<id:identifier>` after the term here. Section order / hints: "
.. summary.options_text .. "."
end
return " None set `|id=` yet; add a unique `|id=` to each {{etymon}} in that section from top to bottom, then `<id:identifier>` after the term here (same value as `|id=`)."
end
return " Specify which one with `<id:identifier>` after the term. Options: " .. summary.options_text .. "."
end
local function warn_ambiguous_etymon_link(page, norm_lang, ids, is_toplevel)
local page_link = etymon_target_page_link(page, norm_lang)
local summary = summarize_available_etymon_ids(ids)
if is_toplevel and summary.target_has_idless then
__state.linked_page_multiple_etymons_idless = true
end
local lang_name = norm_lang:getCanonicalName()
local lead = "Etymology link to " .. page_link .. " is ambiguous (" .. summary.count
.. " {{etymon}} templates for " .. lang_name .. ")."
Util.add_warning(lead .. ambiguous_etymon_suggestion(page_link, summary), true)
end
local function is_mismatched_explicit_id(base_key, cached_args, parent_etymon)
return cached_args == M.data.STATUS.MISSING and not parent_etymon
and #(__state.available_etymon_ids[base_key] or {}) > 0
end
local function maybe_flag_partial_etymology_reference(base_key, etymon_data, cached_args, is_toplevel)
if not is_toplevel or __state.skip_partial_etymology_category then
return
end
if not __state.partial_etymology_targets[base_key] then
return
end
if etymon_data.id and type(cached_args) == "table" then
return
end
__state.linked_page_partial_etymology_sections = true
end
local function is_nonlemma_etymon_template(template_args)
return template_args and M.yesno(template_args.nl, false)
end
local function warn_mismatched_explicit_id(page, norm_lang, base_key, etymon_id)
local page_link = etymon_target_page_link(page, norm_lang)
local summary = summarize_available_etymon_ids(__state.available_etymon_ids[base_key] or {})
local lang_name = norm_lang:getCanonicalName()
local lead = "Etymology link to " .. page_link .. " uses `<id:" .. etymon_id
.. ">`, but no {{etymon}} on that page has `|id=" .. etymon_id .. "|` for " .. lang_name .. "."
Util.add_warning(lead .. " Valid IDs: " .. summary.options_text .. ".", true)
end
-- Given an etymon data, scrape its page and cache the result in the global state object.
function DataRetriever.cache_page_etymons(etymon_page, etymon_title, key, etymon_lang, etymon_id, redirected_from, descendants_is_toplevel)
local content = etymon_title:getContent()
if not content then
__state.cached_etymon_args[key] = M.data.STATUS.REDLINK
return
end
-- Check if the linked page is a redirect. If it is, the template parsing
-- code below will be effectively skipped, and `scrape_page` will be called
-- again on the redirect target (see the bottom of this function)
local lang_section_for_descendants = nil
local redirect_target = etymon_title.redirect_target
if not redirect_target then
content = M.pages.get_section(content, etymon_lang:getFullName(), 2)
if not content then
__state.cached_etymon_args[key] = M.data.STATUS.MISSING
return
end
lang_section_for_descendants = content
end
local etymon_lang_code = etymon_lang:getFullCode()
local lang_page_key = etymon_lang_code .. ":" .. etymon_page
local found_templates_for_lang = {}
local found_ids = {}
local get_node_class = M.template_parser.class_else_type
-- Look for all {{etymon}} templates within the page content using the template parser
-- This way the same page is never parsed more than once
-- Build a map from senseids to their parent etymonids.
local active_etymon_args = nil
local etymology_section_count = 0
local etymology_sections_with_etymon = 0
local current_etymology_has_etymon = false
local current_etymology_has_nonlemma = false
local function finalize_current_etymology_section()
if etymology_section_count == 0 then
return
end
if current_etymology_has_etymon or current_etymology_has_nonlemma then
etymology_sections_with_etymon = etymology_sections_with_etymon + 1
end
current_etymology_has_etymon = false
current_etymology_has_nonlemma = false
end
for node in M.template_parser.parse(content):iterate_nodes() do
local node_class = get_node_class(node)
if node_class == "heading" then
-- A new L2 or etymology section acts as a barrier: an {{etymon}} usage
-- used previously cannot be the parent of any subsequent senseids.
-- Note that we don't have to check for L2s due to the usage of `M.pages.get_section` above.
if node:get_name():find("^Etymology") then
finalize_current_etymology_section()
etymology_section_count = etymology_section_count + 1
active_etymon_args = nil
end
elseif node_class == "template" then
local template_name = node:get_name()
if template_name == "etymon" then
local template_args = node:get_arguments()
-- Check if this etymon is for our language
if template_args[1] == etymon_lang_code then
if is_nonlemma_etymon_template(template_args) then
if etymology_section_count > 0 then
current_etymology_has_nonlemma = true
end
else
if etymology_section_count > 0 then
current_etymology_has_etymon = true
end
table.insert(found_templates_for_lang, template_args)
if template_args.id then
local etymon_key = lang_page_key .. ":" .. template_args.id
__state.cached_etymon_args[etymon_key] = template_args
__state.cached_etymon_pages[etymon_key] = tostring(etymon_page)
table.insert(found_ids, template_args.id)
active_etymon_args = template_args
else
-- Store idless etymon with default key
local etymon_key = lang_page_key .. ":*"
__state.cached_etymon_args[etymon_key] = template_args
__state.cached_etymon_pages[etymon_key] = tostring(etymon_page)
table.insert(found_ids, "*")
active_etymon_args = template_args
end
end
end
elseif active_etymon_args and template_name == "senseid" then
local template_args = node:get_arguments()
-- This should always be true for proper usages of {{senseid}}.
if template_args[1] == etymon_lang_code and template_args[2] then
local sense_id_key = lang_page_key .. ":" .. template_args[2]
__state.senseid_parent_etymon[sense_id_key] = active_etymon_args
__state.cached_etymon_pages[sense_id_key] = tostring(etymon_page)
end
end
end
end
finalize_current_etymology_section()
if lang_section_for_descendants
and etymology_section_count > 1
and etymology_sections_with_etymon > 0
and etymology_sections_with_etymon < etymology_section_count
then
__state.partial_etymology_targets[lang_page_key] = true
end
if descendants_is_toplevel and lang_section_for_descendants and #found_templates_for_lang > 0 then
M.descendants.cache_page_checks({
lang_section = lang_section_for_descendants,
etymon_lang_code = etymon_lang_code,
found_templates_for_lang = found_templates_for_lang,
entry_title = __state.entry_title,
entry_lang_code = __state.entry_lang_code,
entry_lang = __state.entry_lang_code and Util.get_lang(__state.entry_lang_code, true) or nil,
cached_descendants_checks = __state.cached_descendants_checks,
lang_page_key = lang_page_key,
redirected_from = redirected_from,
})
end
local id_data_list = {}
for _, args in ipairs(found_templates_for_lang) do
local id = args.id or "*"
table.insert(id_data_list, { id = id, pos = args.pos })
end
__state.available_etymon_ids[lang_page_key] = id_data_list
if #found_templates_for_lang == 1 then
__state.single_etymons[lang_page_key] = found_templates_for_lang[1]
end
if redirected_from and __state.available_etymon_ids[lang_page_key] then
__state.available_etymon_ids[redirected_from] = __state.available_etymon_ids[redirected_from] or {}
for _, id_data in ipairs(__state.available_etymon_ids[lang_page_key]) do
table.insert(__state.available_etymon_ids[redirected_from], id_data)
end
end
if __state.cached_etymon_args[key] ~= nil or __state.senseid_parent_etymon[key] ~= nil then
-- All done!
return
elseif redirect_target and not redirected_from then
-- Try scraping the redirect.
etymon_page = redirect_target.prefixedText
DataRetriever.cache_page_etymons(etymon_page, redirect_target, lang_page_key .. ":" .. etymon_id, etymon_lang, etymon_id, lang_page_key, descendants_is_toplevel)
__state.cached_etymon_args[key] = __state.cached_etymon_args[etymon_lang_code .. ":" .. etymon_page .. ":" .. etymon_id]
else
__state.cached_etymon_args[key] = M.data.STATUS.MISSING
end
end
local function has_linkable_term(etymon_data)
if etymon_data.is_family or etymon_data.suppress_term or etymon_data.unknown_term then
return false
end
local term = etymon_data.term
if term == nil or term == "" then
return false
end
return M.string_utilities.trim(term) ~= ""
end
local function record_term_id_tracking(etymon_data)
if not has_linkable_term(etymon_data) then
return
end
local term_page = M.links.get_link_page(etymon_data.term, etymon_data.lang)
M.tracking.record_term_id_usage(__state.id_stats, etymon_data, term_page)
end
-- Given an etymon object, scrape its page (if necessary) and return its own etymon arguments as well as the page name.
function DataRetriever.get_etymon_args(etymon_data, is_toplevel)
if not has_linkable_term(etymon_data) then
return M.data.STATUS.MISSING, nil, nil, nil
end
local page = M.links.get_link_page(etymon_data.term, etymon_data.lang)
local norm_lang = Util.get_norm_lang(etymon_data.lang)
local base_key = norm_lang:getFullCode() .. ":" .. page
if etymon_data.id then
local key = base_key .. ":" .. etymon_data.id
local cached_args = __state.cached_etymon_args[key] or __state.senseid_parent_etymon[key]
if cached_args == nil then
local title = mw.title.new(page)
if not title then error('Invalid page title "' .. page .. '" encountered.') end
DataRetriever.cache_page_etymons(page, title, key, norm_lang, etymon_data.id, nil, is_toplevel)
end
cached_args = __state.cached_etymon_args[key] or __state.senseid_parent_etymon[key] -- refresh
-- Get etymon_id from parent if this was resolved via senseid
local parent_etymon = __state.senseid_parent_etymon[key]
local resolved_etymon_id = parent_etymon and parent_etymon.id
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = {
explicit_id = etymon_data.id,
parent_etymon = parent_etymon,
},
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, key, norm_lang, etymon_data.id, nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = {
explicit_id = etymon_data.id,
parent_etymon = parent_etymon,
},
})
end
end
local mismatched_id = is_mismatched_explicit_id(base_key, cached_args, parent_etymon)
if mismatched_id and is_toplevel then
__state.has_mismatched_id = true
M.tracking.record_mismatched_id_usage(__state.id_stats, norm_lang, page, etymon_data.id)
warn_mismatched_explicit_id(page, norm_lang, base_key, etymon_data.id)
end
maybe_flag_partial_etymology_reference(base_key, etymon_data, cached_args, is_toplevel)
return cached_args, __state.cached_etymon_pages[key], resolved_etymon_id, descendants_check
else
__state.used_idless_etymon = true
if is_toplevel then
__state.toplevel_idless_etymon = true
end
if __state.available_etymon_ids[base_key] == nil then
local title = mw.title.new(page)
if not title then error('Invalid page title "' .. page .. '" encountered.') end
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, is_toplevel)
end
local ids = __state.available_etymon_ids[base_key] or {}
local count = #ids
-- Try to filter by postype if available and we have multiple candidates
if count > 1 and etymon_data.postype then
local matching_ids = {}
for _, id_data in ipairs(ids) do
if id_data.pos == etymon_data.postype then
table.insert(matching_ids, id_data)
end
end
if #matching_ids == 1 then
local matched_id = matching_ids[1].id
local matched_key = base_key .. ":" .. matched_id
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "postype")
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = { id = matched_id },
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = { id = matched_id },
})
end
end
local matched_args = __state.cached_etymon_args[matched_key]
maybe_flag_partial_etymology_reference(base_key, etymon_data, matched_args, is_toplevel)
return matched_args, __state.cached_etymon_pages[matched_key], nil, descendants_check
end
end
if count == 1 then
local only_id_data = ids[1]
local only_id = (type(only_id_data) == "table" and only_id_data.id) or only_id_data or "*"
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "single")
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = { id_data = only_id_data },
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = { id_data = only_id_data },
})
end
end
local single_args = __state.single_etymons[base_key]
maybe_flag_partial_etymology_reference(base_key, etymon_data, single_args, is_toplevel)
return single_args, __state.cached_etymon_pages[base_key .. ":" .. only_id], nil, descendants_check
elseif count > 1 then
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "ambiguous")
warn_ambiguous_etymon_link(page, norm_lang, ids, is_toplevel)
maybe_flag_partial_etymology_reference(base_key, etymon_data, M.data.STATUS.AMBIGUOUS, is_toplevel)
return M.data.STATUS.AMBIGUOUS, nil, nil, nil
else
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "missing")
maybe_flag_partial_etymology_reference(base_key, etymon_data, M.data.STATUS.MISSING, is_toplevel)
return M.data.STATUS.MISSING, nil, nil, nil
end
end
end
local function keyword_invisible_in_tree(keyword_info)
if not keyword_info then
return false
end
local inv = keyword_info.invisible
return inv == "all" or inv == true or inv == "tree"
end
-- True when the node has at least one top-level child container visible in the tree.
local function node_has_visible_tree_children(node)
for _, container in ipairs(node.children or {}) do
if not keyword_invisible_in_tree(container.keyword_info) then
return true
end
end
return false
end
-- Count visible term nodes in the tree.
local function get_visible_tree_depth(node, skip_child_rendering)
local max_depth = 1
if skip_child_rendering or not node then
return max_depth
end
for _, container in ipairs(node.children or {}) do
local keyword_info = container.keyword_info
if not keyword_invisible_in_tree(keyword_info) then
local skip_grandchildren = keyword_info and keyword_info.no_child_categories
for _, term in ipairs(container.terms or {}) do
if term.is_duplicate then
if term.original_has_children then
max_depth = math.max(max_depth, 2)
end
else
max_depth = math.max(max_depth, 1 + get_visible_tree_depth(term, skip_grandchildren))
end
end
end
end
return max_depth
end
local function as_param_list(val)
if val == nil then
return {}
end
if type(val) == "table" then
return val
end
if type(val) == "string" and val ~= "" then
return { val }
end
return {}
end
local TreeBuilder = {}
-- Build a unique key for deduplication in the seen table
function TreeBuilder.build_key(lang, title, args)
local norm_lang_code = Util.get_norm_lang(lang):getFullCode()
local is_table = type(args) == "table"
local id = (is_table and args.id) or ""
if title then
return norm_lang_code .. ":" .. M.links.get_link_page(title, lang) .. ":" .. id
end
if is_table and args.status == M.data.STATUS.INLINE then
local content_parts = {}
for i = 1, #args do
content_parts[i] = tostring(args[i])
end
return norm_lang_code .. ":*:" .. id .. "\0" .. table.concat(content_parts, "\0")
end
return norm_lang_code .. ":*:" .. id
end
-- Copy parsed etymon modifiers onto a tree/supplement term node.
function TreeBuilder.apply_etymon_fields(term, etymon_data)
term.id = etymon_data.id
term.gloss = etymon_data.gloss
term.tr = etymon_data.tr
term.ts = etymon_data.ts
term.alt = etymon_data.alt
term.genders = etymon_data.genders
term.pos = etymon_data.pos
term.ng = etymon_data.ng
term.infl = etymon_data.infl
term.refs = etymon_data.refs
term.is_uncertain = etymon_data.unc
term.lit = etymon_data.lit
term.q = etymon_data.q
term.qq = etymon_data.qq
term.l = etymon_data.l
term.ll = etymon_data.ll
term.suppress_term = etymon_data.suppress_term
term.unknown_term = etymon_data.unknown_term
term.is_family = etymon_data.is_family
term.override = etymon_data.override
term.aftype = etymon_data.aftype
term.postype = etymon_data.postype
term.bor = etymon_data.bor
term.lbor = etymon_data.lbor
term.slbor = etymon_data.slbor
end
function TreeBuilder.build_supplement_term(etymon_data, entry_lang, supplement_type)
EtymonParser.check_supplement_term(etymon_data, entry_lang, supplement_type)
local term = {
lang = etymon_data.lang,
title = etymon_data.term,
children = {},
status = M.data.STATUS.OK,
}
TreeBuilder.apply_etymon_fields(term, etymon_data)
return term
end
function TreeBuilder.build_supplement_terms(entry_lang, supplement_type, param_value)
local terms = {}
for _, term_param in ipairs(as_param_list(param_value)) do
if type(term_param) == "string" and term_param ~= "" then
local etymon_data = EtymonParser.parse_etymon(term_param, entry_lang)
if etymon_data then
table.insert(terms, TreeBuilder.build_supplement_term(etymon_data, entry_lang, supplement_type))
end
end
end
return terms
end
-- Attach a |param= supplement defined in etymon_data.supplements (e.g. doublet=).
function TreeBuilder.append_term_supplement(data_tree, entry_lang, supplement_type, param_value)
local config = M.data.supplements[supplement_type]
if not config then
error("Unknown supplement '" .. tostring(supplement_type) .. "'.")
end
local terms = TreeBuilder.build_supplement_terms(entry_lang, supplement_type, param_value)
if #terms == 0 then
return
end
data_tree.supplements = data_tree.supplements or {}
table.insert(data_tree.supplements, {
type = supplement_type,
config = config,
terms = terms,
})
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, supplement_type, entry_lang, entry_lang, true)
end
function TreeBuilder.build(lang, title, args, seen, depth, stop_recursion)
seen = seen or {}
depth = depth or 0
local is_toplevel = (depth == 0)
if depth > __state.max_depth_reached then
__state.max_depth_reached = depth
end
__state.total_nodes = __state.total_nodes + 1
local lang_code = lang:getCode()
__state.language_count[lang_code] = (__state.language_count[lang_code] or 0) + 1
local current_id = (type(args) == "table" and args.id) or ""
local key = TreeBuilder.build_key(lang, title, args)
local node = { lang = lang, title = title, id = current_id, args = args, children = {}, status = M.data.STATUS.OK }
if type(args) ~= "table" or seen[key] then
node.status = args or M.data.STATUS.MISSING
-- Mark as duplicate if we've seen this node before
if seen[key] then
node.is_duplicate = true
node.duplicate_key = key
local original_node = seen[key]
if type(original_node) == "table" and original_node.children and #original_node.children > 0 then
node.original_has_children = true
end
end
return node
end
node.status = args.status or M.data.STATUS.OK
seen[key] = node
-- If stop_recursion is set, skip parsing children but check for visible children
if stop_recursion then
local keywords = M.data.keywords
local has_visible_children = false
for i = 2, #args do
local param = args[i]
if type(param) == "string" then
local keyword_base = get_keyword_base(param)
if keyword_base and keywords[keyword_base] then
local _, kw_modifiers = EtymonParser.parse_keyword_modifiers(param:sub(1, 1) == ":" and param or (":" .. param))
if not keyword_invisible_in_tree(get_effective_keyword_info(keyword_base, kw_modifiers)) then
has_visible_children = true
break
end
elseif param:sub(1, 1) ~= ":" then
-- It's a term (not a keyword), so there are visible children
has_visible_children = true
break
end
end
end
node.has_visible_children = has_visible_children
return node
end
-- Parse args into keyword containers
local current_keyword = "from"
local current_keyword_modifiers = {}
local current_container = nil
local function ensure_container()
if not current_container or current_container.keyword ~= current_keyword then
local keyword_info = get_effective_keyword_info(current_keyword, current_keyword_modifiers)
current_container = {
keyword = current_keyword,
keyword_info = keyword_info,
keyword_modifiers = current_keyword_modifiers,
terms = {},
}
table.insert(node.children, current_container)
-- Override keyword text/phrase for nominalization with <g:code>
if current_keyword_modifiers.g and current_keyword == "nominalization" then
local labels = get_nominalization_label_for_g(current_keyword_modifiers.g)
if not labels then
local codes = {}
for c in pairs(M.data.nominalization_g_codes) do table.insert(codes, c) end
table.sort(codes)
error("Invalid <g:" .. tostring(current_keyword_modifiers.g) .. ">. Supported codes for nominalization: " .. table.concat(codes, ", "))
end
current_container.keyword_info = copy_keyword_info(keyword_info)
current_container.keyword_info.text = labels.text
current_container.keyword_info.phrase = labels.phrase
end
end
return current_container
end
local parse_context_lang = Util.resolve_context_lang(lang, args)
for i = 2, #args do
local param = args[i]
if is_keyword(param) then
local keyword, modifiers = EtymonParser.parse_keyword_modifiers(param)
if not keyword then
error("Invalid keyword '" .. param .. "'.")
end
current_keyword = keyword
current_keyword_modifiers = modifiers
current_container = nil -- Force new container for new keyword
elseif type(param) == "string" and param:sub(1, 1) == ":" then
reject_removed_surf_keyword(param)
error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?")
elseif type(param) == "string" then
local etymon_data = EtymonParser.parse_etymon(param, parse_context_lang)
if etymon_data then
-- Track keyword usage at top level
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, current_keyword, lang, etymon_data.lang, is_toplevel)
local term_node = {}
local container
-- Handle suppress_term (-) and unknown_term (empty or +) directly
if etymon_data.suppress_term or etymon_data.unknown_term then
container = ensure_container()
if etymon_data.ety then
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
inline_args.id = etymon_data.id
inline_args.status = M.data.STATUS.INLINE
term_node = TreeBuilder.build(etymon_data.lang, nil, inline_args, seen, depth + 1)
else
term_node = {
lang = etymon_data.lang,
children = {},
status = M.data.STATUS.OK,
}
end
TreeBuilder.apply_etymon_fields(term_node, etymon_data)
else
-- Regular term: fetch arguments from page
record_term_id_tracking(etymon_data)
local etymon_args, page_of, resolved_etymon_id, descendants_check =
DataRetriever.get_etymon_args(etymon_data, is_toplevel)
-- Check for <ety> inline parameter doesn't override the scraped arguments, unless the latter are missing
if etymon_data.ety then
if etymon_args == M.data.STATUS.REDLINK or etymon_args == M.data.STATUS.MISSING then
__state.current_page_has_inline_etymology = true
if is_toplevel then
__state.toplevel_has_inline_etymology = true
end
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
-- Track inline ety keywords too
local inline_keyword = get_keyword(inline_args[2], true)
if inline_keyword and #inline_args >= 3 then
local inline_etymon = EtymonParser.parse_etymon(inline_args[3], etymon_data.lang)
if inline_etymon then
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, inline_keyword, etymon_data.lang, inline_etymon.lang, is_toplevel)
end
end
inline_args.id = etymon_data.id
inline_args.status = M.data.STATUS.INLINE
etymon_args = inline_args
term_node.page_of = __state.cached_etymon_pages[key] -- term node is on the same page as the parent
else
-- Scraped arguments exist, <ety> is redundant and ignored
__state.current_page_has_redundant_etymology = true
if is_toplevel then
__state.toplevel_redundant_etymology = true
end
end
end
-- Ensure container exists before checking keyword info
container = ensure_container()
-- Check if current keyword has no_child_categories - if so, stop recursion
local keyword_info = container.keyword_info
local should_stop_recursion = (stop_recursion or (keyword_info and keyword_info.no_child_categories))
term_node = TreeBuilder.build(etymon_data.lang, etymon_data.term, etymon_args, seen, depth + 1, should_stop_recursion)
term_node.target_key = Util.get_norm_lang(etymon_data.lang):getFullCode() ..
":" .. M.links.get_link_page(etymon_data.term, etymon_data.lang)
term_node.etymon_id = resolved_etymon_id -- The actual etymon id when resolved via senseid
term_node.page_of = page_of
TreeBuilder.apply_etymon_fields(term_node, etymon_data)
term_node.missing_descendants_header, term_node.missing_descendants_entry =
M.descendants.get_term_sync_flags(current_keyword, term_node.status, descendants_check)
end
table.insert(container.terms, term_node)
end
end
end
return node
end
-- Convert etymology tree to JSON-serializable table
local function tree_to_json(node)
local obj = {
term = node.title,
lang = node.lang:getCode(),
lang_name = node.lang:getCanonicalName(),
id = (node.id and node.id ~= "") and node.id or nil,
status = node.status,
is_uncertain = node.is_uncertain or nil,
is_duplicate = node.is_duplicate or nil,
gloss = node.gloss,
transliteration = node.tr,
transcription = node.ts,
alt = node.alt,
g = node.genders,
pos = node.pos,
ng = node.ng,
infl = node.infl,
children = {},
}
for _, container in ipairs(node.children or {}) do
local keyword_info = container.keyword_info
if keyword_info then
local container_obj = {
keyword = container.keyword,
keyword_label = keyword_info.text,
keyword_abbrev = keyword_info.abbrev,
is_group = keyword_info.is_group or nil,
is_invisible = keyword_info.invisible or nil,
is_uncertain = (container.keyword_modifiers and container.keyword_modifiers.unc) or nil,
terms = {},
}
for _, term in ipairs(container.terms or {}) do
table.insert(container_obj.terms, tree_to_json(term))
end
table.insert(obj.children, container_obj)
end
end
return obj
end
-- Build and return the etymology data tree for a given term.
function export.get_tree(lang, title, args, options)
options = options or {}
__state.entry_title = title
__state.entry_lang_code = lang:getCode()
__state.id_stats = M.tracking.new_id_stats()
__state.skip_partial_etymology_category = options.skip_partial_etymology_category == true
if options.validate then
EtymonParser.validate(lang, args, options.id, title, options.pos, false)
end
local lang_code = lang:getCode()
local start_index = (args[1] == lang_code) and 2 or 1
local tree_args = { [1] = lang_code, id = options.id or args.id }
for i = start_index, #args do
table.insert(tree_args, args[i])
end
__state.cached_etymon_args[lang_code .. ":" .. title .. ":" .. (tree_args.id or "")] = tree_args
local ety_data_tree = TreeBuilder.build(lang, title, tree_args)
if options.json then
return M.JSON.toJSON(tree_to_json(ety_data_tree))
end
return ety_data_tree
end
-- Given a language code, page name and optionally the id= parameter,
-- render the tree and only the etymology tree for the relevant page.
-- Fetches and parses the corresponding {{etymon}} from the requested page,
-- and any further pages needed to render the tree.
-- Parameters can be passed either through the #invoke or as
-- template parameters *through* an #invoke.
function export.render_tree_for_etymon_on_page(frame)
local frame_args = frame.args
local parent_args = frame:getParent().args
local langcode = frame_args[1] or parent_args[1]
local pagename = frame_args[2] or parent_args[2]
local id = frame_args["id"] or parent_args["id"]
local display_title = frame_args["title"] or parent_args["title"]
local parsed_title = mw.title.new(pagename, 0)
local title
if parsed_title.namespace == 0 then
title = M.pages.safe_page_name(parsed_title)
elseif parsed_title.namespace == 118 then
title = "*" .. M.pages.safe_page_name(parsed_title)
else
error("Unsupported namespace for render_tree_for_etymon_on_page: " .. parsed_title.namespace)
end
local lang = Util.get_lang(langcode)
__state.entry_title = title
__state.entry_lang_code = lang:getCode()
__state.id_stats = M.tracking.new_id_stats()
-- Construct etymon_data for DataRetriever.get_args.
local etymon_data = {
lang = lang,
term = title,
id = id
}
local args, pagename = DataRetriever.get_etymon_args(etymon_data, true)
if args == M.data.STATUS.MISSING then
error("The etymon template was not found (language " ..
langcode ..
", title '" ..
title ..
"'" ..
(id and ", ID '" .. id .. "'" or ", no ID given") .. "). Page contents may have changed in the interim.")
end
local tree_title = display_title or title
if lang:stripDiacritics(M.links.remove_links(tree_title)) ~= lang:stripDiacritics(M.links.remove_links(title)) then
M.tracking.track_title_pagename_mismatch(lang)
end
reset_invocation_state()
local ety_data_tree = export.get_tree(lang, tree_title, args, {
validate = true,
id = id,
})
local output = {}
table.insert(output, M.template_styles("Module:etymon/styles.css"))
table.insert(output, M.tree.render({
data_tree = ety_data_tree,
format_term_func = function(term, is_toplevel)
return Util.format_term(term, is_toplevel, {
gloss = "suppress",
pos = "suppress",
lit = "suppress",
tree_ql = "suppress",
})
end,
}))
return table.concat(output)
end
function export.main(frame)
local parent_args = frame:getParent().args
local args = M.parameters.process(parent_args, M.parameters_data.etymon)
local lang = args[1]
local etymon_args = args[2]
local id = args.id
local title = args.title
local text = args.text
local tree = args.tree
local etydate = args.etydate
local doublet = args.doublet
local rfe = args.rfe
local etystub = args.etystub
local is_nonlemma = M.yesno(args.nl, false)
local page_data = Util.get_page_data()
if not title then
title = page_data.pagename
if page_data.namespace == "Rekonstruksi" then title = "*" .. title end
end
local entry_pagename = page_data.pagename
if page_data.namespace == "Rekonstruksi" then
entry_pagename = "*" .. entry_pagename
end
if lang:stripDiacritics(M.links.remove_links(title)) ~= lang:stripDiacritics(M.links.remove_links(entry_pagename)) then
M.tracking.track_title_pagename_mismatch(lang)
end
local norm_lang = Util.get_norm_lang(lang)
local norm_name = norm_lang:getCanonicalName()
local L2_list = page_data.L2_list
local current_L2
-- If the page contains exactly one L2, use it directly.
-- This avoids parser-dependent current-section detection.
if L2_list and L2_list.n == 1 then
current_L2 = L2_list[1]
if L2_matches_lang(current_L2, lang) then
current_L2 = nil
end
else
-- On multilingual pages, try the normal current-L2 detection.
current_L2 = M.pages.get_current_L2()
if current_L2 and L2_matches_lang(current_L2, lang) then
current_L2 = nil
end
-- Under Parsoid, get_current_L2() may return the wrong L2.
-- If the expected language exists somewhere on the page,
-- avoid throwing a false-positive error.
if current_L2 and L2_list then
for i = 1, L2_list.n do
if L2_matches_lang(L2_list[i], lang) then
current_L2 = nil
break
end
end
end
end
if current_L2 then
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if norm_lang:getCode() ~= lang:getCode() then
lang_desc = lang_desc ..
", normalized to " ..
norm_lang:getCode() .. " (" .. norm_name .. ")"
end
error(
"Language '" .. lang_desc ..
"' does not match the L2 header (" .. current_L2 .. ")."
)
end
reset_invocation_state()
local ety_data_tree = export.get_tree(lang, title, etymon_args, {
validate = true,
pos = args.pos,
id = id,
json = args.json,
skip_partial_etymology_category = is_nonlemma,
})
if args.json then
return ety_data_tree
end
local output = {}
local text_allowlist_mode = M.text_allowed.default_mode or "off"
if text and text_allowlist_mode ~= "off" and not Util.is_text_param_allowed_for_lang(lang) then
local msg = "Etymology texts (parameter <code>text=</code>) are not allowed for " .. lang:getFullName() ..
"; see [[Template:etymon#Text allowlist|Template:etymon § Text allowlist]] for the list of languages that may use the <code>text=</code> parameter."
if text_allowlist_mode == "error" then
error(msg)
else
Util.add_warning(msg, true)
end
end
local lang_exc = Util.get_lang_exception(lang)
if lang_exc and lang_exc.disallow then
local disallow = lang_exc.disallow
local error_text = " for " .. lang:getFullName()
if disallow.ref then
error_text = error_text .. "; see " .. disallow.ref
else
error_text = error_text .. "."
end
if tree and disallow.tree then
error("Etymology trees are not allowed" .. error_text)
end
if text and disallow.text then
error("Etymology texts are not allowed" .. error_text)
end
end
if etydate then
local etydate_param_mods = M.parameter_utilities.construct_param_mods {
{ group = "ref" },
{ param = "refn" },
{ param = "nocap", type = "boolean" },
}
local function generate_etydate_obj(etydate_text)
local etydate_specs = {}
for spec in etydate_text:gmatch("[^,]+") do
table.insert(etydate_specs, mw.text.trim(spec))
end
return { [1] = etydate_specs }
end
local parsed_etydate = M.parse_utilities.parse_inline_modifiers(etydate, { param_mods = etydate_param_mods, generate_obj = generate_etydate_obj })
local etydate_args = {
[1] = parsed_etydate[1],
nocap = parsed_etydate.nocap or false,
}
ety_data_tree.supplements = ety_data_tree.supplements or {}
table.insert(ety_data_tree.supplements, {
type = "etydate",
etydate_text = M.etydate.format_etydate(etydate_args, { omit_refs = true }),
etydate_refs = (parsed_etydate.refs and #parsed_etydate.refs > 0) and parsed_etydate.refs or nil,
})
end
TreeBuilder.append_term_supplement(ety_data_tree, lang, "doublet", doublet)
local has_visible_children = node_has_visible_tree_children(ety_data_tree)
-- Suppress trees for multiword entries and one-step chains
local visible_tree_depth = get_visible_tree_depth(ety_data_tree)
local is_trivial_tree = visible_tree_depth <= 2
local is_multiword = title:find("%s") ~= nil or title:find("_") ~= nil
if tree and (is_multiword or is_trivial_tree) then
tree = false
end
if tree then
table.insert(output, M.template_styles("Module:etymon/styles.css"))
table.insert(output, M.tree.render({
data_tree = ety_data_tree,
format_term_func = function(term, is_toplevel)
return Util.format_term(term, is_toplevel, {
gloss = "suppress",
pos = "suppress",
lit = "suppress",
tree_ql = "suppress",
})
end,
}))
end
local tree_disallowed = lang_exc and lang_exc.disallow and lang_exc.disallow.tree
local ety_tree_json = M.JSON.toJSON(tree_to_json(ety_data_tree))
local anchor = M.anchors.etymonid(lang, id, {
no_tree = args.notree,
title = title,
empty_tree = (not has_visible_children) or tree_disallowed,
ety_tree_json = ety_tree_json,
})
table.insert(output, anchor)
local text_stop_lang_missing = nil
if text then
local max_depth, stop_at_blue_link, stop_at_lang, stop_at_lang_or_bluelink
if text == "++" then
max_depth, stop_at_blue_link = false, false
elseif text == "+" then
max_depth, stop_at_blue_link = 1, false
elseif text == "*" then
max_depth, stop_at_blue_link = false, true
elseif text:match("^:[^*]+%*$") then
-- Stop at a specific language OR first bluelink after it, e.g., ":ota*"
-- If the target language is a redlink, continue to the first bluelink
local lang_code = text:match("^:([^*]+)%*$")
if lang_code and lang_code ~= "" then
local lang_obj = Util.get_lang(lang_code, true)
if lang_obj then
stop_at_lang_or_bluelink = lang_code
else
Util.add_warning('Invalid language code "' .. lang_code .. '" in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false
end
else
Util.add_warning('Empty language code in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false
end
elseif text:sub(1, 1) == ":" then
-- Stop at a specific language, e.g., ":ar" stops at first Arabic term
local lang_code = text:sub(2)
if lang_code ~= "" then
-- Validate the language code
local lang_obj = Util.get_lang(lang_code, true)
if lang_obj then
stop_at_lang = lang_code
else
Util.add_warning('Invalid language code "' .. lang_code .. '" in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false -- default to ++
end
else
Util.add_warning('Empty language code in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false -- default to ++
end
else
local num = tonumber(text)
if num and num >= 1 then
max_depth, stop_at_blue_link = num, false
else
error('Invalid text value "' ..
text .. '". Valid values are: "++" (full chain), "+" (first step only), "*" (until first blue link), a number (max steps), ":lang" (stop at language), or ":lang*" (stop at language or first bluelink if redlink)')
end
end
local text_output, text_render_meta = M.text.render({
data_tree = ety_data_tree,
format_term_func = Util.format_term,
lang_matches_stop_code = Util.lang_matches_stop_code,
max_depth = max_depth,
stop_at_blue_link = stop_at_blue_link,
curr_page = page_data.pagename,
nodot = args.nodot,
dot = args.dot,
stop_at_lang = stop_at_lang,
stop_at_lang_or_bluelink = stop_at_lang_or_bluelink,
})
table.insert(output, text_output)
if stop_at_lang and text_render_meta and not text_render_meta.stop_lang_reached then
M.tracking.track_text_stop_lang_missing(lang, stop_at_lang)
text_stop_lang_missing = stop_at_lang
end
end
if rfe then
table.insert(output, Util.expand_request_template(frame, "rfe", rfe, lang:getCode()))
end
if etystub then
table.insert(output, Util.expand_request_template(frame, "etystub", etystub, lang:getCode()))
end
if is_nonlemma then
table.insert(output, " " .. frame:expandTemplate({
title = "nonlemma",
args = {},
}))
end
local categories = {}
if Util.is_content_page() then
M.tracking.track_tree_metrics({
max_depth_reached = __state.max_depth_reached,
total_nodes = __state.total_nodes,
language_count = __state.language_count,
lang = lang,
})
categories = M.categories.build({
data_tree = ety_data_tree,
page_lang = lang,
available_etymon_ids = __state.available_etymon_ids,
senseid_parent_etymon = __state.senseid_parent_etymon,
get_norm_lang_func = Util.get_norm_lang,
lang_exc = lang_exc,
suppress_categories = lang_exc and lang_exc.suppress_categories,
nocat = args.nocat,
tree = tree,
text = text,
exnihilo = args.exnihilo,
toplevel_has_inline_etymology = __state.toplevel_has_inline_etymology,
toplevel_redundant_etymology = __state.toplevel_redundant_etymology,
toplevel_idless_etymon = __state.toplevel_idless_etymon,
has_mismatched_id = __state.has_mismatched_id,
linked_page_multiple_etymons_idless = __state.linked_page_multiple_etymons_idless,
linked_page_partial_etymology_sections = __state.linked_page_partial_etymology_sections,
text_stop_lang_missing = text_stop_lang_missing,
})
M.tracking.track_keywords(__state.toplevel_keyword_stats, lang)
M.tracking.track_page_id(lang, id)
M.tracking.track_ids(__state.id_stats, lang)
end
if #categories > 0 then
table.insert(output, M.categories.format(categories, lang))
end
if __state.warnings then
for i, warning in ipairs(__state.warnings) do
table.insert(output, (i == 1 and "\n" or "") .. warning .. "\n")
end
end
return table.concat(output)
end
return export
i6dcsq27k0zmrve3xo2u36azrglysrp
Northern Hemisphere
0
59510
375887
321472
2026-09-25T13:42:36Z
Hakimi97
2668
Menggantikan Kawasan dunia kepada Benua dan kawasan benua
375887
wikitext
text/x-wiki
==Bahasa Inggeris==
{{Wikipedia|lang=en}}
===Kata nama===
{{en-noun|head=[[northern|Northern]] [[hemisphere|Hemisphere]]}}
# [[Hemisfera Utara]]
===Sebutan===
* {{audio|en|LL-Q1860 (eng)-Wodencafe-Northern Hemisphere.wav|a=AS}}
{{C|en|Benua dan kawasan benua}}
rfgneitevro9d0mngm0r6oc2wbujz5c
Southern Hemisphere
0
59511
375888
321815
2026-09-25T13:43:00Z
Hakimi97
2668
Menggantikan Kawasan dunia kepada Benua dan kawasan benua
375888
wikitext
text/x-wiki
==Bahasa Inggeris==
{{Wikipedia|lang=en}}
===Kata nama===
{{en-noun|head=[[selatan|Selatan]] [[hemisphere|Hemisphere]]}}
# [[Hemisfera Selatan]]
===Sebutan===
* {{audio|en|LL-Q1860 (eng)-Wodencafe-Southern Hemisphere.wav|a=AS}}
{{C|en|Benua dan kawasan benua}}
mhn8zs032mnpto128dlu2gz54d9jd96
East Asia
0
59529
375883
320899
2026-09-25T13:34:46Z
Hakimi97
2668
Kawasan di Asia > Tempat di Asia
375883
wikitext
text/x-wiki
==Bahasa Inggeris==
{{Wikipedia|lang=en}}
===Kata nama khas===
{{en-knk}}
# [[Asia Timur]]
=====Kata setara=====
* {{l|en|Central Asia}}, {{l|en|North Asia}}, {{l|en|South Asia}}, {{l|en|Southeast Asia}}, {{l|en|West Asia}}
{{C|en|Tempat di Asia}}
hui5ku3uzqq8ftrd2ssipj8q5hbd0ye
Southeast Asia
0
59530
375884
321814
2026-09-25T13:35:09Z
Hakimi97
2668
Kawasan di Asia > Tempat di Asia
375884
wikitext
text/x-wiki
==Bahasa Inggeris==
{{Wikipedia|lang=en}}
===Kata nama khas===
{{en-proper noun|head=[[southeast|Southeast]] [[Asia]]}}
# [[Asia Tenggara]]
#: {{syn|en|Nanyang|Southeastern Asia|Farther India}}
=====Bentuk alternatif=====
* {{alter|en|South-East Asia|South East Asia|SEA}}
=====Kata setara=====
* {{l|en|Central Asia}}, {{l|en|East Asia}}, {{l|en|North Asia}}, {{l|en|South Asia}}, {{l|en|West Asia}}
===Sebutan===
* {{audio|en|en-us-Southeast Asia.ogg|a=AS}}
{{C|en|Tempat di Asia}}
cagegdxyffoybyf7qguv4xygq3dcrxh
Central Asia
0
60143
375882
320716
2026-09-25T13:34:16Z
Hakimi97
2668
Kawasan di Asia > Tempat di Asia
375882
wikitext
text/x-wiki
==Bahasa Inggeris==
{{Wikipedia|lang=en}}
===Kata nama khas===
{{en-knk}}
# [[Asia Tengah]]
=====Terbitan kata=====
* {{l|en|Central Asian}}
===Sebutan===
* {{audio|en|LL-Q1860 (eng)-Wodencafe-Central Asia.wav|a=AS}}
===Tesaurus===
====Meronim====
* '''''negara-negara Asia Tengah''':'' [[Afghanistan]], [[Kazakhstan]], [[Kyrgyzstan]], [[Tajikistan]], [[Turkmenistan]], [[Uzbekistan]]
====Holonim====
* {{l|en|Asia}}
====Kata setara====
* {{l|en|East Asia}}
* {{l|en|North Asia}}
* {{l|en|South Asia}}
* {{l|en|Southeast Asia}}
* {{l|en|West Asia}}
{{C|en|Tempat di Asia}}
sngcgxu7ovm7568pzxzoylaxaw8us1s
repang
0
66154
376164
201679
2026-09-26T09:17:13Z
Elvaretta Vito
11512
376164
wikitext
text/x-wiki
== Bahasa Melayu ==
=== Takrifan ===
==== Kata sifat ====
{{ms-ks|j=رڤڠ|pl=-}}
# sama tinggi dan sama rendah; [[rata]]
=== Sebutan ===
* {{dewan|re|pang}}
=== Pautan luar ===
* {{R:PRPM}}
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Repang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Tolong merepang ujung buluh ni bia tak tajam.|Tolong pangkas rata ujung bambu ini biar tidak tajam.}}
c484cv4tx58wcrhcruwavsb06xirbp0
jalu
0
66158
376109
310407
2026-09-26T09:00:10Z
Thurama
11516
376109
wikitext
text/x-wiki
==Bahasa Iban==
===Kata nama===
{{inti|iba|kata nama}}
# mangkuk besar
#: {{cp|iba|Uji ambi '''jalu''' nya.|Cuba ambil '''mangkuk besar''' itu. }}
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} Berjalan dalam keadaan tidur<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
4nmsv4jtop7wducqcgkn53hrymdoavc
376116
376109
2026-09-26T09:02:16Z
Thurama
11516
/* Kata sifat */
376116
wikitext
text/x-wiki
==Bahasa Iban==
===Kata nama===
{{inti|iba|kata nama}}
# mangkuk besar
#: {{cp|iba|Uji ambi '''jalu''' nya.|Cuba ambil '''mangkuk besar''' itu. }}
==Bahasa Melayu==
===Jalu===
{{lb|ms|kata sifat}}
# {{lb|ms|pekanbaru}} Berjalan dalam keadaan tidur<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
fjj13qnt8r4uuqxqb5enreuai1kdp70
sengak
0
67090
376106
313414
2026-09-26T08:59:53Z
Elvaretta Vito
11512
376106
wikitext
text/x-wiki
==Bahasa Iban==
===Kata sifat===
{{inti|iba|kata sifat}}
# sesak nafas
#: {{cp|iba|Pengudah niki tangga ti tinggi, Sani bepun berasai '''sengak'''.|Setelah menaiki tangga yang tinggi,Sani mula berasa '''sesak nafas'''.}}
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} sengak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Jangan suko menyengak macam tu, tekejut budak dibuatnyo.|angan suka menghardik seperti itu, terkejut anak-anak dibuatnya.}}
ie97o26gcr4vt5wn8eqzz8m686s9cr8
sirap
0
71504
376192
305838
2026-09-26T09:31:34Z
Elvaretta Vito
11512
376192
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{inti|ms|kata sifat}}
===Etimologi===
Pinjaman {{bor|ms|en|syrup}}.
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Sirap <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Menyirap darahku dengar kaba bohong tu.|Naik darahku mendengar kabar bohong itu.}}
==Bahasa Kadazandusun==
===Kata nama===
{{inti|dtp|kata nama}}
# [[sirap]]
#: {{cp|dtp|Orohian ilo tangaanak monginum do '''sirap''' .
|Kanak-kanak itu suka minum '''sirap''' .}}
1f01jrp8e5c4415tc62dzll7nlauftg
lompek
0
75410
375967
221067
2026-09-26T08:21:54Z
SY Reski
10853
375967
wikitext
text/x-wiki
==Bahasa Melayu Negeri Sembilan==
===Takrifan===
====Kata kera====
{{inti|zmi|kata kerja}}
#{{l|ms|lompat}}
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} lompek <!--lompat-->
#:{{cp|ms|lompek toruih ang yuang, jatuah kok le.|kamu selalu melompat dari tadi, nanti terjatuh.}}
p5ykwx1ag40pggvn4qjq9eur53vfsm6
Modul:place/locations
828
76177
375872
344227
2026-09-25T12:50:39Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/92925432|92925432]])
375872
Scribunto
text/plain
local export = {}
export.force_cat = false -- set to true to force category generation even on non-mainspace pages
local m_table = require("Module:table")
local insert = table.insert
local dump = mw.dumpObject
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
--[==[ intro:
This module contains data on all known locations, along with some lower-level code to process them (higher-level
known-location code is in [[Module:place/placetypes]]). You must load this module using require(), not using
mw.loadData().
===Location data===
'''NOTE: In order to understand the following better, first read the introductory documentation in [[Module:place]],
especially the section `More about known locations`.'''
The bulk of the code in this module (after some helper functions and placetype tables) describes the known locations
and their relationships. Locations are grouped into ''location groups'' that share some common properties (examples are
states of the United States and cities in Brazil). Each location group is associated with two tables, a ''data table''
that lists the locations and their individual properties, and a ''metadata table'' that lists group-level properties and
defaults for the location properties. Each metadata table points to the associated data table (i.e. contains the data
table as its `data` field), and the global `locations` variable holds a list of all group metadata tables. A given
location is generally described by three values: (a) the group metadata table for the group the location is part of; (b)
the location's canonical ''key'', which is the actual key in the group's data table and is globally unique across all
locations; and (c) the location's ''spec'', which is the initialized object describing the properties of the location
and comes from the value in the data table corresponding to the canonical key, transformed by the `initialize_spec()`
function. These are typically named `group`, `key` and `spec`, respectively and in that order, and are found in the
arguments to many functions.
In a per-group data table, the keys are either ''canonical keys'' describing locations (which, as mentioned above, must
be globally unique) or ''alias keys'' specifying an allowed alias for a given location. There may be multiple aliases
for a given location and the alias keys only need to be unique within a particular group data table, not across all
groups. It is also possible for the same string to serve as an alias key in one group and a canonical key in another
group. (For example, `Newcastle` appears as an alias key in two different groups, referring to two different locations,
canonically known as `Newcastle upon Tyne`, for the city in England, and `Newcastle, New South Wales`, for the city in
New South Wales, Australia; and `Birmingham` appears both as a canonical key in the group of English cities and an alias
key for canonical `Birmingham, Alabama` in the group of US cities.) The corresponding value objects are different for
canonical and alias keys. Corresponding to canonical keys are ''location specs'', describing the properies of the
location that cannot be derived from default properties of the group or global defaults. Corresponding to alias keys
are ''alias specs'', which are highly restricted in the properties they can contain, and whose properties do not have
per-group defaults, but only global defaults.
The canonical key is always the same as the bare category corresponding to the location, which is one of the reasons it
must be globally unique. For example, the country of Georgia uses the canonical key `Georgia` and corresponding bare
category [[:Category:Georgia]], while the US state of Georgia uses the canonical key `Georgia, USA` and corresponding
bare category [[:Category:Georgia, USA]]. The following conventions are followed in naming keys:
* Countries, ''country-like entities'' (which are a mixture of unrecognized de-facto states and dependent territories)
and ''former countries'' (which also includes other types of polities, such as the Roman Empire) use their unqualified
placename as the canonical key. (See the documentation for [[Module:place]] for the distinction between keys and
placenames, which is critical to understand when working with location data.) This also applies to constituent
countries (such as England, Aruba and the Faroe Islands) and constituent parts of grouped dependent territories (such
as the island of Saint Helena, which is administratively part of the British overseas territory of Saint Helena,
Ascension and Tristan da Cunha).
* Cities (including prefecture-level cities in China, which behave in most respects more like non-city administrative
divisions) also normally use their unqualified placename as the canonical key, but if this causes name conflicts or
ambiguities, they use a ''qualified key'' containing either the country name or immediate containing division (if
different) following a comma, such as the case of `Newcastle, New South Wales` and `Birmingham, Alabama` above.
Examples of name conflicts are the two cities just given; examples of ambiguities are the major cities of León and
Mérida in Mexico and city of Cartagena, Colombia, which are given the respective canonical keys of `León, Guanajuato`,
`Mérida, Yucatán` and `Cartagena, Colombia` to avoid ambiguity with the well-known respective cities of the same name
in Spain, even though none of those cities are large enough to be included as known locations in this module. (The
cutoff is generally having a metro area of at least 1,000,000 inhabitants, although there are exceptions.)
* Administrative divisions of countries, other than the exceptions noted above for constituent countries and dependent
territories, use a qualified key that contains the name of the country or constituent country in it, e.g.
`Normandy, France` (a region), `Calvados, France` (a department in the region of Normandy), `Herefordshire, England`
(a ceremonial county), `Northwest Territories, Canada` (a territory), `Central Finland, Finland` (a region),
`Antalya Province, Turkey` (a province), `Cluj County, Romania` (a county), `County Cork, Ireland` (a county) and
`New York, USA` (a state). As shown in these various examples, (a) first and second-level divisions are sometimes both
included (as in France, the United Kingdom and China); (b) the qualifier after the comma is sometimes a constituent
country (England) instead of a country (United Kingdom), and is sometimes abbreviated (USA rather than United States
or Unites States of America); (c) the word `the` is not normally included in the key even if the location is normally
preceded by `the` when following a preposition (there is a property in the location and alias specs to indicate this),
except in a very few cases (most notably `The Hague`); (d) the country is included as a qualifier even if it creates
an apparent redundancy, as with `Central Finland, Finland`; and (e) sometimes the placetype is included in the key, as
with provinces in Turkey and several other countries; states in Nigeria; and counties in Ireland, Romania and several
other countries. Whether the placetype is included, and whether it follows or precedes the placename, depends on
per-country conventions. For example, provinces in Turkey, Iran and several other countries (likewise for states in
Nigeria, oblasts in Russia, etc.) conventionally include the word "Province", "negeri", "Oblast" etc. in their name
because they are normally named after the largest city in the division, which would otherwise lead to ambiguity; and
counties in Ireland and Northern Ireland (and likewise County Durham, England) normally have the word "kaunti"
preceding rather than following them in their conventional name, so we follow this practice. The Wikipedia article
naming scheme for a given administrative division is a strong clue as to how the division is normally referred to,
and we usually follow this practice. (A minor exception is that the Wikipedia articles for provinces in Iran, Laos and
Thailand include the word `province` with an initial lowercase letter while provinces elsewhere, e.g. North and South
Korea, Saudi Arabia and Turkey, use uppercase `Province`; we normalize to uppercase `Province` in all cases.)
As mentioned above, associated with canonical keys in the group data table are location specs, which are objects
containing properties. It is important here to distinguish ''initialized specs'' from ''uninitialized specs''.
Unininitialized specs are as directly specified in [[Module:place/locations]], containing only those properties that
differ from the per-group or global defaults. Initialized specs result from calling `initialize_spec()` on an
uninitialized spec (it is idempotent in that it will do nothing if encountering an already-initialized spec). This
copies all group-level defaults that are not overridden in the location spec itself from the group-level metadata table
into the location spec, so that in general, no more reference need be made to the group to fetch the correct value of a
given location property. (The initialization process also does more transformations in a few cases, noted below.) Note
that the default value of a given property is stored under a key in the group metadata table that is preceded by the
string `default_`; for example, the default value corresponding to the `placetype` property of a given location is
specified in the `default_placetype` key in the group metadata table.
The following are the properties of the location spec.
* `placetype`: String specifying the placetype of the location (e.g. "negara", "negeri", province"). This can also be a
table of such types; in this case, the first listed type is the canonical type that will be used in descriptions, but
the location will be recognized (e.g. in a holonym, or for categorizing into the bare category) when tagged with any
of the specified types. The placetype '''must''' be either specified on an individual location or defaulted at the
group level, or an error occurs.
* `container`: Either a string, a ''canonicalized container'' structure or a list of either type, specifying the
immediate ''container'' (or containers) of the given location. A container is another location which this location is
considered to be directly part of, either politically or (above the country level) geographically. Some locations
belong to multiple immediate containers; this applies especially to transcontinental countries such as Russia and
Turkey. Containers can themselves have containers, forming a tree (or more correctly, a [[w:directed acyclic graph]])
of locations. The list of immediate container(s), followed by the container(s) of the container(s), etc., is termed
the ''container trail'', and some functions compute and return this trail as part of their operation. When a location
spec is initialized, the given container spec is canonicalized into ''canonical container form'', which consists of a
list of canonicalized container structures, each of which is of the form
`{key = "``container_key``", placetype = "``container_placetype``"}`, where ``container_key`` is a canonical location
key and ``container_placetype`` should be the listed placetype for the location, or the first listed placetype if
there are multiple. (FIXME: Since the key uniquely identifies the container location, we should eliminate the
placetype from the container structure.) The list of canonicalized container structures is stored into the
`.containers` field of the location spec (this happens even if the container value is unset in its uninitialized spec
form, causing it to default to the corresponding group-level value), and the `.container` field is set to {nil}. The
canonicalization process is described in more detail below under [[#Container spec canonicalization]].
* `divs`: List of recognized political divisions; e.g. for the Netherlands, a specification of the form
`divs = {"provinces", "municipalities"}` will allow categories such as [[:Category:de:Provinces of the Netherlands]]
and [[:Category:pt:Municipalities of the Netherlands]] to be created. Any division that appears here must also be
found in `placetype_data`, or an error occurs. The entities appearing in the `divs` list can be structures as well as
just strings; this is explained more below under [[#Location divisions]]. Additional political divisions that apply to
all locations in a group can be specified at the group level using the group-only property `addl_divs`, which has the
same format as `divs`. This is intended to be used in the situation where some division types are shared among all
locations in the group and others differ from location to location. An example where this is used is the United
States, where `census-designated places` is specified in the group-level `addl_divs` so that all 50 states have
census-designated places categorized as e.g. [[:Category:Census-designated places in Arizona, USA]], but `counties`
and `county seats` are specified in the group-level `default_divs` because not all states have counties and county
seats (Alaska has boroughs and borough seats and Louisiana has parishes and parish seats), and some states have
additional divisions (New Jersey and Pennsylvania also have boroughs, while Colorado and Connecticut have
municipalities). Note that under most circumstances (particularly, if `container_parent_type` is not set as a property
associated with the division type), any division type specified on a sub-country-level location must also be specified
on all containers up through the country. For example, since French departments specify `communes` and
`municipalities` in `default_divs`, the same division types must be (and are) specified on French regions and for
France itself.
* `keydesc`: String directly specifying a description of the location, for use in generating the contents of category
pages related to the location. In place of a string, a function of three arguments (`group`, `key`, `spec`, as is
normal for locations) that computes the location description can also be given. This is used, for example, for
Russian federal subjects; see `construct_russia_federal_subject_keydesc`. The special string `+++` contained in the
keydesc is replaced with the default value of the location description, which specifies the location's placename,
placetype, and the corresponding values for each container in the container trail, generally up through (but not
beyond) the country level; see `no_include_container_in_desc` below. The location description is used to construct
the full description of various categories, such as bare location categories, whose description generally reads
`"{{(((}}langname}}} terms related to the people, culture, or territory of ``keydesc``."` where ``keydesc`` is the
specified or auto-constructed location description.
* `fulldesc`: String overriding the full description for the bare location category (but not for any other category).
This is currently used only for the location `Earth`, at the very top of the tree (because the standard
`people, culture or territory of ...` text doesn't make sense here), and for `Antarctica` (because it has no permanent
inhabitants). FIXME: This should be renamed `bare_category_fulldesc`.
* `addl_parents`: Specify additional parents for the bare location category, in addition to the category or categories
generated based on the immediate container(s). For example, `Hawaii, USA` specifies `Polynesia` as an additional
parent category; both `North Korea` and `South Korea` specify `Korea` (which is a specially handled location category)
as an additional parent; and `Earth` specifies `nature` (not a location category, but still a topic category) as an
additional parent (which in this case becomes the first parent, as `Earth` has no container). The only restriction on
the categories in `addl_parents` is that they must be topic categories, because each language-specific version of the
bare location category gets the corresponding language-specific versions of the categories in `addl_parents`. FIXME:
This shoudl be renamed `bare_category_addl_parents`.
* `wp`: Spec describing how to construct the Wikipedia article for the location. Each spec is either `true` (equivalent
to `"%l"`, i.e. use the full location placename directly) or a string containing formatting directives, indicating how
to construct the article name. The allowed formatting directives are `%l` (the full location placename), `%e` (the
elliptical location placename) and `%c` (the full placename of the first immediate container). For example, the
default value of `wp` for the group of United States cities is `"%l, %c"` since the city articles tend to be named
e.g. `Austin, Texas` (but with many exceptions, specified using `wp` fields at the city level). Another example is
Thai provinces, which specify a group-level default of `"%e province"` as the Wikipedia articles have lowercase
`province` in their name but the Thai province keys specified in this module have uppercase `Province`. Here we have
to use `%e` to get the placename without the word `Province` in it. The default is `true`, which simply uses the full
location placename as the article name. Note that the Wikipedia article, along with the Wikipedia and Commons category
pages, are shown in the upper right of bare category pages.
* `wpcat`: Spec describing how to construct the Wikipedia category page for the location (i.e. the page listing articles
and categories relevant to the location). The format is the same as with `wp`, and it defaults to the value of `wp`.
It rarely needs to be specified because the category page and the article page almost always follow the same format.
* `commonscat`: Spec describing how to construct the Commons category page for the location (i.e. the page on the
MediaWiki Commons site listing articles and categories relevant to the location). It has the same format as `wp` and
`wpcat` and defaults to `wpcat`, which is usually (but not always) correct.
* `the`: Boolean specifying whether a location should be preceded by `the` when following a preposition, e.g. in
category names such as [[:Category:Cities in the Northern Territory, Australia]] and in old-style place descriptions
when the location occurs as the first holonym, such as the city [[Darwin]] described using
{{tl|place|city|terr/Northern Territory|c/Australia}}. Note that the global default for this and all Boolean
properties is {nil}, which amounts to the same as {false}.
* `british_spelling`: Boolean indicating whether the location in question uses British spelling. Currently this only
affects whether the spelling `neighborhoods` or `neighbourhoods` is used in categories such as
[[:Category:Neighborhoods of New York City]] and [[:Category:Neighbourhoods of Sydney]]. This usually needs to be set
only at the top level (i.e. country or country-like entity), because lower-level entities look up the container trail
for any container that has `british_spelling = true` set, and if found, assume that British spelling applies. The
general principle used in setting this is that all countries in Europe, all dependent territories of any such country,
all former British colonies, and any dependent territories of these former colonies, are assumed to use British
spelling, while all other countries and associated dependent territories are assumed to use American spelling. This
can potentially be modified on a case-by-case basis.
* `is_city`: Boolean indicating whether the location in question is a city. This is explicitly set to `true` for
city-states (e.g. Monaco and Vatican City), dependent territories that are cities (e.g. Hong Kong, Macau, Bonaire,
Gibraltar, etc.), certain city-level administrative divisions (such as `City of Belfast, Northern Ireland`) and
(through a group-levell setting) New York boroughs. In addition, it is set to `true` in initialize_spec() whenever
the group-level `default_placetype == "bandar"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "bandar"` intentionally excludes Chinese
prefecture-level cities, which aren't really cities in that (for example) they don't directly contain neighborhoods,
but do contain cities within them. This setting is used in various places: (a) to add cities, rivers, etc. to
categories like [[:Category:Rivers in Osaka Prefecture, Japan]] and [[:Category:Cities in Wuhan]] for holonyms that
are ''not'' cities; (b) to add districts, neighborhoods, and the like to categories like
[[:Category:Neighborhoods of Brooklyn]] and [[:Category:Neighborhoods of Monaco]] for holoynms that ''are'' cities;
(c) generally, to determine which "generic" placetypes (cities, rivers, neighborhoods, etc.) apply to the location.
(Those that can occur with cities have a `generic_before_cities` setting in [[Module:place/placetypes]], and those
that can occur with non-cities have a `generic_before_non_cities` setting.)
* `is_former_place`: Boolean that should be set on former places such as the Soviet Union and the Roman Empire. For such
places, categories such as [[:Category:fr:Rivers in the Soviet Union]] are neither generated nor recognized (more
generally, no "generic" placetypes apply except for `places`), and category descriptions include the word `former`.
* `overriding_bare_label_parents`: Document me!
* `bare_category_parent_type`: Document me!
* `no_container_cat`: Document me!
* `no_container_parent`: Document me!
* `no_generic_place_cat`: Document me!
* `no_check_holonym_mismatch`: Document me!
* `no_auto_augment_container`: Document me!
* `no_include_container_in_desc`: Document me!
====Location divisions====
The `divs` field of a location describes the recognized political division types of that location. Specifying a given
division type will cause places defined as being of the specified division type and with the location as a holonym will
cause the place to be categorized as ` ``placetypes`` in/of ``location`` `; for example, specifying that the United
States has `"negeri"` as a division will cause anything defined as {{tl|place|fr|state|c/US}} to be categorized under
[[:Category:fr:States of the United States]]. Note that you do not have to explicitly specify division types for
"generic" placetypes (those that have a `generic_before_non_cities` field if the location is not a city, or that have a
`generic_before_cities` field if the location is a city); this includes things like cities, towns, villages,
neighbo(u)rhoods and rivers. A given element in the `divs` list is usually a string naming a plural placetype; the
placetype is automatically converted to the singular for recognizing the placetype in a {{tl|place}} spec, and irregular
plurals such as `kibbutzim` are handled correctly as long as the placetype specifies an appropriate `plural` field
(if the `plural` isn't explicitly given, the default singularization algorithm in [[Module:en-utilities]] is run, which
gets most things correctly but has problems with `passes` and `fortresses`, which are singularized to `passe` and
`fortresse`; for this reason, an explicit plural entry is added to terms in ''-ss''). In place of a string, an object
can be given with the plural placetype in the `type` field; this allows additional properties to be specified along with
the placetype. An example of this is the `divs` list for Canada:
{
["Canada"] = {divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"kaunti", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "di"},
}, ...},
}
Here, both provinces and territories are set to categorize as `provinces and territories`, meaning that there is a
single category [[:Category:Provinces and territories of Canada]] rather than separate categories for provinces and
territories. Similar things are done for other countries that have more than one type of first-level administrative
division (e.g. Australia, China, India and Pakistan). Note that any placetype listed under `cat_as` must exist in the
table of placetypes in [[Module:place/placetypes]], and in fact there is a category-only entry there for `provinces and
territories!` (the use of exclamation point following a plural placetype means that the placetype is present only for
use in categories and won't be recognized as the placetype field in a {{tl|place}} description). In addition, townships
are declared to use `in` rather than `of` as the preposition in the category; hence the category name will be
[[:Category:Townships in Canada]] rather than [[:Category:Townships of Canada]]. (The use of `in` vs. `of` is somewhat
related to whether a given placetype is an official administrative or statistical division of the location in question
and comes in a defined list, in which case `of` should be used, or is more ill-defined, in which case `in` should be
used; the default is `of`, and the use of `in` with `townships` is probably by analogy with the use of `in` with cities
and towns.)
Another more complex example is the divisions given for Quebec:
{
["Quebec, Canada"] = {divs = {
"kaunti",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "wilayah", container_parent_type = false},
{type = "townships", prep = "di"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "kaunti"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "di"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "di"}, "municipalities"}},
}, ...},
}
Here, `container_parent_type` controls the second parent category of the placetype/location category associated with the
entry. In this case, for example, [[:Category:Counties of Quebec, Canada]] will have [[:Category:Counties of Canada]] as
its second or ''container-level'' parent. However, this doesn't make sense for `regional county municipalities`, which
exist only in Quebec (so the parent category [[:Category:Regional county municipalities of Canada]] would have only one
subcategory); but they are similar to regional municipalities in British Columbia, Nova Scotia and Ontario, so the
`container_parent_type = "regional municipalities"` spec causes the container-level parent of this category to be
[[:Category:Regional municipalities of Canada]]. Likewise, `regions` as administrative divisions (as opposed to mere
geographic regions) exist only in Quebec; they have no equivalent elsewhere, so we disable the container-level parent
using `container_parent_type = false`. The specs for `parish municipalities`, `township municipalities` and
`village municipalities` show both that multiple types can be specified under `cat_as` (here, for example, we categorize
`parish municipalities` as both `parishes` and `municipalities`) and that these types can themselves have properties,
just as for entries directly under `divs`. Specifically, `{type = "parishes", container_parent_type = "kaunti"}`
means that any place defined as a parish municipality in Quebec will be categorized under both [[:Category:Parishes of
Quebec, Canada]] and [[:Category:Municipalities of Quebec, Canada]], and that the former will have a container-level
parent of [[:Category:Counties of Canada]] (rather than the default of [[:Category:Parishes of Canada]]). Similarly,
`township municipalities` will be categorized under both [[:Category:Townships in Quebec, Canada]] (''not''
[[:Category:Townships of Quebec, Canada]]) and [[:Category:Municipalities of Quebec, Canada]].
====Container spec canonicalization====
A fully canonicalized container spec for a given location consists of a list of ''canonicalized container objects'',
each with a `key` and `placetype` field. The `key` field should name the canonical key of some other location at a
higher level (e.g. French cities are contained in French departments, which are contained in French regions, which are
contained in France, which is contained in Europe, which is contained in Eurasia, which is contained in the Earth). The
`placetype` field should correspond to the first (canonical) placetype listed for the key in question. The process of
initializing a locaion spec converts the container spec in `.container` into a canonicalized spec in `.containers` and
removes the spec from `.container`. It works as follows:
# If the `container` field is missing, and there is a group-level `default_container` field, it is used in its place.
For example, none of the Brazilian states listed in `brazil_states` specifies a container, but the group specifies
`default_container = "Brazil"`.
# A single string or canonicalized container object is allowed and made into a one-element list.
# If a list element is a string that did ''not'' come from `default_container`, and there is a group-level
`canonicalize_key_container` field, it is assumed to be a one-argument function and is called on the string to get
a canonicalized container object.
# Any remaining strings are assumed to be countries and are used directly as the `key`, with `placetype` set to
`"negara"`.
====Alias keys====
Aliases can be provided for canonical keys using ''alias keys''. Alias keys have a very different location spec
structure from canonical keys. This structure does not, in general, have defaults at the group level and is not
initialized using `initialize_spec()`, but is used as-is. The following properties are recognized in an alias location
spec:
* `alias_of`: The canonical key of which this key is an alias. Required.
* `the`: If true, this alias key is preceded by `the` following a preposition. Defaults to the group-level `default_the`
but does not pay attention to the value of `the` for the corresponding canonical key.
* `display`: This is a display alias, meaning that holonyms using the placename corresponding to this alias will be
converted to the placename corresponding to the canonical key when formatting the holonym for display. (Otherwise,
the aliasing applies only to categorization.) If the value is true, the display canonicalization is to the placename
of the canonical key; otherwise, the value should be a key whose corresponding placename is used when display
canonicalizing.
* `placetype`: The placetype of the alias. Rarely needs to be specified as it defaults to the canonical key's placetype,
and if that is unspecified, to the group-level default placetype.
====Location group metadata tables====
As mentioned above, associated with each location group is a ''metadata table'' listing group-level properties. The
metadata table contains two types of keys: group-level defaults (named like the corresponding location-level keys but
preceded by `default_`, e.g. `default_placetype` corresponding to the location-level `placetype` key) and group-only
keys, which are mostly functions. The following are the possible group-only keys:
* `data`: This points to the group data table for the group, as described above.
* `key_to_placename`: This is a function of one argument to transform the location's key (whether canonical or alias)
into the full and elliptical placenames. The difference between full and elliptical placenames is described in the
documentation for [[Module:place]], but in essence, it applies for keys that include the placetype in them (e.g.
`Phuket Province, Thailand` or `County Mayo, Ireland`), in which case the full placename includes the placetype and
the elliptical placename does not. For keys that do not include the placetype in them (e.g. `Arizona, USA` or
`Gloucestershire, England`), the full and elliptical placenames are identical. Note that neither the full nor the
elliptical placename includes the container in it; hence, for `Phuket Province, Thailand`, the full placename is
`Phuket Province` and the elliptical placename is just `Phuket`. (Note that the full vs. elliptical placename
distinction is intended only for handling cases where the placetype follows or precedes the raw placename and there
is no difference between the two in whether they are normally preceded by `the`. More complex situations, such as
`State of Mexico` (which normally takes `the`) vs. just `Mexico` (which doesn't), or `Islamabad Capital Territory` vs.
just `Islamabad`, should be handled instead by aliases.) The `key_to_placename` function takes one argument, the key,
and returns two arguments, the full and elliptical placenames, respectively. If left undefined, the default is to
chop off anything starting with a comma and return the result as both full and elliptical placename, and if
specifically set to `false`, the key is used directly as both full and elliptical placename. If it needs to be
defined, it is best to use the helper function `make_key_to_placename`, if possible (or
`make_irish_type_key_to_placename` in the case of Ireland and Northern Ireland, where `County` precedes), rather than
rolling your own. In addition, you should use the global `key_to_placename` function (which takes care of the default
implementation and such) rather than directly calling the function in the `key_to_placename` field.
* `placename_to_key`: This is approximately the inverse of `key_to_placename`, transforming a placename (which can be
either in full or elliptical form) into the corresponding key. As with `key_to_placename`, if you need to define this
(generally, when the full and elliptical placenames are different), prefer using `make_placename_to_key` (or
`make_irish_type_placename_to_key` for Ireland and Northern Ireland) to rolling your own. In addition, similarly to
`key_to_placename`, use the global `placename_to_key` function to convert placenames to keys rather than directly
invoking the function in the `placename_to_key` field. If the field is set to `false`, the placename is used unchanged
as the key. Otherwise, the default algorithm works as follows:
*# If the group-level `default_placetype == "bandar"`, use the placename unchanged as the key.
*# Otherwise, if the group-level `default_container` exists and is a string, append it to the placename after a comma +
space and use the result as the key.
*# Otherwise, if the group-level `default_container` is a canonical container object (an object with `key` and
`placetype` fields), and the `placetype` field is either `country` or `constituent country`, append the `key` field
to the placename after a comma + space and use the result as the key.
*# Otherwise, use the placename unchanged as the key.
* `canonicalize_key_container`: A function of one argument to convert the specified `container` field, when a string,
to canonical form. Described in more detail above under [[#Container spec canonicalization]]. It is preferable to
construct the function using `make_canonicalize_key_container`, if possible, rather than rolling your own.
* `addl_divs`: Additional political divisions appended, for all locations in the group, to the list of divisions derived
from the location-level `divs` or group-level `default_divs` fields to get the final list of divisions for the
location. See [[#Location divisions]] for more details.
]==]
-----------------------------------------------------------------------------------
-- Helper functions --
-----------------------------------------------------------------------------------
--[==[
Throw an error. `fmt` is a format string and the remaining arguments are passed through `mw.dumpObject` and then used to
format the format string as if `fmt:format(...)` were called. In general, callers should use `internal_error` unless the
error was due to bad user input rather than a logic error (which usually isn't the case in deep back-end code like
this).
]==]
function export.process_error(fmt, ...)
local args = {...}
for i = 1, select("#", ...) do
args[i] = dump(args[i])
end
return error(string.format(fmt, unpack(args)))
end
--[==[
Throw an internal error (a logic error that should never happen unless there is a bug in the code, as opposed to a user
error triggered by bad input or a system error due to something like running out of memory or hitting a time limit).
`fmt` is a format string and the remaining arguments are passed through `mw.dumpObject` and then used to format the
format string as if `fmt:format(...)` were called.
]==]
function export.internal_error(fmt, ...)
export.process_error("Internal error: " .. fmt, ...)
end
local internal_error = export.internal_error
-- Return whether `list_or_element` (a list of strings, or a single string) "contains" `item` (a string). If
-- `list_or_element` is a list, this returns true if `item` is in the list; otherwise it returns true if `item`
-- equals `list_or_element`.
local function list_or_element_contains(list_or_element, item)
if type(list_or_element) == "table" then
return m_table.contains(list_or_element, item) and true or false
end
return list_or_element == item
end
--[==[
Call the location group's `key_to_placename` function if it exists (see the comment at the top of [[Module:place]] for
the distinction between keys and placenames). Two values are returned, the full and elliptical placenames (e.g. full
`"County Durham"` vs. elliptical `"Durham"`). If the group does not define `key_to_placename`, both full and elliptical
placenames are computed by chopping off anything starting with a comma.
]==]
function export.key_to_placename(group, key)
if group.key_to_placename == false then
return key, key
end
if group.key_to_placename then
local full_placename, elliptical_placename = group.key_to_placename(key)
if type(full_placename) ~= "string" then
internal_error("Key %s returned a non-string full placename: %s", key, full_placename)
end
if type(elliptical_placename) ~= "string" then
internal_error("Key %s returned a non-string elliptical placename: %s", key, elliptical_placename)
end
return full_placename, elliptical_placename
end
key = key:gsub(",.*", "")
return key, key
end
--[==[
Call the location group's `placename_to_key` function if it exists (see the comment at the top of [[Module:place]] for
the distinction between keys and placenames) and return the result. If `placename_to_key` exists with the value `false`,
return the placename unchanged. If the group does not define `placename_to_key`, and it defines a `default_container`
whose placetype is either `country` or `constituent country`, the container name is appended to the placename after a
comma and a space. Otherwise the placename is returned unchanged.
]==]
function export.placename_to_key(group, placename)
if group.placename_to_key == false then
return placename
elseif group.placename_to_key then
local key = group.placename_to_key(placename)
if type(key) ~= "string" then
internal_error("Placename %s returned a non-string key: %s", placename, key)
end
return key
elseif group.default_placetype == "bandar" then
return placename
else
local defcon = group.default_container
if not defcon then
return placename
elseif type(defcon) == "string" then
return placename .. ", " .. defcon
elseif type(defcon) == "table" and (defcon.placetype == "negara" or
defcon.placetype == "negara bahagian") then
return placename .. ", " .. defcon.key
else
return placename
end
end
end
--[==[
Initialize the location spec `spec`, augmenting it with default values taken from `group` if the spec itself doesn't
specify values for the properties. This sets `containers` to a canonicalized list of objects, each with `key` and
`placetype` keys, describing the immediate containers of the location, and erases (sets to nil) the original
non-canonicalized `container` field. (Most locations have only one immediate container but some, e.g. Russia, have more
than one. Containers should be carefully distinguished from category parents. Generally the container is the first
category parent, or the first ``n`` parents if there are ``n`` containers, but there may be additional category parents,
which indicate some sort of relation between the category parent and the location but not necessarily one of
containment.)
This function is idempotent in that nothing happens if called more than once on the same spec.
FIXME: Consider reimplementing this in a more standardly object-oriented way using metatables.
]==]
function export.initialize_spec(group, key, spec)
if spec.initialized then
return
end
local container = spec.container
local containers
local container_from_default
if not container then
container = group.default_container
container_from_default = true
end
if container then
if type(container) == "string" or container.key then
container = {container}
end
containers = {}
for _, cont in ipairs(container) do
if type(cont) == "string" then
if group.canonicalize_key_container and not container_from_default then
cont = group.canonicalize_key_container(cont)
else
cont = {key = cont, placetype = "negara"}
end
end
insert(containers, cont)
end
end
spec.containers = containers
spec.container = nil
local function value_with_default(val, default_val)
if val == nil then
return default_val
else
return val
end
end
local function set_or_default(prop)
spec[prop] = value_with_default(spec[prop], group["default_" .. prop])
end
set_or_default("placetype")
if not spec.placetype then
internal_error("No placetype found in key %s for spec %s or in group `default_placetype`", key, spec)
end
set_or_default("divs")
spec.addl_divs = group.addl_divs
for _, prop in ipairs {
"keydesc",
"fulldesc",
"addl_parents",
"overriding_bare_label_parents",
"bare_category_parent_type",
"wp",
"wpcat",
"commonscat",
"british_spelling",
"the",
"no_container_cat",
"no_container_parent",
"no_generic_place_cat",
"no_check_holonym_mismatch",
"no_auto_augment_container",
"no_include_container_in_desc",
"is_city",
"is_former_place",
} do
set_or_default(prop)
end
-- `default_placetype == "bandar"` is correct; if `default_placetype` has something else like `prefecture-level city`
-- as the canonical placetype but also lists `city` (as Chinese prefecture-level cities do), don't mark as
-- is_city.
spec.is_city = value_with_default(spec.is_city, group.default_placetype == "bandar")
spec.initialized = true
end
--[=[
Given a location group, key and possible placetypes that the placename must match, check if the key exists in the group
with at least one of the group's key's placetypes matching one of the passed-in placetypes. If so, return two values:
the group key (which potentially could differ from the passed-in key due to aliases) and the corresponding spec object,
which (as with all functions that return spec objects) has been initialized using `initialize_spec()` (i.e. default
property values have been copied from the group into the spec, if the spec doesn't itself specify a value for the
property in question).
`alias_resolution` controls how aliases are resolved. Normally, both display and category aliases are followed, and
the returned key will reflect the canonical location key. However, if `alias_resolution` is {"none"}, no alias following
happens. In that case, if the key specifies an alias, the spec for the alias rather than the spec for the canonical
location is returned, and importantly, it is returned uninitialized, meaning that properties from the group are not
copied into the spec. (If the key specifies a canonical location, its spec is returned initialized, as in the normal
case where `alias_resolution` is unspecified.) The caller needs to check whether the returned spec is an alias by
looking for an `alias_of` property. If `alias_resolution` is {"display"}, the behavior is the same as for {"none"}
except that if the alias contains a setting `display = true`, the returned key will reflect the canonical location key,
and if the alias contains a setting `display = ``string`` `, the returned key will reflect that string.
This is a low-level function meant for internal use; external callers should generally use `get_matching_location` (for
internally-derived locations), `find_matching_holonym_location` (for externally-derived locations) or
`find_canonical_key` (for known-canonical locations where the placetype isn't known).
]=]
local function find_matching_key_in_group(group, placetypes, key, alias_resolution)
if alias_resolution ~= nil and alias_resolution ~= "none" and alias_resolution ~= "display" and
alias_resolution ~= "all" then
internal_error("Bad value for 'alias_resolution': %s", alias_resolution)
end
local spec = group.data[key]
if not spec then
return nil
end
local function check_correct_placetype(placetype)
if type(placetype) == "table" then
for _, pt in ipairs(placetype) do
if list_or_element_contains(placetypes, pt) then
return true
end
end
return false
else
return list_or_element_contains(placetypes, placetype)
end
end
if spec.alias_of then
local resolved_key = spec.alias_of
local resolved_spec = group.data[resolved_key]
if not resolved_spec then
internal_error("Key %s is an alias of %s, which doesn't exist", key, resolved_key)
elseif resolved_spec.alias_of then
internal_error("Key %s is an alias of %s, which is itself an alias; indirect aliasing not allowed",
key, resolved_key)
end
if alias_resolution == "none" or alias_resolution == "display" then
-- We could be working with non-initialized/defaulted spec, since we're pulling it directly from the group.
local placetype = spec.placetype or resolved_spec.placetype or group.default_placetype
if not placetype then
internal_error("No placetype found for key %s in any of spec %s, alias-resolved spec %s or in group " ..
"`default_placetype`", key, spec, resolved_spec)
end
if not check_correct_placetype(placetype) then
return nil
end
if alias_resolution == "display" then
if spec.display == true then
key = resolved_key
elseif spec.display then
key = spec.display
end
end
return key, spec
end
key = resolved_key
spec = resolved_spec
end
-- We could be working with non-initialized/defaulted spec, since we're pulling it directly from the group.
local placetype = spec.placetype or group.default_placetype
if not placetype then
internal_error("No placetype found for key %s in spec %s or group `default_placetype`", key, spec)
end
if not check_correct_placetype(placetype) then
return nil
end
export.initialize_spec(group, key, spec)
return key, spec
end
--[=[
Given a location group, placename and possible placetypes that the placename must match, check if the placename exists
in the group with at least one of the placetypes of the key in the group that corresponds to the placename matching one
of the passed-in placetypes. If so, return two values: the key corrsponding to the passed-in placename and the
corresponding spec object. This is similar to `find_matching_key_in_group()` but works with placenames rather than keys.
`alias_resolution` is as in `find_matching_key_in_group()`.
This is a low-level function meant for internal use; external callers should generally use `get_matching_location` (for
internally-derived locations), `find_matching_holonym_location` (for externally-derived locations) or
`find_canonical_key` (for known-canonical locations where the placetype isn't known).
]=]
local function find_matching_placename_in_group(group, placetypes, placename, alias_resolution)
local key = export.placename_to_key(group, placename)
return find_matching_key_in_group(group, placetypes, key, alias_resolution)
end
--[==[
If `key` is a canonical known location key (i.e. not an alias), return the corresponding group and initialized spec.
If no such key exists, return {nil}. This throws an internal error if two locations with the same key are found.
]==]
function export.find_canonical_key(key)
local found_locations = {}
for _, group in ipairs(export.locations) do
local spec = group.data[key]
if not spec then
-- do nothing
elseif spec.alias_of then
mw.log(("Skipping alias '%s' of canonical '%s'"):format(key, spec.alias_of))
else
insert(found_locations, {group, spec})
end
end
if not found_locations[1] then
return nil
elseif found_locations[2] then
internal_error("Found multiple matching locations for canonical key %s: %s", key, found_locations)
else
local group, spec = unpack(found_locations[1])
export.initialize_spec(group, key, spec)
return group, spec
end
end
--[==[
Iterator that returns all locations matching a given description, where the description consists of either a placename
or a key along with a list of possible placetypes. Usually there will be at most one such location. The iterator
returns three values at each iteration: the location group, canonical key by which the location is known and the spec
object describing the location. `data` contains the following possible fields:
* `placetypes`: A list of possible placetypes, one of which must match one of the location's placetypes; or a string
specifying a placetype, which must match one of the location's placetypes. This must be specified.
* `placename`: The placename of the location. Either this or `key` must be specified.
* `key`: The key of the location. Either this or `placename` must be specified.
* `alias_resolution`: If specified, it behaves the same as for `find_matching_key_in_group`.
The spec is normally initialized using `initialize_spec()` prior to it being returned (but may not be if
`alias_resolution` is given and the specified key or placename is an alias; see the documentation for
`find_matching_key_in_group`).
]==]
function export.iterate_matching_location(data)
local i = 0
local n = #export.locations
return function()
while true do
i = i + 1
if i > n then
break
end
local group = export.locations[i]
local key, spec
if data.placename then
key, spec = find_matching_placename_in_group(group, data.placetypes, data.placename,
data.alias_resolution)
else
if not data.key then
internal_error("'.placename' or '.key' must be defined: %s", data)
end
key, spec = find_matching_key_in_group(group, data.placetypes, data.key, data.alias_resolution)
end
if key then
return group, key, spec
end
end
end
end
--[==[
Return the location matching a given description, where the description consists of either a placename or a key along
with a list of possible placetypes. This is similar to `iterate_matching_location()` but throws an internal error if
there is not exactly one location found; as such, it is for use with internally specified locations (such as the
containers of known locations) rather than externally specified locations, which may not match a known location and in
some cases may match multiple known locations. For finding an externally specified location, consider using
`find_matching_holonym_location`, which returns {nil} rather than throwing an error if the location isn't found, but
also (more importantly) checks to make sure there are no conflicting holonyms among the user-specified holonyms (e.g.
{{tl|place|city|s/Delaware|c/USA|t=Newark}} will not match the known location `Newark` (in New Jersey, not Delaware).
]==]
function export.get_matching_location(data)
local all_found = {}
for group, key, spec in export.iterate_matching_location(data) do
insert(all_found, {group, key, spec})
end
if not all_found[1] then
internal_error("Couldn't find matching location for data %s", data)
elseif all_found[2] then
internal_error("Found multiple matching locations for data %s: %s", data, all_found)
else
return unpack(all_found[1])
end
end
--[==[
Successively iterate over a location's containers, and then the containers of those containers, etc. Keep in mind that
locations may have multiple containers (e.g. Russia has both Europe and Asia as containers, and both Europe and Asia
have Eurasia as their container). A given container will never be returned twice (e.g. in the case where a specific
location A has locations B and C as containers, and B has C as its container, C will not be returned twice). An
internal error happens if a container loop is detected. The return value is a list of location objects, each of which
contains `group`, `key` and `spec` fields.
]==]
function export.iterate_containers(group, key, spec)
local keys_seen = {}
keys_seen[key] = true
local iterations = 0
local last_iteration_containers = {{group = group, key = key, spec = spec}}
return function()
iterations = iterations + 1
if iterations > 10 then
internal_error("Probable loop in containers when processing key %s", key)
end
local next_iteration_containers = {}
for _, location in ipairs(last_iteration_containers) do
local containers = location.spec.containers
if containers then
for _, container in ipairs(containers) do
local container_group, container_key, container_spec = export.get_matching_location {
placetypes = container.placetype,
key = container.key,
}
if not keys_seen[container_key] then
insert(next_iteration_containers, {
group = container_group, key = container_key, spec = container_spec
})
keys_seen[container_key] = true
end
end
end
end
if not next_iteration_containers[1] then
return nil
end
last_iteration_containers = next_iteration_containers
return next_iteration_containers
end
end
--[==[
Given a placename, convert it into a link (two-part if `display_form` is given and differs from `placename`) and add
`"the "` to the beginning if called for in `spec`.
]==]
function export.construct_linked_placename(spec, placename, display_form)
local linked_placename = display_form and placename ~= display_form and ("[[%s|%s]]"):format(placename,
display_form) or ("[[%s]]"):format(placename)
if spec.the then
linked_placename = "the " .. linked_placename
end
return linked_placename
end
--[=[
This is typically used to define `key_to_placename`. It generates a function that chops off parts of a string (a
location key), typically at the end, in order to get the full and elliptical versions of a placename. (See the
documentation above for `key_to_placename` under "Location group tables" for the difference between full and elliptical
placenames.) `container_patterns` is a Lua pattern or a list of possible patterns matching the container at the end of
the key, which will be used to remove that container. If multiple patterns are specified, each one is tried until one
matches. If `container_patterns` is omitted, this part of the process is skipped. The reulting string becomes the full
placename. If `divtype_patterns` is specified, it is likewise either a Lua pattern or list of possible patterns to match
and remove the political division affixed onto the end (or possibly the beginning) of the key in the keys of certain
countries (such as South Korean and North Korean counties, which include the word "kaunti" in the key). The resulting
chopped string becomes the elliptical placename. If `divtype_patterns` is omitted, this part of the process is skipped
and the full and elliptical placenames are the same.
Typical usage is as follows:
```
key_to_placename = make_key_to_placename(", England$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", South Korea$", " County$")
```
]=]
local function make_key_to_placename(container_patterns, divtype_patterns)
if type(container_patterns) == "string" then
container_patterns = {container_patterns}
end
if type(divtype_patterns) == "string" then
divtype_patterns = {divtype_patterns}
end
return function(key)
local full_placename = key
if container_patterns then
for _, container_pattern in ipairs(container_patterns) do
local nsubs
full_placename, nsubs = full_placename:gsub(container_pattern, "")
if nsubs > 0 then
break
end
end
end
local elliptical_placename = full_placename
if divtype_patterns then
for _, divtype_pattern in ipairs(divtype_patterns) do
local nsubs
elliptical_placename, nsubs = elliptical_placename:gsub(divtype_pattern, "")
if nsubs > 0 then
break
end
end
end
return full_placename, elliptical_placename
end
end
--[=[
This is typically used to define `placename_to_key`. It generates a function that appends a string to the end of a given
placename to get the key (see the definition of `placename_to_key` above in the documentation under "Location group
tables"). Optional `divtype_suffix` is a raw string (which should not contain hyphens or other characters that have
special meaning in Lua patterns) to be appended first to the placename; if already present at the end, it is not
appended. `container_suffix` is then added in the same fashion if given. Typical usage is like this:
```
placename_to_key = make_placename_to_key(", England")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, England"`)
or
```
placename_to_key = make_placename_to_key(", South Korea", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon County, South Korea"`).
]=]
local function make_placename_to_key(container_suffix, divtype_suffix)
return function(placename)
local key = placename
if divtype_suffix then
if not key:find(divtype_suffix .. "$") then
key = key .. divtype_suffix
end
end
if container_suffix then
key = key .. container_suffix
end
return key
end
end
--[=[
This is typically used to define `canonicalize_key_container`, which converts a container as specified in the location
data into the canonical form containing both the full container key and its placetype. It generates a function to do
the canonicalization of a given container. If the container is a string, `suffix` is appended onto the string (use {nil}
or {""} if there is no suffix to append), and the placetype is set to `placetype`. Otherwise the container is left
as-is. Typical usage is like this:
```
canonicalize_key_container = make_canonicalize_key_container(", Canada", "province")
```
which will convert e.g. `"Ontario"` into `{key = "Ontario, Canada", placetype = "province"}`.
]=]
local function make_canonicalize_key_container(suffix, placetype)
return function(container)
if type(container) == "string" then
return {key = container .. (suffix or ""), placetype = placetype}
else
return container
end
end
end
-----------------------------------------------------------------------------------
-- Top-level tables --
-----------------------------------------------------------------------------------
export.continents = {
["Bumi"] = {the = true, placetype = "planet", addl_parents = {"alam semula jadi"},
fulldesc = "=the planet [[Earth]] and the features found on it"},
["Afrika"] = {placetype = "benua", container = {key = "Bumi", placetype = "planet"}},
["Amerika"] = {placetype = {"superbenua", "benua"}, container = {key = "Bumi", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Amerika"},
["America"] = {alias_of = "Amerika", the = true},
["Amerika Utara"] = {placetype = "benua", container = {key = "America", placetype = "superbenua"}},
["Caribbean"] = {the = true, placetype = {"kawasan benua", "wilayah"}, container = {key = "Amerika Utara", placetype = "benua"}},
["Amerika Tengah"] = {placetype = {"kawasan benua", "wilayah"}, container = {key = "Amerika Utara", placetype = "benua"}},
["Amerika Selatan"] = {placetype = "benua", container = {key = "America", placetype = "superbenua"}},
["Antartika"] = {placetype = "benua", container = {key = "Bumi", placetype = "planet"},
fulldesc = "=benua [[Antarctica]]"},
["Eurasia"] = {placetype = {"superbenua", "benua"}, container = {key = "Bumi", placetype = "planet"},
keydesc = "[[Eurasia]], i.e. [[Europe]] and [[Asia]] together"},
["Asia"] = {placetype = "benua", container = {key = "Eurasia", placetype = "superbenua"}},
["Eropah"] = {placetype = "benua", container = {key = "Eurasia", placetype = "superbenua"}},
["Oceania"] = {placetype = "benua", container = {key = "Bumi", placetype = "planet"}},
["Melanesia"] = {placetype = {"kawasan benua", "wilayah"}, container = {key = "Oceania", placetype = "benua"}},
["Mikronesia"] = {placetype = {"kawasan benua", "wilayah"}, container = {key = "Oceania", placetype = "benua"}},
["Polinesia"] = {placetype = {"kawasan benua", "wilayah"}, container = {key = "Oceania", placetype = "benua"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "negara", prep = "di"}},
-- It's enough to mention the first-level continent or continent group. It seems excessive to write e.g.
-- "El Salvador, a country in Central America, a continental region in North America, a continent in America, ...".
default_no_include_container_in_desc = true,
default_no_container_cat = true,
default_no_container_parent = true,
default_no_auto_augment_container = true,
default_no_generic_place_cat = true,
-- French Guyana is in France but not in Europe, which should not be an issue, so don't check holonym mismatches at
-- this level. We also run into problems with supercontinents, which have "benua" as the fallback and cause
-- mismatches.
default_no_check_holonym_mismatch = true,
data = export.continents,
}
-- Countries: including those with partial recognition that are normally considered countries (e.g. Kosovo, Taiwan).
export.countries = {
["Afghanistan"] = {container = "Asia", divs = {"provinces", "daerah"}},
["Albania"] = {container = "Eropah", divs = {"kaunti", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "Afrika", divs = {"provinces", "communes", "daerah", "municipalities"}},
["Andorra"] = {container = "Eropah", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "Afrika", divs = {"provinces", "municipalities"}},
["Antigua dan Barbuda"] = {container = "Caribbean", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Amerika Selatan", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"Eropah", "Asia"}, divs = {"provinces", "daerah", "municipalities"},
british_spelling = true},
["Republik Armenia"] = {alias_of = "Armenia", the = true}, -- differs in "the"
-- Both a country and continent
["Australia"] = {container = "Oceania", divs = {
{type = "negeri", cat_as = "negeri dan wilayah"},
{type = "wilayah", cat_as = "negeri dan wilayah"},
{type = "ABBREVIATION_OF negeri", cat_as = "abbreviations of states and territories"},
{type = "ABBREVIATION_OF territories", cat_as = "abbreviations of states and territories"},
"local government areas", "dependent territories",
}, british_spelling = true},
["Austria"] = {container = "Eropah", divs = {"negeri", "daerah", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"Eropah", "Asia"}, divs = {"daerah", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribbean", divs = {"daerah"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "Asia", divs = {"kegabenoran"}},
["Bangladesh"] = {container = "Asia", divs = {"divisions", "daerah", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "Eropah", divs = {"wilayah", "daerah"}, british_spelling = true},
["Belgium"] = {container = "Eropah", divs = {"wilayah", "provinces", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Amerika Tengah", divs = {"daerah"}, british_spelling = true},
["Benin"] = {container = "Afrika", divs = {"departments", "communes"}},
["Bhutan"] = {container = "Asia", divs = {"daerah", "gewogs", "chiwogs"}},
["Bolivia"] = {container = "Amerika Selatan", divs = {"provinces", "departments", "municipalities"}},
["Bosnia dan Herzegovina"] = {container = "Eropah", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia dan Hercegovina"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Bosnia and Herzegovina"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Bosnia"] = {alias_of = "Bosnia dan Herzegovina", display = true},
["Botswana"] = {container = "Afrika", divs = {"daerah", "subdaerah"}, british_spelling = true},
["Brazil"] = {container = "Amerika Selatan", divs = {
"negeri", "municipalities", "macroregions",
{type = "ABBREVIATION_OF negeri", cat_as = "abbreviations of states"},
}},
["Brunei"] = {container = "Asia", divs = {"daerah", "mukim"}, british_spelling = true},
["Bulgaria"] = {container = "Eropah", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "Afrika", divs = {"wilayah", "departments", "provinces"}},
["Burundi"] = {container = "Afrika", divs = {"provinces", "communes"}},
["Kemboja"] = {container = "Asia", divs = {"provinces", "daerah"}},
["Cameroon"] = {container = "Afrika", divs = {"wilayah", "departments"}},
["Kanada"] = {container = "Amerika Utara", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces and territories"},
{type = "ABBREVIATION_OF territories", cat_as = "abbreviations of provinces and territories"},
"kaunti", "daerah", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
-- Don't change the following to something more politically correct (e.g. "First Nations reserves") until/unless
-- the Canadian government makes a similar switch (and note that as of Apr 18 2025, the Wikipedia article is
-- still at [[w:Indian reserves]]).
"Indian reserves",
"census divisions",
{type = "townships", prep = "di"},
},
british_spelling = true},
["Cape Verde"] = {container = "Afrika", divs = {"municipalities", "parishes"}},
["Republik Afrika Tengah"] = {the = true, container = "Afrika", divs = {"prefectures", "subprefectures"}},
["Chad"] = {container = "Afrika", divs = {"wilayah", "departments"}},
["Chile"] = {container = "Amerika Selatan", divs = {"wilayah", "provinces", "communes"}},
["China"] = {container = "Asia", divs = {
{type = "provinces", cat_as = "provinces and autonomous regions"},
{type = "autonomous regions", cat_as = "provinces and autonomous regions"},
{type = "FORMER provinces", cat_as = "former provinces"},
"special administrative regions",
"prefectures",
{type = "FORMER prefectures", cat_as = "former prefectures"},
"prefecture-level cities",
{type = "kaunti", cat_as = "counties and county-level cities"},
{type = "county-level cities", cat_as = "counties and county-level cities"},
{type = "FORMER counties", cat_as = "former counties and county-level cities"},
{type = "FORMER county-level cities", cat_as = "former counties and county-level cities"},
-- "towns" (but not "townships") are automatically added as they are specified as generic_before_non_cities.
"daerah",
{type = "FORMER districts", cat_as = "former districts"},
"subdaerah",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["Republik Rakyat China"] = {alias_of = "China", the = true}, -- differs in "the"
["Colombia"] = {container = "Amerika Selatan", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "Afrika", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Amerika Tengah", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "Eropah", divs = {"kaunti", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribbean", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"Eropah", "Asia"}, divs = {"daerah"}, british_spelling = true},
["Republik Czech"] = {the = true, container = "Eropah", divs = {"wilayah", "daerah", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Republik Demokratik Congo"] = {the = true, container = "Afrika", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Denmark"] = {container = "Eropah", divs = {"wilayah", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "Afrika", divs = {"wilayah", "daerah"}},
["Dominica"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Republik Dominica"] = {the = true, container = "Caribbean", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["East Timor"] = {container = "Asia", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "East Timor", display = true},
["Ecuador"] = {container = "Amerika Selatan", divs = {"provinces", "cantons"}},
["Mesir"] = {container = "Afrika", divs = {"kegabenoran", "wilayah"}, british_spelling = true},
["El Salvador"] = {container = "Amerika Tengah", divs = {"departments", "municipalities"}},
["Guinea Khatulistiwa"] = {container = "Afrika", divs = {"provinces"}},
["Eritrea"] = {container = "Afrika", divs = {"wilayah", "subregions"}},
["Estonia"] = {container = "Eropah", divs = {"kaunti", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "Afrika", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "Afrika", divs = {"wilayah", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Mikronesia", divs = {"negeri"}},
["Mikronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Finland"] = {container = "Eropah", divs = {"wilayah", "municipalities"}, british_spelling = true},
["Perancis"] = {container = "Eropah", divs = {"wilayah", "kanton", "collectivities",
"communes",
{type = "municipalities", cat_as = "communes"},
"departments",
{type = "prefectures", cat_as = {"prefectures", "departmental capitals"}},
{type = "French prefectures", cat_as = {"prefectures", "departmental capitals"}},
"dependent territories", "territories", "provinces",
}, british_spelling = true},
["Gabon"] = {container = "Afrika", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "Afrika", divs = {"divisions", "daerah"}, british_spelling = true, wp = "The %l"},
["Georgia"] = {container = {"Eropah", "Asia"}, divs = {"wilayah", "daerah"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l (country)"},
["Jerman"] = {container = "Eropah", divs = {
"negeri",
-- Bavaria, Baden-Württemberg, Hesse and North Rhine-Westphalia have administrative regions as divisions, but
-- there aren't really enough of them to categorize per state.
"wilayah",
"municipalities", "daerah"}, british_spelling = true},
["Ghana"] = {container = "Afrika", divs = {"wilayah", "daerah"}, british_spelling = true},
["Greece"] = {container = "Eropah", divs = {"wilayah", "regional units", "municipalities",
{type = "peripheries", cat_as = {"wilayah"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Amerika Tengah", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "Afrika", divs = {"wilayah", "prefectures"}},
["Guinea-Bissau"] = {container = "Afrika", divs = {"wilayah"}},
["Guyana"] = {container = "Amerika Selatan", divs = {"wilayah"}, british_spelling = true},
["Haiti"] = {container = "Caribbean", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Amerika Tengah", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "Eropah", divs = {"kaunti", "daerah"}, british_spelling = true},
["Iceland"] = {container = "Eropah", divs = {"wilayah", "municipalities", "kaunti"}, british_spelling = true},
["India"] = {container = "Asia", divs = {
{type = "negeri", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF negeri", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "daerah", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "Asia", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "Asia", divs = {"provinces", "kaunti"}},
["Iraq"] = {container = "Asia", divs = {"kegabenoran", "daerah"}},
["Ireland"] = {container = "Eropah", addl_parents = {"British Isles"},
divs = {"kaunti", "daerah", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republik Ireland"] = {alias_of = "Ireland", the = true}, -- differs in "the"
["Israel"] = {container = "Asia", divs = {"daerah"}},
["Itali"] = {container = "Eropah", divs = {
"wilayah", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "wilayah"},
}, british_spelling = true},
["Ivory Coast"] = {container = "Afrika", divs = {"daerah", "wilayah"}},
-- We should really be using Ivory Coast (common name) but there are political ramifications to the use of
-- Côte d'Ivoire so don't make it a display alias.
["Côte d'Ivoire"] = {alias_of = "Ivory Coast"},
["Jamaica"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Jepun"] = {container = "Asia", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "Asia", divs = {"kegabenoran"}},
["Kazakhstan"] = {container = {"Asia", "Eropah"}, divs = {"wilayah", "daerah"}},
["Kenya"] = {container = "Afrika", divs = {"kaunti"}, british_spelling = true},
["Kiribati"] = {container = "Mikronesia", british_spelling = true},
["Kosovo"] = {container = "Eropah", divs = {"daerah", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "Asia", divs = {"kegabenoran", "areas"}},
["Kyrgyzstan"] = {container = "Asia", divs = {"wilayah", "daerah"}},
["Laos"] = {container = "Asia", divs = {"provinces", "daerah"}},
["Latvia"] = {container = "Eropah", divs = {"municipalities"}, british_spelling = true},
["Lubnan"] = {container = "Asia", divs = {"kegabenoran", "daerah"}},
["Lesotho"] = {container = "Afrika", divs = {"daerah"}, british_spelling = true},
["Liberia"] = {container = "Afrika", divs = {"kaunti", "daerah"}},
["Libya"] = {container = "Afrika", divs = {"daerah", "municipalities"}},
["Liechtenstein"] = {container = "Eropah", divs = {"municipalities"}, british_spelling = true},
["Lithuania"] = {container = "Eropah", divs = {"kaunti", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "Eropah", divs = {"cantons", "daerah"}, british_spelling = true},
["Madagascar"] = {container = "Afrika", divs = {"wilayah", "daerah"}},
["Malawi"] = {container = "Afrika", divs = {"wilayah", "daerah"}, british_spelling = true},
["Malaysia"] = {container = "Asia", divs = {"negeri", "wilayah persekutuan", "daerah"}, british_spelling = true},
["Maldives"] = {the = true, container = "Asia", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "Afrika", divs = {"wilayah", "cercles"}},
["Malta"] = {container = "Eropah", divs = {"wilayah", "local councils"}, british_spelling = true},
["Kepulauan Marshall"] = {the = true, container = "Mikronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "Afrika", divs = {"wilayah", "departments"}},
["Mauritius"] = {container = "Afrika", divs = {"daerah"}, british_spelling = true},
["Mexico"] = {container = "Amerika Utara", addl_parents = {"Amerika Tengah"}, divs = {
"negeri", "municipalities",
{type = "ABBREVIATION_OF negeri", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "Eropah", divs = {
{type = "daerah", cat_as = "districts and autonomous territorial units"},
{type = "autonomous territorial units", cat_as = "districts and autonomous territorial units"},
"communes", "municipalities",
}, british_spelling = true},
["Monaco"] = {placetype = {"negara kota", "negara"}, container = "Eropah",
-- We want the first placetype to be 'city-state' so the description of Monaco says it's a city-state, but we
-- want its parent to be "countries in Europe".
bare_category_parent_type = {type = "negara", prep = "di"},
is_city = true, british_spelling = true},
["Mongolia"] = {container = "Asia", divs = {"provinces", "daerah"}},
["Montenegro"] = {container = "Eropah", divs = {"municipalities"}},
["Maghribi"] = {container = "Afrika", divs = {"wilayah", "prefectures", "provinces"}},
["Mozambique"] = {container = "Afrika", divs = {"provinces", "daerah"}},
["Myanmar"] = {container = "Asia",
divs = {"wilayah", "negeri", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"daerah"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "Afrika", divs = {"wilayah", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Mikronesia", divs = {"daerah"}, british_spelling = true},
["Nepal"] = {container = "Asia", divs = {"provinces", "daerah"}},
["Belanda"] = {the = true, placetype = {"negara", "negara bahagian"}, container = "Eropah",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "negara bahagian"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polinesia", divs = {
"wilayah", "dependent territories", "territorial authorities",
{type = "daerah", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Amerika Tengah", divs = {"departments", "municipalities"}},
["Niger"] = {container = "Afrika", divs = {"wilayah", "departments"}},
["Nigeria"] = {container = "Afrika", divs = {
"negeri",
-- Categorize the Federal Capital Territory as a state because there's only one of it; we could categorize
-- everything under 'states and territories' but that seems a bit pointless.
{type = "wilayah persekutuan", cat_as = "negeri"},
"local government areas",
}, british_spelling = true},
["Korea Utara"] = {container = "Asia", addl_parents = {"Korea"}, divs = {"provinces", "kaunti"}},
["Macedonia Utara"] = {container = "Eropah", divs = {"wilayah", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "Macedonia Utara", display = true},
["Republik Macedonia Utara"] = {alias_of = "Macedonia Utara", the = true}, -- differs in "the"
["Republik Macedonia"] = {alias_of = "Macedonia Utara", the = true}, -- differs in "the"
["Norway"] = {container = "Eropah",
divs = {"kaunti", "municipalities", "dependent territories", "daerah", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "Asia", divs = {"kegabenoran", "provinces"}},
["Pakistan"] = {container = "Asia", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "wilayah persekutuan", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "daerah",
}, british_spelling = true},
["Palau"] = {container = "Mikronesia", divs = {"negeri"}},
["Palestin"] = {container = "Asia", divs = {"kegabenoran"}},
["Negara Palestin"] = {alias_of = "Palestine", the = true}, -- differs in "the"
["Panama"] = {container = "Amerika Tengah", divs = {"provinces", "daerah"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "daerah"}, british_spelling = true},
["Paraguay"] = {container = "Amerika Selatan", divs = {"departments", "daerah"}},
["Peru"] = {container = "Amerika Selatan", divs = {"wilayah", "provinces", "daerah"}},
["Filipina"] = {the = true, container = "Asia", divs = {
"wilayah",
"wilayah",
"daerah",
"perbandaran",
"barangay",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
{type = "ABBREVIATION_OF barangays", cat_as = "abbreviations of barangays"},
}},
["Poland"] = {divs = {"voivodeships", "kaunti",
{type = "Polish colonies", cat_as = {{type = "kampung", prep = "di"}}},
}, container = "Eropah", british_spelling = true},
["Portugal"] = {container = "Eropah", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "daerah", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "Asia", divs = {"municipalities", "zones"}},
["Republik Congo"] = {the = true, container = "Afrika", divs = {"departments", "daerah"}},
["Romania"] = {container = "Eropah", divs = {
"wilayah", "kaunti", "communes",
{type = "ABBREVIATION_OF kaunti", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Rusia"] = {container = {"Eropah", "Asia"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"daerah", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "Afrika", divs = {"provinces", "daerah"}},
["Saint Kitts dan Nevis"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Saint Lucia"] = {container = "Caribbean", divs = {"daerah"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true},
["Samoa"] = {container = "Polinesia", divs = {"daerah"}, british_spelling = true},
["San Marino"] = {container = "Eropah", divs = {"municipalities"}, british_spelling = true},
["São Tomé dan Príncipe"] = {container = "Afrika", divs = {"daerah"}},
["Arab Saudi"] = {container = "Asia", divs = {"wilayah", "kegaboneran"}},
["Senegal"] = {container = "Afrika", divs = {"wilayah", "departments"}},
["Serbia"] = {container = "Eropah", divs = {"daerah", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "Afrika", divs = {"daerah"}, british_spelling = true},
["Sierra Leone"] = {container = "Afrika", divs = {"provinces", "daerah"}, british_spelling = true},
["Singapura"] = {container = "Asia", divs = {"daerah", "wilayah"}, british_spelling = true},
["Slovakia"] = {container = "Eropah", divs = {"wilayah", "daerah"}, british_spelling = true},
["Slovenia"] = {container = "Eropah", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: the official name does not include "the" at the beginning, but it sounds strange in
-- English to leave it out and it's commonly included, so we include it.
["Kepulauan Solomon"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "Afrika", divs = {"wilayah", "daerah"}},
["Afrika Selatan"] = {container = "Afrika", divs = {
"provinces",
"daerah",
{type = "district municipalities", cat_as = "daerah"},
{type = "metropolitan municipalities", cat_as = "daerah"},
"municipalities",
}, british_spelling = true},
["Korea Selatan"] = {container = "Asia", addl_parents = {"Korea"}, divs = {"provinces", "kaunti", "daerah"}},
["Sudan Selatan"] = {container = "Afrika", divs = {"wilayah", "negeri", "kaunti"}, british_spelling = true},
["Sepanyol"] = {container = "Eropah", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "Asia", divs = {"provinces", "daerah"}, british_spelling = true},
["Sudan"] = {container = "Afrika", divs = {"negeri", "daerah"}, british_spelling = true},
["Suriname"] = {container = "Amerika Selatan", divs = {"daerah"}},
["Sweden"] = {container = "Eropah", divs = {"provinces", "kaunti", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "Eropah", divs = {"cantons", "municipalities", "daerah"}, british_spelling = true},
["Syria"] = {container = "Asia", divs = {"kegabenoran", "daerah"}},
["Taiwan"] = {container = "Asia", divs = {"kaunti", "daerah", "townships", "special municipalities"}},
["Republik China"] = {alias_of = "Taiwan", the = true}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "Asia", divs = {"wilayah", "daerah"}},
["Tanzania"] = {container = "Afrika", divs = {"wilayah", "daerah"}, british_spelling = true},
["Thailand"] = {container = "Asia", divs = {"wilayah", "daerah", "subdaerah"}},
["Togo"] = {container = "Afrika", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polinesia", divs = {"divisions"}, british_spelling = true},
["Trinidad dan Tobago"] = {container = "Caribbean", divs = {"wilayah", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "Afrika", divs = {"kegabenoran", "delegations"}},
["Turki"] = {container = {"Eropah", "Asia"}, divs = {"provinces", "daerah"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Turkey", display = true},
["Turkmenistan"] = {container = "Asia", divs = {
-- The 5 regions are often also called provinces
"wilayah", {type = "provinces", cat_as = "wilayah"}, "daerah"},
},
["Tuvalu"] = {container = "Polinesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "Afrika", divs = {"daerah", "kaunti"}, british_spelling = true},
["Ukraine"] = {container = "Eropah", divs = {
{type = "oblasts", cat_as = "oblasts and autonomous republics"},
{type = "autonomous republics", cat_as = "oblasts and autonomous republics"},
"raions", "hromadas",
}, british_spelling = true},
["United Arab Emirates"] = {the = true, container = "Asia", divs = {"emirates"}},
-- Abbreviations get display-canonicalized.
["UAE"] = {alias_of = "United Arab Emirates", display = true, the = true},
["U.A.E."] = {alias_of = "United Arab Emirates", display = true, the = true},
["United Kingdom"] = {the = true, container = "Eropah", addl_parents = {"British Isles"},
divs = {"negara bahagian", "kaunti", "daerah", "boroughs", "territories", "dependent territories",
"traditional counties"},
keydesc = "the [[United Kingdom]] of Great Britain and Northern Ireland", british_spelling = true},
-- Abbreviations get display-canonicalized.
["UK"] = {alias_of = "United Kingdom", display = true, the = true},
["U.K."] = {alias_of = "United Kingdom", display = true, the = true},
["Amerika Syarikat"] = {the = true, container = "Amerika Utara",
divs = {"kaunti", "county seats", "negeri", "territories", "dependent territories",
{type = "ABBREVIATION_OF negeri", cat_as = "abbreviations of states"},
{type = "DEROGATORY_NAME_FOR states", cat_as = "derogatory names for states"},
{type = "NICKNAME_FOR states", cat_as = "nicknames for states"},
{type = "OFFICIAL_NICKNAME_FOR states", cat_as = "official nicknames for states"},
{type = "boroughs", prep = "di"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "di"},
{type = "unincorporated communities", prep = "di"},
-- Don't change the following to something more politically correct until/unless the US government makes a
-- similar switch (and note that as of Apr 18 2025, the Wikipedia article is still at
-- [[w:Indian reservations]]).
"Indian reservations",
}},
-- Abbreviations and long forms (when possible) get display-canonicalized.
["US"] = {alias_of = "Amerika Syarikat", display = true, the = true},
["U.S."] = {alias_of = "Amerika Syarikat", display = true, the = true},
["USA"] = {alias_of = "Amerika Syarikat", display = true, the = true},
["U.S.A."] = {alias_of = "Amerika Syarikat", display = true, the = true},
["United States of America"] = {alias_of = "Amerika Syarikat", display = true, the = true},
["United States"] = {alias_of = "Amerika Syarikat", display = true, the = true},
["Uruguay"] = {container = "Amerika Selatan", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "Asia", divs = {"wilayah", "daerah"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Kota Vatikan"] = {placetype = {"negara kota", "negara"}, container = "Eropah",
-- We want the first placetype to be 'city-state' so the description of Vatican City says it's a city-state,
-- but we want its parent to be "countries in Europe".
bare_category_parent_type = {type = "negara", prep = "di"},
addl_parents = {"Rom"}, is_city = true, british_spelling = true},
["Vatikan"] = {alias_of = "Kota Vatikan", the = true}, -- differs in "the"
["Venezuela"] = {container = "Amerika Selatan", divs = {"negeri", "municipalities"}},
["Vietnam"] = {container = "Asia", divs = {"wilayah", "daerah", "perbandaran"}},
["Sahara Barat"] = {placetype = {"wilayah", "negara"}, container = "Afrika",
bare_category_parent_type = {type = "negara", prep = "di"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara", the = true},
["Yaman"] = {container = "Asia", divs = {"kegabenoran", "daerah"}},
["Zambia"] = {container = "Afrika", divs = {"provinces", "daerah"}, british_spelling = true},
["Zimbabwe"] = {container = "Afrika", divs = {"provinces", "daerah"}, british_spelling = true},
}
local function canonicalize_continent_container(key)
if type(key) ~= "string" then
return key
end
if export.continents[key] then
return {key = key, placetype = export.continents[key].placetype}
end
internal_error("Unrecognized key %s in `canonicalize_continent_like`", key)
end
export.countries_group = {
canonicalize_key_container = canonicalize_continent_container,
default_overriding_bare_label_parents = {"+++", "negara"},
default_placetype = "negara",
default_no_container_cat = true,
default_no_container_parent = true,
-- No need to augment country holonyms with continents; not needed for disambiguation.
default_no_auto_augment_container = true,
data = export.countries,
}
-- Country-like entities: typically overseas territories or de-facto independent countries, which in both cases
-- are not internationally recognized as sovereign nations but which we treat similarly to countries.
export.country_like_entities = {
-- British Overseas Territory
["Akrotiri and Dhekelia"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Cyprus", "Eropah", "Asia"},
british_spelling = true,
},
-- Åland: Listed as a region of Finland. Wikipedia lists this under "dependent territories" in
-- [[w:List of sovereign states and dependent territories by continent]].
-- unincorporated territory of the United States
["American Samoa"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Polinesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "negara"},
addl_parents = {"Georgia", "Eropah", "Asia"},
divs = {"daerah"},
keydesc = "the de-facto independent state of [[Abkhazia]], internationally recognized as part of the country of [[Georgia]]",
british_spelling = true,
},
-- Australian external territory
["Ashmore and Cartier Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Australia",
addl_parents = {"Asia"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"negara bahagian", "negara"},
container = "Netherlands",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Amerika Utara"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribbean"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Asia"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Norway",
addl_parents = {"Afrika"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Australia",
addl_parents = {"Asia"},
british_spelling = true,
},
-- Sui generis French "state private property" per Wikipedia; classify as overseas territory like the
-- French Southern and Antarctic Lands.
["Clipperton Island"] = {
placetype = {"overseas territory", "territory"},
container = "France",
addl_parents = {"Amerika Utara"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Australia",
addl_parents = {"Asia"},
wp = "Cocos (Keeling) Islands",
british_spelling = true,
},
["Cocos (Keeling) Islands"] = {alias_of = "Cocos Islands", display = true, the = true},
["Keeling Islands"] = {alias_of = "Cocos Islands", display = true, the = true},
-- self-governing but in free association with New Zealand
["Cook Islands"] = {
the = true,
placetype = {"negara"},
container = "New Zealand",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"negara bahagian", "negara"},
container = "Netherlands",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polinesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Amerika Selatan"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Denmark",
addl_parents = {"Eropah"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "wilayah"},
container = "France",
divs = {"communes"},
addl_parents = {"Amerika Selatan"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "France",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "France",
addl_parents = {"Afrika"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Eropah"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Denmark",
addl_parents = {"Amerika Utara"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "wilayah"},
container = "France",
addl_parents = {"Caribbean"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Mikronesia"},
},
-- self-governing British Crown dependency; technically called the Bailiwick of Guernsey
["Guernsey"] = {
placetype = {"crown dependency", "dependency", "dependent territory", "bailiwick", "territory"},
container = "United Kingdom",
addl_parents = {"British Isles", "Eropah"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey", the = true},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Australia",
addl_parents = {"Afrika"},
},
-- special administrative region of China
["Hong Kong"] = {
placetype = {"special administrative region", "bandar"},
container = "China",
is_city = true,
british_spelling = true,
},
-- self-governing British Crown dependency
["Isle of Man"] = {
the = true,
placetype = {"crown dependency", "dependency", "dependent territory", "territory"},
container = "United Kingdom",
addl_parents = {"British Isles", "Eropah"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "pulau"},
container = "Norway",
addl_parents = {"Eropah"},
british_spelling = true,
},
-- self-governing British Crown dependency; technically called the Bailiwick of Jersey
["Jersey"] = {
placetype = {"crown dependency", "dependency", "dependent territory", "bailiwick", "territory"},
container = "United Kingdom",
addl_parents = {"British Isles", "Eropah"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey", the = true},
-- special administrative region of China
["Macau"] = {
placetype = {"special administrative region", "bandar"},
container = "China",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "wilayah"},
container = "France",
divs = {"communes"},
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "wilayah"},
container = "France",
divs = {"communes"},
addl_parents = {"Afrika"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "France",
addl_parents = {"Melanesia"},
british_spelling = true,
},
-- dependent territory of New Zealand
["New Zealand Subantarctic Islands"] = {
the = true,
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Antartika"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"negara"},
container = "New Zealand",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Australia",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "negara"},
addl_parents = {"Cyprus", "Turkey", "Eropah", "Asia"},
divs = {"daerah"},
keydesc = "the de-facto independent state of [[Northern Cyprus]], internationally recognized as part of the country of [[Cyprus]]",
british_spelling = true,
},
-- commonwealth, unincorporated territory of the United States
["Northern Mariana Islands"] = {
the = true,
placetype = {"commonwealth", "unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Mikronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Caribbean"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "wilayah"},
container = "France",
divs = {"communes"},
addl_parents = {"Afrika"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribbean"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "France",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- British Overseas Territory
["Saint Helena, Ascension and Tristan da Cunha"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
divs = {{type = "constituent parts", container_parent_type = false}},
addl_parents = {"Atlantic Ocean", "Afrika"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "pulau"},
container = {key = "Saint Helena, Ascension and Tristan da Cunha", placetype = "overseas territory"},
addl_parents = {"Atlantic Ocean"},
overriding_bare_label_parents = {},
no_container_cat = false,
no_container_parent = false,
no_auto_augment_container = false,
},
["Saint Helena"] = {
placetype = {"constituent part", "territory", "pulau"},
container = {key = "Saint Helena, Ascension and Tristan da Cunha", placetype = "overseas territory"},
addl_parents = {"Atlantic Ocean"},
overriding_bare_label_parents = {},
no_container_cat = false,
no_container_parent = false,
no_auto_augment_container = false,
},
["Tristan da Cunha"] = {
placetype = {"constituent part", "territory", "archipelago"},
container = {key = "Saint Helena, Ascension and Tristan da Cunha", placetype = "overseas territory"},
addl_parents = {"Atlantic Ocean"},
overriding_bare_label_parents = {},
no_container_cat = false,
no_container_parent = false,
no_auto_augment_container = false,
},
-- overseas collectivity of France
["Saint Martin"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "France",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "France",
divs = {"communes"},
addl_parents = {"Amerika Utara"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribbean"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"negara bahagian", "negara"},
container = "Netherlands",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "negara"},
addl_parents = {"Somalia", "Afrika"},
keydesc = "the de-facto independent state of [[Somaliland]], internationally recognized as part of the country of [[Somalia]]",
british_spelling = true,
},
-- British Overseas Territory
-- FIXME: We should form the group "South Georgia and the South Sandwich Islands" like we did for
-- "Saint Helena, Ascension and Tristan da Cunha".
["South Georgia"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Atlantic Ocean"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["South Ossetia"] = {
placetype = {"unrecognized country", "negara", "kawasan geografi", "wilayah"},
addl_parents = {"Georgia", "Eropah", "Asia"},
keydesc = "kawasan geografi dan negara merdeka de facto [[South Ossetia]], yang diiktiraf di peringkat antarabangsa sebagai sebahagian daripada negara [[Georgia]]",
british_spelling = true,
},
-- British Overseas Territory
["South Sandwich Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Atlantic Ocean"},
wp = true,
wpcat = "South Georgia and the South Sandwich Islands",
british_spelling = true,
},
-- Norwegian unincorporated area
["Svalbard"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "archipelago"},
container = "Norway",
addl_parents = {"Eropah"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polinesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "negara"},
addl_parents = {"Moldova", "Eropah"},
keydesc = "the de-facto independent state of [[Transnistria]], internationally recognized as part of [[Moldova]]",
british_spelling = true,
},
-- British Overseas Territory
["Turks and Caicos Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribbean"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Islands", "Mikronesia", "Polinesia", "Caribbean"},
},
-- FIXME: We should add entries for the other minor outlying islands.
-- Baker Island (Oceania)
-- Howland Island (Oceania)
-- Jarvis Island (Oceania)
-- Johnston Atoll (Oceania)
-- Kingman Reef (Oceania)
-- Midway Atoll (Oceania)
-- Navassa Island (Caribbean)
-- Palmyra Atoll (Oceania)
-- Wake Island (Oceania)
["Wake Island"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Mikronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Amerika Syarikat",
addl_parents = {"Caribbean"},
},
["U.S. Virgin Islands"] = {alias_of = "United States Virgin Islands", display = true, the = true},
["US Virgin Islands"] = {alias_of = "United States Virgin Islands", display = true, the = true},
-- overseas collectivity of France
["Wallis dan Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Perancis",
addl_parents = {"Polinesia"},
british_spelling = true,
},
}
export.country_like_entities_group = {
-- don't do any transformations between key and placename; in particular, don't chop off anything from
-- "Saint Helena, Ascension and Tristan da Cunha".
key_to_placename = false,
placename_to_key = false,
canonicalize_key_container = make_canonicalize_key_container(nil, "negara"),
default_overriding_bare_label_parents = {"country-like entities"},
default_no_container_cat = true,
default_no_container_parent = true,
-- These entities often aren't really part of their container; a village in Wallis and Futuna (an overseas
-- collectivity of France in Polynesia), for example, shouldn't be treated as a village in France, nor as a village
-- in Europe.
default_no_auto_augment_container = true,
data = export.country_like_entities,
}
-- Former countries and such; we don't create "Cities in ..." categories because they don't exist anymore
export.former_countries = {
-- de-facto independent state of Armenian ethnicity, internationally recognized as part of Azerbaijan
-- (also known as Nagorno-Karabakh)
-- NOTE: Formerly listed Armenia as a parent; this seems politically non-neutral so I've taken it out.
["Artsakh"] = {
placetype = {"unrecognized country", "negara"},
addl_parents = {"Azerbaijan", "Eropah", "Asia"},
keydesc = "the former de-facto independent state of [[Artsakh]], internationally recognized as part of [[Azerbaijan]]",
british_spelling = true,
},
["Nagorno-Karabakh"] = {alias_of = "Artsakh"},
["Czechoslovakia"] = {container = "Eropah", british_spelling = true},
["Jerman Timur"] = {container = "Eropah", addl_parents = {"Germany"}, british_spelling = true},
["Vietnam Utara"] = {container = "Asia", addl_parents = {"Vietnam"}},
["Parsi"] = {placetype = {"empayar", "negara"}, container = "Asia", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empayar", "negara"}, container = {"Eropah", "Afrika", "Asia"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Empayar Rom"] = {
the = true, placetype = {"empayar", "negara"}, container = {"Eropah", "Afrika", "Asia"}, addl_parents = {"Rom"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Vietnam Selatan"] = {container = "Asia", addl_parents = {"Vietnam"}},
["Kesatuan Soviet"] = {
the = true, container = {"Eropah", "Asia"}, divs = {"republik", "autonomous republics"},
british_spelling = true},
["Jerman Barat"] = {container = "Eropah", addl_parents = {"Jerman"}, british_spelling = true},
["Yugoslavia"] = {container = "Eropah", divs = {"daerah"},
keydesc = "the former [[Kingdom of Yugoslavia]] (1918–1943) or the former [[Socialist Federal Republic of Yugoslavia]] (1943–1992)", british_spelling = true},
}
export.former_countries_group = {
canonicalize_key_container = canonicalize_continent_container,
default_overriding_bare_label_parents = {"former countries and country-like entities"},
default_is_former_place = true,
default_placetype = "negara",
default_no_container_cat = true,
default_no_container_parent = true,
-- No need to augment country holonyms with continents; not needed for disambiguation.
default_no_auto_augment_container = true,
data = export.former_countries,
}
-----------------------------------------------------------------------------------
-- Subpolity tables --
-----------------------------------------------------------------------------------
export.australia_states_and_territories = {
["Australian Capital Territory, Australia"] = {the = true, placetype = "territory"},
["Jervis Bay Territory, Australia"] = {the = true, placetype = "territory"},
["New South Wales, Australia"] = {},
["Northern Territory, Australia"] = {the = true, placetype = "territory"},
["Queensland, Australia"] = {},
["South Australia, Australia"] = {},
["Tasmania, Australia"] = {},
["Victoria, Australia"] = {},
["Western Australia, Australia"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Australia",
default_placetype = "negeri",
default_divs = "local government areas",
data = export.australia_states_and_territories,
}
export.austria_states = {
["Vienna, Austria"] = {},
["Lower Austria, Austria"] = {},
["Upper Austria, Austria"] = {},
["Styria, Austria"] = {},
["Tyrol, Austria"] = {wp = "Tyrol (state)"},
["Carinthia, Austria"] = {},
["Salzburg, Austria"] = {wp = "Salzburg (state)"},
["Vorarlberg, Austria"] = {},
["Burgenland, Austria"] = {},
}
-- states of Austria
export.austria_group = {
default_container = "Austria",
default_placetype = "negeri",
default_divs = "municipalities",
data = export.austria_states,
}
export.bangladesh_divisions = {
["Barisal Division, Bangladesh"] = {},
["Chittagong Division, Bangladesh"] = {},
["Dhaka Division, Bangladesh"] = {},
["Khulna Division, Bangladesh"] = {},
["Mymensingh Division, Bangladesh"] = {},
["Rajshahi Division, Bangladesh"] = {},
["Rangpur Division, Bangladesh"] = {},
["Sylhet Division, Bangladesh"] = {},
}
-- divisions of Bangladesh
export.bangladesh_group = {
key_to_placename = make_key_to_placename(", Bangladesh$", " Division$"),
placename_to_key = make_placename_to_key(", Bangladesh", " Division"),
default_container = "Bangladesh",
default_placetype = "division",
default_divs = "daerah",
data = export.bangladesh_divisions,
}
export.brazil_states = {
["Acre, Brazil"] = {wp = "%l (state)"},
["Alagoas, Brazil"] = {},
["Amapá, Brazil"] = {},
["Amazonas, Brazil"] = {wp = "%l (Brazilian state)"},
["Bahia, Brazil"] = {},
["Ceará, Brazil"] = {},
["Distrito Federal, Brazil"] = {wp = "Federal District (Brazil)"},
["Espírito Santo, Brazil"] = {},
["Goiás, Brazil"] = {},
["Maranhão, Brazil"] = {},
["Mato Grosso, Brazil"] = {},
["Mato Grosso do Sul, Brazil"] = {},
["Minas Gerais, Brazil"] = {},
["Pará, Brazil"] = {},
["Paraíba, Brazil"] = {},
["Paraná, Brazil"] = {wp = "%l (state)"},
["Pernambuco, Brazil"] = {},
["Piauí, Brazil"] = {},
["Rio de Janeiro, Brazil"] = {wp = "%l (state)"},
["Rio Grande do Norte, Brazil"] = {},
["Rio Grande do Sul, Brazil"] = {},
["Rondônia, Brazil"] = {},
["Roraima, Brazil"] = {},
["Santa Catarina, Brazil"] = {wp = "%l (state)"},
["São Paulo, Brazil"] = {wp = "%l (state)"},
["Sergipe, Brazil"] = {},
["Tocantins, Brazil"] = {},
}
-- states of Brazil
export.brazil_group = {
default_container = "Brazil",
default_placetype = "negeri",
default_divs = "municipalities",
data = export.brazil_states,
}
export.canada_provinces_and_territories = {
["Alberta, Canada"] = {divs = {
{type = "municipal districts", container_parent_type = "rural municipalities"},
}},
["British Columbia, Canada"] = {divs =
{type = "regional districts", container_parent_type = false},
"regional municipalities",
},
["Manitoba, Canada"] = {divs = {"rural municipalities"}},
["New Brunswick, Canada"] = {divs = {"kaunti", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"kaunti", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"kaunti", "regional municipalities", {type = "townships", prep = "di"}}},
["Prince Edward Island, Canada"] = {divs = {"kaunti", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"kaunti",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
-- administrative regions have an official (but non-governmental) function but there don't appear to be any
-- equivalent regions elsewhere in Canada, so disable the [[Category:Regions of Canada]] grouping
{type = "wilayah", container_parent_type = false},
{type = "townships", prep = "di"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "kaunti"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "di"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "kampung", prep = "di"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada", the = true},
}
-- provinces and territories of Canada
export.canada_group = {
default_container = "Canada",
default_placetype = "province",
data = export.canada_provinces_and_territories,
}
export.china_provinces_and_autonomous_regions = {
-- direct-administered municipalities are not here but below under prefecture-level cities
["Anhui, China"] = {},
["Fujian, China"] = {},
["Fuchien, China"] = {alias_of = "Fujian, China", display = true},
["Gansu, China"] = {},
["Guangdong, China"] = {},
["Guangxi, China"] = {placetype = "autonomous region"},
["Guizhou, China"] = {},
["Hainan, China"] = {},
["Hebei, China"] = {},
["Heilongjiang, China"] = {},
["Henan, China"] = {},
["Hubei, China"] = {},
["Hunan, China"] = {},
["Inner Mongolia, China"] = {placetype = "autonomous region"},
["Jiangsu, China"] = {},
["Jiangxi, China"] = {},
["Jilin, China"] = {},
["Liaoning, China"] = {},
["Ningxia, China"] = {placetype = "autonomous region"},
["Qinghai, China"] = {},
["Shaanxi, China"] = {},
["Shandong, China"] = {},
["Shanxi, China"] = {},
["Sichuan, China"] = {},
["Tibet, China"] = {placetype = "autonomous region", wp = "Tibet Autonomous Region"},
["Xinjiang, China"] = {placetype = "autonomous region"},
["Yunnan, China"] = {},
["Zhejiang, China"] = {},
}
-- provinces and autonomous regions of China
export.china_group = {
default_container = "China",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"daerah", "subdaerah", "townships",
{type = "kaunti", cat_as = "counties and county-level cities"},
{type = "county-level cities", cat_as = "counties and county-level cities"},
},
data = export.china_provinces_and_autonomous_regions,
}
export.china_prefecture_level_cities = {
-- In China, a "prefecture-level city" is not a city in any real sense. It is rather a prefecture, which is an
-- administrative unit smaller than a province but bigger than a county, which is administratively controlled by
-- the chief city of the prefecture (which bears the same name as the prefecture), in a unified government. Prior
-- to the mid-1980's, in fact, prefecture-level cities *were* prefectures, and a few of them (especially in the
-- western portion of China) have not yet been converted. Generally a given province is entirely tiled by
-- prefecture-level cities, another indication that they should be treated as prefectures and not cities per se.
-- Yet another indication is that prefecture-level cities can contain counties and county-level cities (which, much
-- like prefecture-level cities, are effectively counties surrounding a chief city of the county, again which bears
-- the same name as the county-level city).
--
-- For this reason, we treat prefecture-level cities as non-city political divisions, and separately enumerate the
-- most populous so we can separately categorize districts and counties under them instead of lumping them at the
-- province level.
--
-- Note also that China separately distinguishes "urban area" from "metro area". Sometimes the two figures are
-- identical but sometimes the metro area is larger (and very occasionally smaller, which I assume is an error). I'm
-- guessing that the "urban area" is the contiguous urban area over a certain density while the metro area includes
-- all urban areas above a certain density; when the latter is greater, it's because of satellite cities in the
-- metro area separated by suburban/exurban or rural land.
-- At first I chose all prefecture/province-level cities with a total prefecture/province-level population of at
-- least 6,000,000 per the 2020 census with data taken from https://www.citypopulation.de/en/china/admin/ (a total
-- of 67, including the four direct-administered municipalities), and also chose all prefecture/province-level
-- cities whose "urban population" was at least 2,000,000 per the 2020 census with data taken from Wikipedia
-- [[w:List of cities in China by population#Cities and towns by population]] (a total of 61 cities; if we cut off
-- at 1.5 million we'd have 84 cities, and if we cut off at 1 million we'd have 105 cities). Merging them produces
-- 87 cities. Note that this leaves off a few well-known cities (Guilin, Qiqihar, Kashgar, Lhasa, ...) but includes
-- a lot of obscure cities.
--
-- At a later date I added all cities from citypopulation.de whose "urban" population per the 2020 China census was
-- >= 1 million, and then finally added all urban agglomerations from citypopulation.de whose 2025-01-01 estimate
-- was >= 1 million. These are sorted below by the urban agglomeration value (which is generally of the "adm-urb" =
-- "administrative area (urban population)" type) and sometimes groups nearby cities into a single agglomeration
-- (most notably in the case of the Pearl River Delta, grouped under Guangzhou with an agglomeration population of
-- 72,700,000 but including a large number of nearby large cities in the agglomeration (although for some reason not
-- Hong Kong, maybe due to the administrative issues involved). In addition, citypopulation.de includes divisions
-- under a prefecture-level city if they are city-like and have an agglomeration population of at least 1 million;
-- this includes several county-level cities, one county and one district (Wanzhou, a "district" of Chongqing
-- despite being 142 miles away). None of the county-level cities or counties have districts under them, only
-- subdistricts, towns and townships.
["Guangzhou"] = {container = "Guangdong"}, -- 18.7 prefectural, 18.8 urban; sub-provincial city; 16.097 urban (72.700 adm-urb including Dongguan, Foshan, Huizhou, Jiangmen, Shenzhen, Zhongshan) per citypopulation.de
["Dongguan"] = {container = "Guangdong"}, -- 10.5 prefectural, 10.5 urban; 9.645 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Foshan"] = {container = "Guangdong"}, -- 9.5 prefectural, 9.5 urban; 9.043 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Huizhou"] = {container = "Guangdong"}, -- 6.0 prefectural, 2.5 urban; 2.900 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Jiangmen"] = {container = "Guangdong"}, -- 4.798 prefectural, 2.7 urban; 1.795 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Shenzhen"] = {container = "Guangdong"}, -- 17.5 prefectural, 14.7 urban; sub-provincial city; 17.445 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Zhongshan"] = {container = "Guangdong"}, -- 4.418 prefectural, 4.4 urban; 3.842 per citypopulation.de; included by citypopulation.de in Guangzhou agglomeration
["Shanghai"] = {placetype = {"direct-administered municipality", "municipality", "bandar"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {
placetype = "county-level city",
container = "Jiangsu",
divs = {"subdaerah"}
}, -- 1.231 urban per citypopulation.de; included by citypopulation.de in Shanghai agglomeration
-- NOTE: Not to be confused with Cangzhou in Hebei
["Changzhou"] = {container = "Jiangsu"}, -- 5.278 prefectural, 3.6 urban; 3.187 urban per citypopulation.de; included by citypopulation.de in Shanghai agglomeration
-- NOTE: There is also a prefecture-level city Suzhou in Anhui with 5.3 million prefectural inhabitants
["Suzhou"] = {container = "Jiangsu"}, -- 12.8 prefectural, 4.3 urban; 5.893 urban per citypopulation.de; included by citypopulation.de in Shanghai agglomeration
["Wuxi"] = {container = "Jiangsu"}, -- 7.5 prefectural, 3.3 urban; 3.957 per citypopulation.de; included by citypopulation.de in Shanghai agglomeration
["Beijing"] = {placetype = {"direct-administered municipality", "municipality", "bandar"}}, -- 21.9 prefectural, 21.9 urban; 18.961 urban (21.500 adm-urb) per citypopulation.de
["Chengdu"] = {container = "Sichuan"}, -- 20.9 prefectural, 16.9 urban; sub-provincial city; 13.568 urban (18.100 adm-urb) per citypopulation.de
["Xiamen"] = {container = "Fujian"}, -- 5.163 prefectural, 5.2 urban; sub-provincial city; 4.617 urban (15.400 adm-urb including Jinjiang, Quanzhou, Putian) per citypopulation.de
["Jinjiang"] = {
placetype = "county-level city",
container = "Fujian",
divs = {"subdaerah", "townships"}
}, -- 1.416 urban per citypopulation.de; included by citypopulation.de in Xiamen agglomeration
["Quanzhou"] = {container = "Fujian"}, -- 8.8 prefectural, 1.7 urban (6.7 metro); 1.469 urban per citypopulation.de; included by citypopulation.de in Xiamen agglomeration
["Putian"] = {container = "Fujian"}, -- 3.210 prefectural, 2.0 urban; 1.539 urban per citypopulation.de; included by citypopulation.de in Xiamen agglomeration
["Hangzhou"] = {container = "Zhejiang"}, -- 11.9 prefectural, 10.7 urban; sub-provincial city; 9.236 urban (14.600 adm-urb including Shaoxing) per citypopulation.de
["Shaoxing"] = {container = "Zhejiang"}, -- 5.270 prefectural, 2.5 urban; 2.333 urban per citypopulation.de; included by citypopulation.de in Hangzhou agglomeration
["Xi'an"] = {container = "Shaanxi"}, -- 12.1 prefectural, 11.9 urban; sub-provincial city; 9.393 urban (13.400 adm-urb including Xianyang) per citypopulation.de
["Xianyang"] = {container = "Shaanxi"}, -- 1.193 urban per citypopulation.de; included by citypopulation.de in Xi'an agglomeration
["Chongqing"] = {placetype = {"direct-administered municipality", "municipality", "bandar"}}, -- 32.1 prefectural, 16.9 urban; 9.581 urban (12.900 adm-urb) per citypopulation.de
["Wuhan"] = {container = "Hubei"}, -- 12.4 prefectural, 12.3 urban; sub-provincial city; 10.495 urban (12.600 adm-urb) per citypopulation.de
["Tianjin"] = {placetype = {"direct-administered municipality", "municipality", "bandar"}}, -- 13.9 prefectural, 13.9 urban; 11.052 urban (11.700 adm-urb) per citypopulation.de
["Changsha"] = {container = "Hunan"}, -- 10.0 prefectural, 6.0 urban; 5.630 urban (11.500 adm-urb including Xiangtan, Zhuzhou) per citypopulation.de
-- Changsha County -- 1.024 urban per citypopulation.de
["Zhuzhou"] = {container = "Hunan"}, -- 1.510 urban per citypopulation.de; included by citypopulation.de in Changsha agglomeration
["Zhengzhou"] = {container = "Henan"}, -- 12.6 prefectural, 6.7 urban; 6.461 urban (10.300 adm-urb) per citypopulation.de
["Nanjing"] = {container = "Jiangsu"}, -- 9.3 prefectural, 9.3 urban; sub-provincial city; 7.520 urban (9.500 adm-urb including Ma'anshan) per citypopulation.de
["Shenyang"] = {container = "Liaoning"}, -- 9.1 prefectural, 7.9 urban; sub-provincial city; 7.026 urban (8.800 adm-urb including Fushun) per citypopulation.de
["Fushun"] = {container = "Liaoning"}, -- 1.229 urban per citypopulation.de; included by citypopulation.de in Shenyang agglomeration
["Hefei"] = {container = "Anhui"}, -- 9.4 prefectural, 4.2 urban; 5.056 urban (8.200 adm-urb) per citypopulation.de
["Shantou"] = {container = "Guangdong"}, -- 5.502 prefectural, 4.3 urban; 3.839 urban (8.050 adm-urb including Chaozhou, Jieyang, Puning) per citypopulation.de
["Chaozhou"] = {container = "Guangdong"}, -- 1.254 urban per citypopulation.de; included by citypopulation.de in Shantou agglomeration
["Jieyang"] = {container = "Guangdong"}, -- 1.243 urban per citypopulation.de; included by citypopulation.de in Shantou agglomeration
["Qingdao"] = {container = "Shandong"}, -- 10.1 prefectural, 7.1 urban; sub-provincial city; 6.165 urban (7.700 adm-urb) per citypopulation.de
["Ningbo"] = {container = "Zhejiang"}, -- 9.4 prefectural, 5.1 urban; sub-provincial city; 3.731 urban (7.600 adm-urb including Cixi, Yuyao) per citypopulation.de
["Cixi"] = {container = "Zhejiang"}, -- 1.458 urban per citypopulation.de; included by citypopulation.de in Ningbo agglomeration
["Yuyao"] = {container = "Zhejiang"}, -- 1.014 urban per citypopulation.de; included by citypopulation.de in Ningbo agglomeration
-- Hong Kong 7.500 agglomeration per citypopulation.de 2025-01-01 estimate including Kowloon, Victoria
["Wenzhou"] = {container = "Zhejiang"}, -- 9.6 prefectural, 3.6 urban; 2.582 urban (7.000 adm-urb including Rui'an, Cangnan, Pingyang) per citypopulation.de
-- Rui'an is a "county-level city" of the "prefecture-level city" of Wenzhou but in fact is 19 miles away from Wenzhou city proper (urban core to urban core).
["Rui'an"] = {placetype = "county-level city", container = {key = "Wenzhou", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}}, -- 1.013 urban per citypopulation.de; included by citypopulation.de in Wenzhou agglomeration
["Kunming"] = {container = "Yunnan"}, -- 8.5 prefectural, 6.0 urban; 5.273 urban (6.800 adm-urb) per citypopulation.de
-- includes Láiwú city
["Jinan"] = {container = "Shandong", wp = "%l, %c"}, -- 9.2 prefectural, 8.4 urban; sub-provincial city; 5.648 urban (6.750 adm-urb) per citypopulation.de
-- includes Xīnjí city
["Shijiazhuang"] = {container = "Hebei"}, -- 11.2 prefectural, 4.1 urban; 5.090 urban (6.450 adm-urb) per citypopulation.de
["Taiyuan"] = {container = "Shanxi"}, -- 5.304 prefectural, 4.5 urban; 4.304 urban (6.150 adm-urb) per citypopulation.de
["Harbin"] = {container = "Heilongjiang"}, -- 10.0 prefectural, 7.0 urban; sub-provincial city; 5.243 urban (5.550 adm-urb) per citypopulation.de
["Nanning"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}}, -- 8.7 prefectural, 3.8 urban; 4.583 urban (5.550 adm-urb) per citypopulation.de
["Dalian"] = {container = "Liaoning"}, -- 7.5 prefectural, 5.7 urban; sub-provincial city; 4.914 urban (5.400 adm-urb) per citypopulation.de
["Guiyang"] = {container = "Guizhou"}, -- 5.987 prefectural, 3.5 urban; 4.021 urban (5.300 adm-urb) per citypopulation.de
["Changchun"] = {container = "Jilin"}, -- 9.1 prefectural, 5.7 urban; sub-provincial city; 4.557 urban (5.200 adm-urb) per citypopulation.de
["Nanchang"] = {container = "Jiangxi"}, -- 6.3 prefectural, 3.6 (3.9?) urban, 5.3 metro; 3.519 urban (5.150 adm-urb) per citypopulation.de
["Ürümqi"] = {container = {key = "Xinjiang, China", placetype = "autonomous region"}}, -- 4.054 prefectural, 4.3 urban; 3.843 urban (5.000 adm-urb) per citypopulation.de
["Urumqi"] = {alias_of = "Ürümqi", display = true},
["Fuzhou"] = {container = "Fujian"}, -- 8.3 prefectural, 4.1 urban; 3.723 urban (4.775 adm-urb) per citypopulation.de
["Linyi"] = {container = "Shandong"}, -- 11.0 prefectural, 2.3 urban; 2.744 urban (4.650 adm-urb) per citypopulation.de
["Zibo"] = {container = "Shandong"}, -- 4.704 prefectural, 2.6 urban; 2.750 urban (3.975 adm-urb) per citypopulation.de
["Luoyang"] = {container = "Henan"}, -- 7.1 prefectural, 2.4 urban; 2.231 urban (3.750 adm-urb) per citypopulation.de
["Lanzhou"] = {container = "Gansu"}, -- 4.359 prefectural, 3.1 urban; 3.013 urban (3.575 adm-urb) per citypopulation.de
["Nantong"] = {container = "Jiangsu"}, -- 7.7 prefectural, 2.3 urban; 2.988 urban (3.475 adm-urb) citypopulation.de
["Weifang"] = {container = "Shandong"}, -- 9.4 prefectural, 2.7 urban; 1.998 urban (3.325 adm-urb) per citypopulation.de
["Jiangyin"] = {placetype = "county-level city", container = {key = "Wuxi", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}}, -- 1.331 urban (3.200 adm-urb including Zhangjiagang) per citypopulation.de
["Zhangjiagang"] = {container = "Jiangsu"}, -- 1.056 urban per citypopulation.de; included in Jiangyin figures
["Xuzhou"] = {container = "Jiangsu"}, -- 9.1 prefectural, 2.6 urban; 2.846 urban (3.150 adm-urb) per citypopulation.de
["Handan"] = {container = "Hebei"}, -- 9.4 prefectural, 2.8 urban; 2.095 urban (2.925 adm-urb) per citypopulation.de
["Hohhot"] = {container = {key = "Inner Mongolia, China", placetype = "autonomous region"}}, -- 3.446 prefectural, 2.7 urban; 2.373 urban (2.850 adm-urb) per citypopulation.de
["Haikou"] = {container = "Hainan"}, -- 2.873 prefectural, 2.3 urban; 2.349 urban (2.800 adm-urb) per citypopulation.de
["Tangshan"] = {container = "Hebei"}, -- 7.7 prefectural, 3.4 urban; 2.550 urban (2.750 adm-urb) per citypopulation.de
["Xinxiang"] = {container = "Henan"}, -- 6.3 prefectural, 1.2 urban, 2.7 metro; 1.271 urban (2.700 adm-urb) per citypopulation.de
["Yiwu"] = {
placetype = "county-level city",
container = "Zhejiang",
divs = {"subdaerah", "townships"}
}, -- 1.481 urban (2.700 adm-urb) per citypopulation.de
["Zhuhai"] = {container = "Guangdong"}, -- 2.439 prefectural, 2.4 urban; 2.207 urban (2.675 adm-urb) per citypopulation.de
["Taizhou, Zhejiang"] = {container = "Zhejiang"}, -- 6.6 prefectural, 1.6 urban; 1.486 urban (2.625 adm-urb) per citypopulation.de
["Taizhou"] = {alias_of = "Taizhou, Zhejiang"},
["Yantai"] = {container = "Shandong"}, -- 7.1 prefectural, 2.5 urban; 2.312 urban (2.550 adm-urb) per citypopulation.de
["Yinchuan"] = {container = {key = "Ningxia, China", placetype = "autonomous region"}}, -- 1.663 urban (2.525 adm-urb) per citypopulation.de
["Liuzhou"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}}, -- 4.157 prefectural, 2.2 urban; 2.205 urban (2.500 adm-urb) per citypopulation.de
["Anshan"] = {container = "Liaoning"}, -- 1.480 urban (2.350 adm-urb including Liáoyáng) per citypopulation.de
["Yangzhou"] = {container = "Jiangsu"}, -- 2.067 urban (2.300 adm-urb) per citypopulation.de
["Jiaxing"] = {container = "Zhejiang"}, -- 1.188 urban (2.275 adm-urb) per citypopulation.de
["Xining"] = {container = "Qinghai"}, -- 1.677 urban (2.250 adm-urb) per citypopulation.de
-- includes Dìngzhōu city and Xióngān Xīnqū
["Baoding"] = {container = "Hebei"}, -- 11.5 prefectural, 2.0 urban; 1.940 urban (2.225 adm-urb) per citypopulation.de
["Baotou"] = {container = {key = "Inner Mongolia, China", placetype = "autonomous region"}}, -- 2.709 prefectural, 2.2 urban; 2.104 urban (2.200 adm-urb) per citypopulation.de
["Ganzhou"] = {container = "Jiangxi"}, -- 9.0 prefectural, 1.6 urban; 1.778 urban (2.150 adm-urb) per citypopulation.de
["Pingdingshan"] = {container = "Henan"}, -- 1.046 urban (2.100 adm-urb) per citypopulation.de
["Zunyi"] = {container = "Guizhou"}, -- 6.6 prefectural, 2.4 urban/metro; 1.675 urban (2.025 adm-urb) per citypopulation.de
["Bengbu"] = {container = "Anhui"}, -- 1.078 urban (2.000 adm-urb) per citypopulation.de
["Datong"] = {container = "Shanxi"}, -- 3.105 prefectural, 2.0 urban; 1.810 urban (2.000 adm-urb) per citypopulation.de
["Anyang"] = {container = "Henan"}, -- 1.188 urban (1.960 adm-urb) per citypopulation.de
["Huai'an"] = {container = "Jiangsu"}, -- 4.556 prefectural, 2.6 urban; 1.805 urban (1.940 adm-urb) per citypopulation.de
["Zaozhuang"] = {container = "Shandong"}, -- 1.350 urban (1.900 adm-urb) per citypopulation.de
["Zhanjiang"] = {container = "Guangdong"}, -- 7.0 prefectural, 1.9 urban; 1.401 urban (1.890 adm-urb) per citypopulation.de
["Huainan"] = {container = "Anhui"}, -- 1.256 urban (1.880 adm-urb) per citypopulation.de
["Jining"] = {container = "Shandong"}, -- 8.4 prefectural, 1.5 urban; 1.700 urban (1.880 adm-urb) per citypopulation.de
["Daqing"] = {container = "Heilongjiang"}, -- 1.604 urban (1.860 adm-urb) per citypopulation.de
["Wuhu"] = {container = "Anhui"}, -- 1.598 urban (1.850 adm-urb) per citypopulation.de
["Guilin"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}}, -- 1.361 urban (1.830 adm-urb) per citypopulation.de
["Mianyang"] = {container = "Sichuan"}, -- 1.549 urban (1.800 adm-urb) per citypopulation.de
["Xiangyang"] = {container = "Hubei"}, -- 1.686 urban (1.800 adm-urb) per citypopulation.de
["Huzhou"] = {container = "Zhejiang"}, -- 1.084 urban (1.750 adm-urb) per citypopulation.de
["Puyang"] = {container = "Henan"}, -- 0.824 urban (1.750 adm-urb) per citypopulation.de
["Shangqiu"] = {container = "Henan"}, -- 7.8 prefectural, 1.9 urban (2.8 metro); 1.031 urban (1.750 adm-urb) per citypopulation.de
["Qinhuangdao"] = {container = "Hebei"}, -- 1.520 urban (1.740 adm-urb) per citypopulation.de
["Xingtai"] = {container = "Hebei"}, -- 7.1 prefectural, 971,000 urban; 1.5 urban (1.700 adm-urb) per citypopulation.de
["Nanyang"] = {container = "Henan", wp = "%l, %c"}, -- 9.7 prefectural, 2.1 urban/metro; 1.481 urban (1.680 adm-urb) per citypopulation.de
["Jiaozuo"] = {container = "Henan"}, -- 0.875 urban (1.640 adm-urb) per citypopulation.de
["Jilin City"] = {container = "Jilin"}, -- 1.509 urban (1.610 adm-urb) per citypopulation.de
["Jilin"] = {alias_of = "Jilin City"},
["Jinhua"] = {container = "Zhejiang"}, -- 7.1 prefectural, 1.5 urban; 1.041 urban (1.590 adm-urb) per citypopulation.de
["Shangrao"] = {container = "Jiangxi"}, -- 6.5 prefectural, 2.1 urban, 1.3 metro [sic]; 1.342 urban (1.580 adm-urb) per citypopulation.de
["Heze"] = {container = "Shandong"}, -- 8.8 prefectural, 1.3 urban; 1.294 urban (1.570 adm-urb) per citypopulation.de
["Yulin"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}, wp = "%l, %c"}, -- 0.878 urban (1.570 adm-urb) per citypopulation.de
["Tai'an"] = {container = "Shandong"}, -- 1.417 urban (1.560 adm-urb) per citypopulation.de
["Weihai"] = {container = "Shandong"}, -- 1.340 urban (1.510 adm-urb) per citypopulation.de
-- Taizhou, Jiangsu would be here (1.490 adm-urb) but moved to china_prefecture_level_cities_2 to avoid clash
["Yancheng"] = {container = "Jiangsu"}, -- 6.7 prefectural, 1.6 urban; 1.353 urban (1.460 adm-urb) per citypopulation.de
["Zhangjiakou"] = {container = "Hebei"}, -- 1.339 urban (1.450 adm-urb) per citypopulation.de
["Maoming"] = {container = "Guangdong"}, -- 6.2 prefectural, 2.5 urban; 1.308 urban (1.440 adm-urb) per citypopulation.de
["Nanchong"] = {container = "Sichuan"}, -- 1.254 urban (1.440 adm-urb) per citypopulation.de
["Fuyang"] = {container = "Anhui", wp = "%l, %c"}, -- 8.2 prefectural, 2.1 urban; 1.191 urban (1.410 adm-urb) per citypopulation.de
["Xuchang"] = {container = "Henan"}, -- 0.850 urban (1.390 adm-urb) per citypopulation.de
["Yichang"] = {container = "Hubei"}, -- 1.284 urban (1.390 adm-urb) per citypopulation.de
["Dazhou"] = {container = "Sichuan"}, -- 1.136 urban (1.380 adm-urb) per citypopulation.de
["Kaifeng"] = {container = "Henan"}, -- 1.194 urban (1.340 adm-urb) per citypopulation.de
["Luzhou"] = {container = "Sichuan"}, -- 1.128 urban (1.340 adm-urb) per citypopulation.de
["Qingyuan"] = {container = "Guangdong"}, -- 1.198 urban (1.340 adm-urb) per citypopulation.de
["Huaibei"] = {container = "Anhui"}, -- 0.831 urban (1.330 adm-urb) per citypopulation.de
["Yibin"] = {container = "Sichuan"}, -- 1.101 urban (1.310 adm-urb) per citypopulation.de
["Lu'an"] = {container = "Anhui"}, -- 1.070 urban (1.300 adm-urb) per citypopulation.de
["Dezhou"] = {container = "Shandong"}, -- 0.843 urban (1.290 adm-urb) per citypopulation.de
["Rizhao"] = {container = "Shandong"}, -- 1.147 urban (1.270 adm-urb) per citypopulation.de
["Changzhi"] = {container = "Shanxi"}, -- 1.047 urban (1.250 adm-urb) per citypopulation.de
["Hengyang"] = {container = "Hunan"}, -- 6.6 prefectural, 1.5 urban; 1.185 urban (1.250 adm-urb) per citypopulation.de
["Jinzhou"] = {container = "Liaoning"}, -- 1.021 urban (1.240 adm-urb) per citypopulation.de
["Liaocheng"] = {container = "Shandong"}, -- 1.020 urban (1.240 adm-urb) per citypopulation.de
["Changde"] = {container = "Hunan"}, -- 1.101 urban (1.230 adm-urb) per citypopulation.de
["Suqian"] = {container = "Jiangsu"}, -- 1.082 urban (1.230 adm-urb) per citypopulation.de
["Xinyang"] = {container = "Henan"}, -- 6.2 prefectural, 1.4 urban/metro; 1.015 urban (1.230 adm-urb) per citypopulation.de
["Baoji"] = {container = "Shaanxi"}, -- 1.108 urban (1.220 adm-urb) per citypopulation.de
["Yueyang"] = {container = "Hunan"}, -- 1.125 urban (1.220 adm-urb) per citypopulation.de
["Zhenjiang"] = {container = "Jiangsu"}, -- 1.124 urban (1.210 adm-urb) per citypopulation.de
-- Wanzhou is a "district" of the "direct-administered municipality" of Chongqing but in fact is 142 miles away from Chongqing city proper.
["Wanzhou"] = {placetype = "daerah", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdaerah", "townships"}, wp = "%l, %c"}, -- 1.078 urban (1.190 adm-urb) per citypopulation.de
["Ulanhad"] = {container = {key = "Inner Mongolia, China", placetype = "autonomous region"}}, -- 1.093 urban (1.180 adm-urb) per citypopulation.de
["Chifeng"] = {alias_of = "Ulanhad"},
["Ulankhad"] = {alias_of = "Ulanhad", display = true},
["Ezhou"] = {container = "Hubei"}, -- < 0.750 urban (1.180 adm-urb) per citypopulation.de
["Zhaoqing"] = {container = "Guangdong"}, -- 1.036 urban (1.160 adm-urb) per citypopulation.de
["Lianyungang"] = {container = "Jiangsu"}, -- 4.599 prefectural, 2.0 urban; 1.071 urban (1.150 adm-urb) per citypopulation.de
["Qujing"] = {container = "Yunnan"}, -- 0.976 urban (1.150 adm-urb) per citypopulation.de
-- Shuyang is a "kaunti" of the "prefecture-level city" of Suqian but in fact is 38 miles away from Suqian city proper (urban core to urban core).
-- The county itself is 37 miles by 34 miles.
["Shuyang"] = {placetype = "kaunti", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}, wp = "%l County"}, -- 0.986 urban (1.120 adm-urb) per citypopulation.de
-- Yongkang is a "county-level city" of the "prefecture-level city" of Jinhua but in fact is 32 miles away from Jinhua city proper (urban core to urban core).
["Yongkang"] = {placetype = "county-level city", container = {key = "Jinhua", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}, wp = "%l, Zhejiang"}, -- < 0.750 urban (1.110 adm-urb) per citypopulation.de
["Zhoukou"] = {container = "Henan"}, -- 9.0 prefectural, 721,000 urban (1.6 metro); < 0.750 urban (1.100 adm-urb) per citypopulation.de
["Beihai"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}}, -- < 1 urban (1.090 adm-urb) per citypopulation.de
["Jiujiang"] = {container = "Jiangxi"}, -- < 0.750 urban (1.080 adm-urb) per citypopulation.de
["Shaoyang"] = {container = "Hunan"}, -- 6.6 prefectural, 802,000 urban, 1.4 metro; < 1 urban (1.080 adm-urb) per citypopulation.de
["Chuzhou"] = {container = "Anhui"}, -- < 0.750 urban (1.070 adm-urb) per citypopulation.de
["Hengshui"] = {container = "Hebei"}, -- 0.885 urban (1.070 adm-urb) per citypopulation.de
["Shiyan"] = {container = "Hubei"}, -- 0.955 urban (1.070 adm-urb) per citypopulation.de
["Huludao"] = {container = "Liaoning"}, -- 0.764 urban (1.060 adm-urb) per citypopulation.de
["Dongying"] = {container = "Shandong"}, -- 0.961 urban (1.050 adm-urb) per citypopulation.de
["Guigang"] = {container = {key = "Guangxi, China", placetype = "autonomous region"}}, -- 0.921 urban (1.050 adm-urb) per citypopulation.de
-- Liuyang is a "county-level city" of the "prefecture-level city" of Changsha but in fact is 47 miles away from Changsha city proper (urban core to urban core).
["Liuyang"] = {placetype = "county-level city", container = {key = "Changsha", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}}, -- 0.886 urban (1.040 adm-urb) per citypopulation.de
-- NOTE: Not to be confused with Changzhou in Jiangsu
["Cangzhou"] = {container = "Hebei"}, -- 7.3 prefectural, 621,000 urban; 0.759 urban (1.030 adm-urb) per citypopulation.de
["Liupanshui"] = {container = "Guizhou"}, -- < 0.750 urban (1.030 adm-urb) per citypopulation.de
["Panjin"] = {container = "Liaoning"}, -- 0.980 urban (1.030 adm-urb) per citypopulation.de
["Qiqihar"] = {container = "Heilongjiang"}, -- 1.030 urban (1.030 adm-urb) per citypopulation.de
["Linfen"] = {container = "Shanxi"}, -- < 0.750 urban (1.010 adm-urb) per citypopulation.de
-- Tengzhou is a "county-level city" of the "prefecture-level city" of Zaozhuang but in fact is 30 miles away from Zaozhuang city proper (urban core to urban core).
["Tengzhou"] = {placetype = "county-level city", container = {key = "Zaozhuang", placetype = "prefecture-level city"}, divs = {"subdaerah", "townships"}}, -- 0.937 urban (1.010 adm-urb) per citypopulation.de
-- 3 extra that got added in earlier incarnations and aren't found in the "major agglomerations of the world" page https://citypopulation.de/en/world/agglomerations/ reference date 2025-01-01
["Kunshan"] = {
placetype = "county-level city",
container = "Jiangsu",
divs = {"subdaerah", "townships"}
}, -- 1.652 urban (2020 China census) per citypopulation.de
["Zhumadian"] = {container = "Henan"}, -- 7.0 prefectural, 722,000 urban per Wikipedia; 0.754 urban per citypopulation.de
["Bijie"] = {container = "Guizhou"}, -- 6.9 prefectural, ? urban, ? metro (not listed in Wikipedia); < 0.750 urban per citypopulation.de
}
export.china_prefecture_level_cities_group = {
-- don't do any transformations between key and placename; in particular, don't chop off anything from
-- "Taizhou, Zhejiang" or "Suzhou, Anhui".
key_to_placename = false,
placename_to_key = false, -- don't add ", China" to make the key
default_container = "China",
canonicalize_key_container = make_canonicalize_key_container(", China", "province"),
-- Prefecture-level cities aren't really cities but allow them to be identified that way, as many people
-- don't understand how Chinese administrative divisions work.
default_placetype = {"prefecture-level city", "bandar"},
default_divs = {
-- "towns" (but not "townships") are automatically added as they are specified as generic_before_non_cities,
-- and prefecture-level cities (as well as county-level cities) are considered non-cities.
"daerah", "subdaerah", "townships",
{type = "kaunti", cat_as = "counties and county-level cities"},
{type = "county-level cities", cat_as = "counties and county-level cities"},
},
data = export.china_prefecture_level_cities,
}
-- Needed to avoid problems with two cities called Taizhou and Suzhou.
export.china_prefecture_level_cities_2 = {
-- NOTE: There is also a larger and better-known prefecture-level city Taizhou in Zhejiang.
["Taizhou, Jiangsu"] = {container = "Jiangsu"}, -- 1.3 urban (1.490 adm-urb) per citypopulation.de 2020 census
["Taizhou"] = {alias_of = "Taizhou, Jiangsu"},
-- NOTE: There is also a larger and better-known prefecture-level city Suzhou in Jiangsu.
["Suzhou, Anhui"] = {container = "Anhui"}, -- 5.3 prefectural, 1.766 metro and "urban"; < 1 urban (1.010 adm-urb) per citypopulation.de 2020 census
-- hopefully this will work because we also have Suzhou as a key by itself for the larger, more-well-known Suzhou in Jiangsu
["Suzhou"] = {alias_of = "Suzhou, Anhui"},
}
export.china_prefecture_level_cities_group_2 = {
-- don't do any transformations between key and placename; in particular, don't chop off anything from
-- "Taizhou, Jiangsu".
placename_to_key = false, -- don't add ", China" to make the key
default_container = "China",
canonicalize_key_container = make_canonicalize_key_container(", China", "province"),
-- Prefecture-level cities aren't really cities but allow them to be identified that way, as many people
-- don't understand how Chinese administrative divisions work.
default_placetype = {"prefecture-level city", "bandar"},
default_divs = {
-- "towns" (but not "townships") are automatically added as they are specified as generic_before_non_cities,
-- and prefecture-level cities (as well as county-level cities) are considered non-cities.
"daerah", "subdaerah", "townships",
{type = "kaunti", cat_as = "counties and county-level cities"},
{type = "county-level cities", cat_as = "counties and county-level cities"},
},
data = export.china_prefecture_level_cities_2,
}
export.finland_regions = {
["Lapland, Finland"] = {wp = "%l (%c)"},
["North Ostrobothnia, Finland"] = {},
["Northern Ostrobothnia, Finland"] = {alias_of = "North Ostrobothnia, Finland", display = true},
["Kainuu, Finland"] = {},
["North Karelia, Finland"] = {},
["Northern Savonia, Finland"] = {},
["North Savo, Finland"] = {alias_of = "Northern Savonia, Finland", display = true},
["Southern Savonia, Finland"] = {},
["South Savo, Finland"] = {alias_of = "Southern Savonia, Finland", display = true},
["South Karelia, Finland"] = {},
["Central Finland, Finland"] = {},
["South Ostrobothnia, Finland"] = {},
["Southern Ostrobothnia, Finland"] = {alias_of = "South Ostrobothnia, Finland", display = true},
["Ostrobothnia, Finland"] = {wp = "%l (region)"},
["Central Ostrobothnia, Finland"] = {},
["Pirkanmaa, Finland"] = {},
["Satakunta, Finland"] = {},
["Päijänne Tavastia, Finland"] = {},
["Päijät-Häme, Finland"] = {alias_of = "Päijänne Tavastia, Finland", display = true},
["Tavastia Proper, Finland"] = {},
["Kanta-Häme, Finland"] = {alias_of = "Tavastia Proper, Finland", display = true},
["Kymenlaakso, Finland"] = {},
["Uusimaa, Finland"] = {},
["Southwest Finland, Finland"] = {},
["Åland Islands, Finland"] = {the = true, wp = "Åland"},
["Åland, Finland"] = {alias_of = "Åland Islands, Finland"}, -- differs in "the"
}
-- regions of Finland
export.finland_group = {
default_container = "Finland",
default_placetype = "wilayah",
default_divs = "municipalities",
data = export.finland_regions,
}
export.france_administrative_regions = {
["Auvergne-Rhône-Alpes, France"] = {},
["Bourgogne-Franche-Comté, France"] = {},
["Brittany, France"] = {wp = "%l (administrative region)"},
["Centre-Val de Loire, France"] = {},
["Corsica, France"] = {},
-- overseas departments are handled in `export.country_like_entities`
-- ["French Guiana"] = {},
["Grand Est, France"] = {},
-- ["Guadeloupe"] = {},
["Hauts-de-France, France"] = {},
["Île-de-France, France"] = {},
-- ["Martinique"] = {},
-- ["Mayotte"] = {},
["Normandy, France"] = {wp = "%l (administrative region)"},
["Nouvelle-Aquitaine, France"] = {},
["Occitania, France"] = {wp = "%l (administrative region)"},
["Occitanie, France"] = {alias_of = "Occitania, France", display = true},
["Pays de la Loire, France"] = {},
["Provence-Alpes-Côte d'Azur, France"] = {},
-- ["Réunion"] = {},
}
-- administrative regions of France
export.france_group = {
default_container = "France",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "wilayah",
default_divs = {
"communes",
{type = "municipalities", cat_as = "communes"},
"departments",
{type = "prefectures", cat_as = {"prefectures", "departmental capitals"}},
{type = "French prefectures", cat_as = {"prefectures", "departmental capitals"}},
},
data = export.france_administrative_regions,
}
export.france_departments = {
["Ain, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 01
["Aisne, France"] = {container = "Hauts-de-France"}, -- 02
["Allier, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 03
["Alpes-de-Haute-Provence, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 04
["Hautes-Alpes, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 05
["Alpes-Maritimes, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 06
["Ardèche, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 07
["Ardennes, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 08
["Ariège, France"] = {container = "Occitania", wp = "%l (department)"}, -- 09
["Aube, France"] = {container = "Grand Est"}, -- 10
["Aude, France"] = {container = "Occitania"}, -- 11
["Aveyron, France"] = {container = "Occitania"}, -- 12
["Bouches-du-Rhône, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 13
["Calvados, France"] = {container = "Normandy", wp = "%l (department)"}, -- 14
["Cantal, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 15
["Charente, France"] = {container = "Nouvelle-Aquitaine"}, -- 16
["Charente-Maritime, France"] = {container = "Nouvelle-Aquitaine"}, -- 17
["Cher, France"] = {container = "Centre-Val de Loire", wp = "%l (department)"}, -- 18
["Corrèze, France"] = {container = "Nouvelle-Aquitaine"}, -- 19
["Corse-du-Sud, France"] = {container = "Corsica"}, -- 2A
["Haute-Corse, France"] = {container = "Corsica"}, -- 2B
["Côte-d'Or, France"] = {container = "Bourgogne-Franche-Comté"}, -- 21
["Côte d'Or, France"] = {alias_of = "Côte-d'Or, France", display = true},
["Côtes-d'Armor, France"] = {container = "Brittany"}, -- 22
["Côtes d'Armor, France"] = {alias_of = "Côtes-d'Armor, France", display = true},
["Creuse, France"] = {container = "Nouvelle-Aquitaine"}, -- 23
["Dordogne, France"] = {container = "Nouvelle-Aquitaine"}, -- 24
["Doubs, France"] = {container = "Bourgogne-Franche-Comté"}, -- 25
["Drôme, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 26
["Eure, France"] = {container = "Normandy"}, -- 27
["Eure-et-Loir, France"] = {container = "Centre-Val de Loire"}, -- 28
["Finistère, France"] = {container = "Brittany"}, -- 29
["Gard, France"] = {container = "Occitania"}, -- 30
["Haute-Garonne, France"] = {container = "Occitania"}, -- 31
["Gers, France"] = {container = "Occitania"}, -- 32
["Gironde, France"] = {container = "Nouvelle-Aquitaine"}, -- 33
["Hérault, France"] = {container = "Occitania"}, -- 34
["Ille-et-Vilaine, France"] = {container = "Brittany"}, -- 35
["Indre, France"] = {container = "Centre-Val de Loire"}, -- 36
["Indre-et-Loire, France"] = {container = "Centre-Val de Loire"}, -- 37
["Isère, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 38
["Jura, France"] = {container = "Bourgogne-Franche-Comté", wp = "%l (department)"}, -- 39
["Landes, France"] = {container = "Nouvelle-Aquitaine", wp = "%l (department)"}, -- 40
["Loir-et-Cher, France"] = {container = "Centre-Val de Loire"}, -- 41
["Loire, France"] = {container = "Auvergne-Rhône-Alpes", wp = "%l (department)"}, -- 42
["Haute-Loire, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 43
["Loire-Atlantique, France"] = {container = "Pays de la Loire"}, -- 44
["Loiret, France"] = {container = "Centre-Val de Loire"}, -- 45
["Lot, France"] = {container = "Occitania", wp = "%l (department)"}, -- 46
["Lot-et-Garonne, France"] = {container = "Nouvelle-Aquitaine"}, -- 47
["Lozère, France"] = {container = "Occitania"}, -- 48
["Maine-et-Loire, France"] = {container = "Pays de la Loire"}, -- 49
["Manche, France"] = {container = "Normandy"}, -- 50
["Marne, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 51
["Haute-Marne, France"] = {container = "Grand Est"}, -- 52
["Mayenne, France"] = {container = "Pays de la Loire"}, -- 53
["Meurthe-et-Moselle, France"] = {container = "Grand Est"}, -- 54
["Meuse, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 55
["Morbihan, France"] = {container = "Brittany"}, -- 56
["Moselle, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 57
["Nièvre, France"] = {container = "Bourgogne-Franche-Comté"}, -- 58
["Nord, France"] = {container = "Hauts-de-France", wp = "%l (French department)"}, -- 59
["Oise, France"] = {container = "Hauts-de-France"}, -- 60
["Orne, France"] = {container = "Normandy"}, -- 61
["Pas-de-Calais, France"] = {container = "Hauts-de-France"}, -- 62
["Puy-de-Dôme, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 63
["Pyrénées-Atlantiques, France"] = {container = "Nouvelle-Aquitaine"}, -- 64
["Hautes-Pyrénées, France"] = {container = "Occitania"}, -- 65
["Pyrénées-Orientales, France"] = {container = "Occitania"}, -- 66
["Bas-Rhin, France"] = {container = "Grand Est"}, -- 67
["Haut-Rhin, France"] = {container = "Grand Est"}, -- 68
["Rhône, France"] = {container = "Auvergne-Rhône-Alpes", wp = "%l (department)"}, -- 69D
["Metropolis of Lyon, France"] = {container = "Auvergne-Rhône-Alpes", the = true}, -- 69M
["Lyon Metropolis, France"] = {alias_of = "Metropolis of Lyon, France"},
["Lyon, France"] = {alias_of = "Metropolis of Lyon, France"},
["Haute-Saône, France"] = {container = "Bourgogne-Franche-Comté"}, -- 70
["Saône-et-Loire, France"] = {container = "Bourgogne-Franche-Comté"}, -- 71
["Sarthe, France"] = {container = "Pays de la Loire"}, -- 72
["Savoie, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 73
["Haute-Savoie, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 74
["Paris, France"] = {container = "Île-de-France"}, -- 75
["Seine-Maritime, France"] = {container = "Normandy"}, -- 76
["Seine-et-Marne, France"] = {container = "Île-de-France"}, -- 77
["Yvelines, France"] = {container = "Île-de-France"}, -- 78
["Deux-Sèvres, France"] = {container = "Nouvelle-Aquitaine"}, -- 79
["Somme, France"] = {container = "Hauts-de-France", wp = "%l (department)"}, -- 80
["Tarn, France"] = {container = "Occitania", wp = "%l (department)"}, -- 81
["Tarn-et-Garonne, France"] = {container = "Occitania"}, -- 82
["Var, France"] = {container = "Provence-Alpes-Côte d'Azur", wp = "%l (department)"}, -- 83
["Vaucluse, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 84
["Vendée, France"] = {container = "Pays de la Loire"}, -- 85
["Vienne, France"] = {container = "Nouvelle-Aquitaine", wp = "%l (department)"}, -- 86
["Haute-Vienne, France"] = {container = "Nouvelle-Aquitaine"}, -- 87
["Vosges, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 88
["Yonne, France"] = {container = "Bourgogne-Franche-Comté"}, -- 89
["Territoire de Belfort, France"] = {container = "Bourgogne-Franche-Comté"}, -- 90
["Essonne, France"] = {container = "Île-de-France"}, -- 91
["Hauts-de-Seine, France"] = {container = "Île-de-France"}, -- 92
["Seine-Saint-Denis, France"] = {container = "Île-de-France"}, -- 93
["Val-de-Marne, France"] = {container = "Île-de-France"}, -- 94
["Val-d'Oise, France"] = {container = "Île-de-France"}, -- 95
--["Guadeloupe"] = {container = "Guadeloupe"}, -- 971
--["Martinique"] = {container = "Martinique"}, -- 972
--["Guyane"] = {container = "French Guiana", wp = "French Guiana"}, -- 973
--["La Réunion"] = {container = "Réunion", wp = "Réunion"}, -- 974
--["Mayotte"] = {container = "Mayotte"}, -- 976
}
export.france_departments_group = {
placename_to_key = make_placename_to_key(", France"),
canonicalize_key_container = make_canonicalize_key_container(", France", "wilayah"),
default_placetype = "department",
default_divs = {
"communes",
{type = "municipalities", cat_as = "communes"},
},
data = export.france_departments,
}
export.germany_states = {
["Baden-Württemberg, Germany"] = {},
["Bavaria, Germany"] = {},
-- Berlin, Bremen and Hamburg are effectively city-states and don't have districts ([[Kreise]]), so override
-- the default_divs setting. Better not to include them at all since they're included as cities down below.
-- ["Berlin"] = {divs = {}},
["Brandenburg, Germany"] = {},
-- ["Bremen"] = {divs = {}},
-- ["Hamburg"] = {divs = {}},
["Hesse, Germany"] = {},
["Lower Saxony, Germany"] = {},
["Mecklenburg-Vorpommern, Germany"] = {},
["Mecklenburg-Western Pomerania, Germany"] = {alias_of = "Mecklenburg-Vorpommern, Germany", display = true},
["North Rhine-Westphalia, Germany"] = {},
["Rhineland-Palatinate, Germany"] = {},
["Saarland, Germany"] = {},
["Saxony, Germany"] = {},
["Saxony-Anhalt, Germany"] = {},
["Schleswig-Holstein, Germany"] = {},
["Thuringia, Germany"] = {},
}
-- states of Germany
export.germany_group = {
default_container = "Germany",
default_placetype = "negeri",
default_divs = {"daerah", "municipalities"},
data = export.germany_states,
}
export.greece_regions = {
["Attica, Greece"] = {wp = "%l (region)"},
["Central Greece, Greece"] = {wp = "%l (administrative region)"},
["Central Macedonia, Greece"] = {},
["Crete, Greece"] = {},
["Eastern Macedonia and Thrace, Greece"] = {},
["Epirus, Greece"] = {wp = "%l (region)"},
["Ionian Islands, Greece"] = {the = true, wp = "%l (region)"},
["North Aegean, Greece"] = {the = true},
-- I would expect 'the Peloponnese' but Wikipedia mostly has categories like [[w:Category:Geography of Peloponnese (region)]]
-- and [[w:Category:Buildings and structures in Peloponnese (region)]]; only [[w:Category:People from the Peloponnese (region)]]
-- has "the" in it.
["Peloponnese, Greece"] = {wp = "%l (region)"},
["South Aegean, Greece"] = {the = true},
["Thessaly, Greece"] = {},
["Western Greece, Greece"] = {},
["Western Macedonia, Greece"] = {},
["Mount Athos, Greece"] = {placetype = {"autonomous region", "wilayah"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Greece",
default_placetype = "wilayah",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "daerah"}
local india_polity_without_divisions = {"daerah"}
-- States and union territories of India. Only some of them are divided into divisions.
export.india_states_and_union_territories = {
["Andaman and Nicobar Islands, India"] =
{the = true, placetype = "union territory", divs = india_polity_without_divisions},
["Andhra Pradesh, India"] = {divs = india_polity_without_divisions},
["Arunachal Pradesh, India"] = {divs = india_polity_with_divisions},
["Assam, India"] = {divs = india_polity_with_divisions},
["Bihar, India"] = {divs = india_polity_with_divisions},
["Chandigarh, India"] = {placetype = "union territory", divs = india_polity_without_divisions},
["Chhattisgarh, India"] = {divs = india_polity_with_divisions},
["Dadra and Nagar Haveli and Daman and Diu, India"] = {placetype = "union territory", divs = india_polity_without_divisions},
["Delhi, India"] = {placetype = "union territory", divs = india_polity_with_divisions},
["Goa, India"] = {divs = india_polity_without_divisions},
["Gujarat, India"] = {divs = india_polity_without_divisions},
["Haryana, India"] = {divs = india_polity_with_divisions},
["Himachal Pradesh, India"] = {divs = india_polity_with_divisions},
["Jammu and Kashmir, India"] = {placetype = "union territory", divs = india_polity_with_divisions,
wp = "%l (union territory)"},
["Jharkhand, India"] = {divs = india_polity_with_divisions},
["Karnataka, India"] = {divs = india_polity_with_divisions},
["Kerala, India"] = {divs = india_polity_without_divisions},
["Ladakh, India"] = {placetype = "union territory", divs = india_polity_with_divisions},
["Lakshadweep, India"] = {placetype = "union territory", divs = india_polity_without_divisions},
["Madhya Pradesh, India"] = {divs = india_polity_with_divisions},
["Maharashtra, India"] = {divs = india_polity_with_divisions},
["Manipur, India"] = {divs = india_polity_without_divisions},
["Meghalaya, India"] = {divs = india_polity_with_divisions},
["Mizoram, India"] = {divs = india_polity_without_divisions},
["Nagaland, India"] = {divs = india_polity_with_divisions},
["Odisha, India"] = {divs = india_polity_with_divisions},
["Puducherry, India"] = {placetype = "union territory", divs = india_polity_without_divisions,
wp = "%l (union territory)"},
["Pondicherry, India"] = {alias_of = "Puducherry, India", display = true},
["Punjab, India"] = {divs = india_polity_with_divisions, wp = "%l, %c"},
["Rajasthan, India"] = {divs = india_polity_with_divisions},
["Sikkim, India"] = {divs = india_polity_without_divisions},
["Tamil Nadu, India"] = {divs = india_polity_without_divisions},
["Telangana, India"] = {divs = india_polity_without_divisions},
["Tripura, India"] = {divs = india_polity_without_divisions},
["Uttar Pradesh, India"] = {divs = india_polity_with_divisions},
["Uttarakhand, India"] = {divs = india_polity_with_divisions},
["West Bengal, India"] = {divs = india_polity_with_divisions},
}
-- states and union territories of India
export.india_group = {
default_container = "India",
default_placetype = "negeri",
data = export.india_states_and_union_territories,
}
export.indonesia_provinces = {
["Aceh, Indonesia"] = {},
["Bali, Indonesia"] = {},
["Bangka Belitung Islands, Indonesia"] = {the = true},
["Banten, Indonesia"] = {},
["Bengkulu, Indonesia"] = {},
["Central Java, Indonesia"] = {},
["Central Kalimantan, Indonesia"] = {},
["Central Papua, Indonesia"] = {},
["Central Sulawesi, Indonesia"] = {},
["East Java, Indonesia"] = {},
["East Kalimantan, Indonesia"] = {},
["East Nusa Tenggara, Indonesia"] = {},
["Gorontalo, Indonesia"] = {},
["Highland Papua, Indonesia"] = {wp = "%l"},
["Special Capital Region of Jakarta, Indonesia"] = {the = true, wp = "Jakarta"},
["Jakarta, Indonesia"] = {alias_of = "Special Capital Region of Jakarta, Indonesia"},
["Jambi, Indonesia"] = {},
["Lampung, Indonesia"] = {},
["Maluku, Indonesia"] = {},
["North Kalimantan, Indonesia"] = {},
["North Maluku, Indonesia"] = {},
["North Sulawesi, Indonesia"] = {},
["North Papua, Indonesia"] = {},
["North Sumatra, Indonesia"] = {},
["Papua, Indonesia"] = {wp = "%l (province)"},
["Riau, Indonesia"] = {},
["Riau Islands, Indonesia"] = {the = true},
["Southeast Sulawesi, Indonesia"] = {},
["South Kalimantan, Indonesia"] = {},
["South Papua, Indonesia"] = {},
["South Sulawesi, Indonesia"] = {},
["South Sumatra, Indonesia"] = {},
["Southwest Papua, Indonesia"] = {},
["West Java, Indonesia"] = {},
["West Kalimantan, Indonesia"] = {},
["West Nusa Tenggara, Indonesia"] = {},
["West Papua, Indonesia"] = {wp = "%l (province)"},
["West Sulawesi, Indonesia"] = {},
["West Sumatra, Indonesia"] = {},
["Special Region of Yogyakarta, Indonesia"] = {the = true},
["Yogyakarta, Indonesia"] = {alias_of = "Special Region of Yogyakarta, Indonesia"},
}
-- provinces of Indonesia
export.indonesia_group = {
default_container = "Indonesia",
default_placetype = "province",
-- per https://www.quora.com/Does-Indonesia-use-British-or-American-English, Indonesia tends to use American
-- spellings.
data = export.indonesia_provinces,
}
export.iran_provinces = {
["Alborz Province, Iran"] = {}, -- abbreviation AL, capital [[w:Karaj]]
["Ardabil Province, Iran"] = {}, -- abbreviation AR, capital [[w:Ardabil]]
["Bushehr Province, Iran"] = {}, -- abbreviation BU, capital [[w:Bushehr]]
["Chaharmahal and Bakhtiari Province, Iran"] = {}, -- abbreviation CB, capital [[w:Shahr-e Kord]]
["East Azerbaijan Province, Iran"] = {}, -- abbreviation EA, capital [[w:Tabriz]]
["Fars Province, Iran"] = {}, -- abbreviation FA, capital [[w:Shiraz]]
["Pars Province, Iran"] = {alias_of = "Fars Province, Iran", display = true},
["Gilan Province, Iran"] = {}, -- abbreviation GN, capital [[w:Rasht]]
["Golestan Province, Iran"] = {}, -- abbreviation GO, capital [[w:Gorgan]]
["Hamadan Province, Iran"] = {}, -- abbreviation HA, capital [[w:Hamadan]]
["Hormozgan Province, Iran"] = {}, -- abbreviation HO, capital [[w:Bandar Abbas]]
["Ilam Province, Iran"] = {}, -- abbreviation IL, capital [[w:Ilam, Iran|Ilam]]
["Isfahan Province, Iran"] = {}, -- abbreviation IS, capital [[w:Isfahan]]
["Kerman Province, Iran"] = {}, -- abbreviation KN, capital [[w:Kerman]]
["Kermanshah Province, Iran"] = {}, -- abbreviation KE, capital [[w:Kermanshah]]
["Khuzestan Province, Iran"] = {}, -- abbreviation KH, capital [[w:Ahvaz]]
["Kohgiluyeh and Boyer-Ahmad Province, Iran"] = {}, -- abbreviation KB, capital [[w:Yasuj]]
["Kurdistan Province, Iran"] = {}, -- abbreviation KU, capital [[w:Sanandaj]]
["Lorestan Province, Iran"] = {}, -- abbreviation LO, capital [[w:Khorramabad]]
["Markazi Province, Iran"] = {}, -- abbreviation MA, capital [[w:Arak, Iran|Arak]]
["Mazandaran Province, Iran"] = {}, -- abbreviation MN, capital [[w:Sari, Iran|Sari]]
["North Khorasan Province, Iran"] = {}, -- abbreviation NK, capital [[w:Bojnord]]
["Qazvin Province, Iran"] = {}, -- abbreviation QA, capital [[w:Qazvin]]
["Qom Province, Iran"] = {}, -- abbreviation QM, capital [[w:Qom]]
["Razavi Khorasan Province, Iran"] = {}, -- abbreviation RK, capital [[w:Mashhad]]
["Semnan Province, Iran"] = {}, -- abbreviation SE, capital [[w:Semnan, Iran|Semnan]]
["Sistan and Baluchestan Province, Iran"] = {}, -- abbreviation SB, capital [[w:Zahedan]]
["South Khorasan Province, Iran"] = {}, -- abbreviation SK, capital [[w:Birjand]]
["Tehran Province, Iran"] = {}, -- abbreviation TE, capital [[w:Tehran]]
["West Azerbaijan Province, Iran"] = {}, -- abbreviation WA, capital [[w:Urmia]]
["Yazd Province, Iran"] = {}, -- abbreviation YA, capital [[w:Yazd]]
["Zanjan Province, Iran"] = {}, -- abbreviation ZA, capital [[w:Zanjan, Iran|Zanjan]]
}
-- provinces of Iran
export.iran_group = {
key_to_placename = make_key_to_placename(", Iran", " Province$"),
placename_to_key = make_placename_to_key(", Iran", " Province"),
default_container = "Iran",
default_placetype = "province",
-- There aren't nearly enough counties of Iran currently entered in any language to allow for categorizing them
-- per-province. (As of 2025-05-09, there are only 6 counties in each of [[Category:en:Counties of Iran]],
-- [[Category:fa:Counties of Iran]] and [[Category:ar:Counties of Iran]].)
-- default_divs = "kaunti",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
data = export.iran_provinces,
}
export.ireland_counties = {
["County Carlow, Ireland"] = {},
["County Cavan, Ireland"] = {},
["County Clare, Ireland"] = {},
["County Cork, Ireland"] = {},
["County Donegal, Ireland"] = {},
["County Dublin, Ireland"] = {},
["County Galway, Ireland"] = {},
["County Kerry, Ireland"] = {},
["County Kildare, Ireland"] = {},
["County Kilkenny, Ireland"] = {},
["County Laois, Ireland"] = {},
["County Leitrim, Ireland"] = {},
["County Limerick, Ireland"] = {},
["County Longford, Ireland"] = {},
["County Louth, Ireland"] = {},
["County Mayo, Ireland"] = {},
["County Meath, Ireland"] = {},
["County Monaghan, Ireland"] = {},
["County Offaly, Ireland"] = {},
["County Roscommon, Ireland"] = {},
["County Sligo, Ireland"] = {},
["County Tipperary, Ireland"] = {},
["County Waterford, Ireland"] = {},
["County Westmeath, Ireland"] = {},
["County Wexford, Ireland"] = {},
["County Wicklow, Ireland"] = {},
}
local function make_irish_type_key_to_placename(container_pattern)
return function(key)
key = key:gsub(container_pattern, "")
local elliptical_key = key:gsub("^County ", "")
return key, elliptical_key
end
end
local function make_irish_type_placename_to_key(container_suffix)
return function(placename)
if not placename:find("^County ") and not placename:find("^City ") then
placename = "County " .. placename
end
return placename .. container_suffix
end
end
-- counties of Ireland
export.ireland_group = {
key_to_placename = make_irish_type_key_to_placename(", Ireland$"),
placename_to_key = make_irish_type_placename_to_key(", Ireland"),
default_container = "Ireland",
default_placetype = "kaunti",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Itali"] = {},
["Aosta Valley, Itali"] = {placetype = {"autonomous region", "administrative region", "wilayah"}},
["Apulia, Itali"] = {},
["Basilicata, Itali"] = {},
["Calabria, Itali"] = {},
["Campania, Itali"] = {},
["Emilia-Romagna, Itali"] = {},
["Friuli-Venezia Giulia, Itali"] = {placetype = {"autonomous region", "administrative region", "wilayah"}},
["Lazio, Itali"] = {},
["Liguria, Itali"] = {},
["Lombardy, Itali"] = {},
["Marche, Itali"] = {},
["Molise, Itali"] = {},
["Piedmont, Itali"] = {},
["Sardinia, Itali"] = {placetype = {"autonomous region", "administrative region", "wilayah"}},
["Sicily, Itali"] = {placetype = {"autonomous region", "administrative region", "wilayah"}},
["Trentino-Alto Adige, Itali"] = {placetype = {"autonomous region", "administrative region", "wilayah"}},
["Tuscany, Itali"] = {},
["Umbria, Itali"] = {},
["Veneto, Itali"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Itali",
default_placetype = "wilayah",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi Prefecture, Jepun"] = {},
["Akita Prefecture, Jepun"] = {},
["Aomori Prefecture, Jepun"] = {},
["Chiba Prefecture, Jepun"] = {},
["Ehime Prefecture, Jepun"] = {},
["Fukui Prefecture, Jepun"] = {},
["Fukuoka Prefecture, Jepun"] = {},
["Fukushima Prefecture, Jepun"] = {},
["Gifu Prefecture, Jepun"] = {},
["Gunma Prefecture, Jepun"] = {},
["Hiroshima Prefecture, Jepun"] = {},
["Hokkaido Prefecture, Jepun"] = {divs = "subprefectures", wp = "Hokkaido"},
["Hyōgo Prefecture, Jepun"] = {},
["Hyogo Prefecture, Jepun"] = {alias_of = "Hyōgo Prefecture, Jepun", display = true},
["Ibaraki Prefecture, Jepun"] = {},
["Ishikawa Prefecture, Jepun"] = {},
["Iwate Prefecture, Jepun"] = {},
["Kagawa Prefecture, Jepun"] = {},
["Kagoshima Prefecture, Jepun"] = {},
["Kanagawa Prefecture, Jepun"] = {},
["Kōchi Prefecture, Jepun"] = {},
["Kochi Prefecture, Jepun"] = {alias_of = "Kōchi Prefecture, Jepun", display = true},
["Kumamoto Prefecture, Jepun"] = {},
["Kyoto Prefecture, Jepun"] = {},
["Mie Prefecture, Jepun"] = {},
["Miyagi Prefecture, Jepun"] = {},
["Miyazaki Prefecture, Jepun"] = {},
["Nagano Prefecture, Jepun"] = {},
["Nagasaki Prefecture, Jepun"] = {},
["Nara Prefecture, Jepun"] = {},
["Niigata Prefecture, Jepun"] = {},
["Ōita Prefecture, Jepun"] = {},
["Oita Prefecture, Jepun"] = {alias_of = "Ōita Prefecture, Jepun", display = true},
["Okayama Prefecture, Jepun"] = {},
["Okinawa Prefecture, Jepun"] = {},
["Osaka Prefecture, Jepun"] = {},
["Saga Prefecture, Jepun"] = {},
["Saitama Prefecture, Jepun"] = {},
["Shiga Prefecture, Jepun"] = {},
["Shimane Prefecture, Jepun"] = {},
["Shizuoka Prefecture, Jepun"] = {},
["Tochigi Prefecture, Jepun"] = {},
["Tokushima Prefecture, Jepun"] = {},
["Tottori Prefecture, Jepun"] = {},
["Toyama Prefecture, Jepun"] = {},
["Wakayama Prefecture, Jepun"] = {},
["Yamagata Prefecture, Jepun"] = {},
["Yamaguchi Prefecture, Jepun"] = {},
["Yamanashi Prefecture, Jepun"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Japan$", " Prefecture$"),
placename_to_key = make_placename_to_key(", Jepun", " Prefecture"),
default_container = "Japan",
default_placetype = "prefecture",
data = export.japan_prefectures,
}
export.laos_provinces = {
["Attapeu Province, Laos"] = {},
["Bokeo Province, Laos"] = {},
["Bolikhamxai Province, Laos"] = {},
["Champasak Province, Laos"] = {},
["Houaphanh Province, Laos"] = {},
["Khammouane Province, Laos"] = {},
["Luang Namtha Province, Laos"] = {},
["Luang Prabang Province, Laos"] = {},
["Oudomxay Province, Laos"] = {},
["Phongsaly Province, Laos"] = {},
["Salavan Province, Laos"] = {},
["Savannakhet Province, Laos"] = {},
["Vientiane Province, Laos"] = {},
["Vientiane Prefecture, Laos"] = {placetype = "prefecture", wp = "%l"},
["Sainyabuli Province, Laos"] = {},
["Sekong Province, Laos"] = {},
["Xaisomboun Province, Laos"] = {},
["Xiangkhouang Province, Laos"] = {},
}
local function laos_placename_to_key(placename)
if placename == "Vientiane Prefecture" then
return placename .. ", Laos"
end
if placename:find(" Province$") then
return placename .. ", Laos"
end
return placename .. " Province, Laos"
end
-- provinces of Laos
export.laos_group = {
key_to_placename = make_key_to_placename(", Laos$", {" Province$", " Prefecture$"}),
placename_to_key = laos_placename_to_key,
default_container = "Laos",
default_placetype = "province",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
data = export.laos_provinces,
}
export.lebanon_governorates = {
["Akkar Governorate, Lebanon"] = {},
["Baalbek-Hermel Governorate, Lebanon"] = {},
["Beirut Governorate, Lebanon"] = {},
["Beqaa Governorate, Lebanon"] = {},
["Keserwan-Jbeil Governorate, Lebanon"] = {},
["Mount Lebanon Governorate, Lebanon"] = {},
["Nabatieh Governorate, Lebanon"] = {},
-- These two are generic enough that we don't want to automatically augment a use of `gov/North Governorate` or
-- `gov/South Governorate` with `c/Lebanon`.
["North Governorate, Lebanon"] = {no_auto_augment_container = true},
["South Governorate, Lebanon"] = {no_auto_augment_container = true},
}
-- governorates of Lebanon
export.lebanon_group = {
key_to_placename = make_key_to_placename(", Lebanon$", " Governorate$"),
placename_to_key = make_placename_to_key(", Lebanon", " Governorate"),
default_container = "Lebanon",
default_placetype = "kegabenoran",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Melaka, Malaysia"] = {},
["Negeri Sembilan, Malaysia"] = {},
["Pahang, Malaysia"] = {},
["Penang, Malaysia"] = {},
["Perak, Malaysia"] = {},
["Perlis, Malaysia"] = {},
["Sabah, Malaysia"] = {},
["Sarawak, Malaysia"] = {},
["Selangor, Malaysia"] = {},
["Terengganu, Malaysia"] = {},
}
-- states of Malaysia
export.malaysia_group = {
default_container = "Malaysia",
default_placetype = "negeri",
default_wp = "%l, %c",
data = export.malaysia_states,
}
export.malta_regions = {
-- Some of the regions are generic enough that we don't want to automatically augment a use of e.g.
-- `r/Northern Region` with `c/Malta`. In particular;
-- * "Eastern Region" also occurs at least in Ghana, Uganda, Iceland, Nigeria, Venezuela, North Macedonia and
-- El Salvador;
-- * "Northern Region" also occurs at least in Ghana, Uganda, Malawi, Nigeria, Canada and South Africa;
-- * "Western Region" also occurs at least in Abu Dhabi, Bahrain, South Africa, Ghana, Iceland, Nepal, Nigeria,
-- Serbia and Uganda;
-- * "Southern Region" also occurs at least in Nigeria, Eritrea, Iceland, Ireland, Malawi and Serbia.
["Eastern Region, Malta"] = {no_auto_augment_container = true},
["Gozo Region, Malta"] = {wp = "%l"},
["Northern Region, Malta"] = {no_auto_augment_container = true},
["Port Region, Malta"] = {},
["Southern Region, Malta"] = {no_auto_augment_container = true},
["Western Region, Malta"] = {no_auto_augment_container = true},
}
-- regions of Malta
export.malta_group = {
key_to_placename = make_key_to_placename(", Malta$", " Region"),
placename_to_key = make_placename_to_key(", Malta", " Region"),
default_container = "Malta",
default_placetype = "wilayah",
default_wp = "%l, %c",
default_the = true,
data = export.malta_regions,
}
export.mexico_states = {
["Aguascalientes, Mexico"] = {},
["Baja California, Mexico"] = {},
-- not display-canonicalizing because the "Norte" could be for emphasis
["Baja California Norte, Mexico"] = {alias_of = "Baja California, Mexico"},
["Baja California Sur, Mexico"] = {},
["Campeche, Mexico"] = {},
["Chiapas, Mexico"] = {},
["Chihuahua, Mexico"] = {wp = "%l (state)"},
["Coahuila, Mexico"] = {},
["Colima, Mexico"] = {},
["Durango, Mexico"] = {},
["Guanajuato, Mexico"] = {},
["Guerrero, Mexico"] = {},
["Hidalgo, Mexico"] = {wp = "%l (state)"},
["Jalisco, Mexico"] = {},
["State of Mexico, Mexico"] = {the = true},
["Mexico, Mexico"] = {alias_of = "State of Mexico, Mexico"}, -- differs in "the"
-- ["Mexico City, Mexico"] = {}, doesn't belong here because it's a city
["Michoacán, Mexico"] = {},
["Michoacan, Mexico"] = {alias_of = "Michoacán, Mexico", display = true},
["Morelos, Mexico"] = {},
["Nayarit, Mexico"] = {},
["Nuevo León, Mexico"] = {},
["Nuevo Leon, Mexico"] = {alias_of = "Nuevo León, Mexico", display = true},
["Oaxaca, Mexico"] = {},
["Puebla, Mexico"] = {},
["Querétaro, Mexico"] = {},
["Queretaro, Mexico"] = {alias_of = "Querétaro, Mexico", display = true},
["Quintana Roo, Mexico"] = {},
["San Luis Potosí, Mexico"] = {},
["San Luis Potosi, Mexico"] = {alias_of = "San Luis Potosí, Mexico", display = true},
["Sinaloa, Mexico"] = {},
["Sonora, Mexico"] = {},
["Tabasco, Mexico"] = {},
["Tamaulipas, Mexico"] = {},
["Tlaxcala, Mexico"] = {},
["Veracruz, Mexico"] = {},
["Yucatán, Mexico"] = {},
["Yucatan, Mexico"] = {alias_of = "Yucatán, Mexico", display = true},
["Zacatecas, Mexico"] = {},
}
-- Mexican states
export.mexico_group = {
default_container = "Mexico",
default_placetype = "negeri",
data = export.mexico_states,
}
export.moldova_districts_and_autonomous_territorial_units = {
["Anenii Noi District, Moldova"] = {}, -- capital [[Anenii Noi]]
["Basarabeasca District, Moldova"] = {}, -- capital [[Basarabeasca]]
["Briceni District, Moldova"] = {}, -- capital [[Briceni]]
["Cahul District, Moldova"] = {}, -- capital [[Cahul]]
["Cantemir District, Moldova"] = {}, -- capital [[Cantemir, Moldova|Cantemir]]
["Călărași District, Moldova"] = {}, -- capital [[Călărași, Moldova|Călărași]]
["Căușeni District, Moldova"] = {}, -- capital [[Căușeni]]
["Cimișlia District, Moldova"] = {}, -- capital [[Cimișlia]]
["Criuleni District, Moldova"] = {}, -- capital [[Criuleni]]
["Dondușeni District, Moldova"] = {}, -- capital [[Dondușeni]]
["Drochia District, Moldova"] = {}, -- capital [[Drochia]]
["Dubăsari District, Moldova"] = {}, -- capital [[Cocieri]]
["Edineț District, Moldova"] = {}, -- capital [[Edineț]]
["Fălești District, Moldova"] = {}, -- capital [[Fălești]]
["Florești District, Moldova"] = {}, -- capital [[Florești, Moldova|Florești]]
["Glodeni District, Moldova"] = {}, -- capital [[Glodeni]]
["Hîncești District, Moldova"] = {}, -- capital [[Hîncești]]
["Ialoveni District, Moldova"] = {}, -- capital [[Ialoveni]]
["Leova District, Moldova"] = {}, -- capital [[Leova]]
["Nisporeni District, Moldova"] = {}, -- capital [[Nisporeni]]
["Ocnița District, Moldova"] = {}, -- capital [[Ocnița]]
["Orhei District, Moldova"] = {}, -- capital [[Orhei]]
["Rezina District, Moldova"] = {}, -- capital [[Rezina]]
["Rîșcani District, Moldova"] = {}, -- capital [[Rîșcani]]
["Sîngerei District, Moldova"] = {}, -- capital [[Sîngerei]]
["Soroca District, Moldova"] = {}, -- capital [[Soroca]]
["Strășeni District, Moldova"] = {}, -- capital [[Strășeni]]
["Șoldănești District, Moldova"] = {}, -- capital [[Șoldănești]]
["Ștefan Vodă District, Moldova"] = {}, -- capital [[Ștefan Vodă]]
["Taraclia District, Moldova"] = {}, -- capital [[Taraclia]]
["Telenești District, Moldova"] = {}, -- capital [[Telenești]]
["Ungheni District, Moldova"] = {}, -- capital [[Ungheni]]
["Chișinău, Moldova"] = {placetype = "municipality"},
["Bălți, Moldova"] = {placetype = "municipality"},
["Gagauzia, Moldova"] = {placetype = {"autonomous territorial unit", "autonomous region", "wilayah"}}, -- capital [[Comrat]]
-- the remainder are under the de-facto control of the unrecognized state of Transnistria
["Bender, Moldova"] = {placetype = "municipality"},
["Tighina, Moldova"] = {alias_of = "Bender, Moldova"},
["Transnistria, Moldova"] = {placetype = {"autonomous territorial unit", "autonomous region", "wilayah"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova", the = true},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova", the = true},
}
local function moldova_placename_to_key(placename)
local elliptical_key = placename .. ", Moldova"
if export.moldova_districts_and_autonomous_territorial_units[elliptical_key] then
return elliptical_key
end
if placename:find(" District$") then
return placename .. ", Moldova"
end
return placename .. " District, Moldova"
end
-- Moldovan districts (raions) and autonomous territorial units
export.moldova_group = {
key_to_placename = make_key_to_placename(", Moldova$", " District"),
placename_to_key = moldova_placename_to_key,
default_container = "Moldova",
default_placetype = {"daerah", "raion"},
default_divs = "communes",
data = export.moldova_districts_and_autonomous_territorial_units,
}
export.morocco_regions = {
["Tangier-Tetouan-Al Hoceima, Morocco"] = {},
["Oriental, Morocco"] = {wp = "%l (%c)"},
["L'Oriental, Morocco"] = {alias_of = "Oriental, Morocco", display = true},
["Fez-Meknes, Morocco"] = {},
["Rabat-Sale-Kenitra, Morocco"] = {wp = "Rabat-Salé-Kénitra"},
["Rabat-Salé-Kénitra, Morocco"] = {alias_of = "Rabat-Sale-Kenitra, Morocco", display = true},
["Beni Mellal-Khenifra, Morocco"] = {wp = "Béni Mellal-Khénifra"},
["Béni Mellal-Khénifra, Morocco"] = {alias_of = "Beni Mellal-Khenifra, Morocco", display = true},
["Casablanca-Settat, Morocco"] = {},
["Marrakesh-Safi, Morocco"] = {wp = "Marrakesh–Safi"}, -- WP title has en-dash
["Marrakech-Safi, Morocco"] = {alias_of = "Marrakesh-Safi, Morocco", display = true},
["Draa-Tafilalet, Morocco"] = {wp = "Drâa-Tafilalet"},
["Drâa-Tafilalet, Morocco"] = {alias_of = "Draa-Tafilalet, Morocco", display = true},
["Souss-Massa, Morocco"] = {},
["Guelmim-Oued Noun, Morocco"] = {
keydesc = "+++. '''NOTE:''' This region lies partly within the disputed territory of [[Western Sahara]]"
},
["Laayoune-Sakia El Hamra, Morocco"] = {
wp = "Laâyoune-Sakia El Hamra",
keydesc = "+++. '''NOTE:''' This region lies almost completely within the disputed territory of [[Western Sahara]]",
},
["Laâyoune-Sakia El Hamra, Morocco"] = {alias_of = "Laayoune-Sakia El Hamra, Morocco", display = true},
["Dakhla-Oued Ed-Dahab, Morocco"] = {
keydesc = "+++. '''NOTE:''' This region lies completely within the disputed territory of [[Western Sahara]]",
},
}
-- regions of Morocco
export.morocco_group = {
default_container = "Maghribi",
default_placetype = "wilayah",
data = export.morocco_regions,
}
export.egypt_governorates = {
["Cairo Governorate, Egypt"] = {},
["Giza Governorate, Egypt"] = {},
["Sharqia Governorate, Egypt"] = {},
["Dakahlia Governorate, Egypt"] = {},
["Beheira Governorate, Egypt"] = {},
["Minya Governorate, Egypt"] = {},
["Qalyubia Governorate, Egypt"] = {},
["Sohag Governorate, Egypt"] = {},
["Alexandria Governorate, Egypt"] = {},
["Gharbia Governorate, Egypt"] = {},
["Asyut Governorate, Egypt"] = {},
["Monufia Governorate, Egypt"] = {},
["Faiyum Governorate, Egypt"] = {},
["Kafr El Sheikh Governorate, Egypt"] = {},
["Qena Governorate, Egypt"] = {},
["Beni Suef Governorate, Egypt"] = {},
["Damietta Governorate, Egypt"] = {},
["Aswan Governorate, Egypt"] = {},
["Ismailia Governorate, Egypt"] = {},
["Luxor Governorate, Egypt"] = {},
["Suez Governorate, Egypt"] = {},
["Port Said Governorate, Egypt"] = {},
["Matrouh Governorate, Egypt"] = {},
["North Sinai Governorate, Egypt"] = {},
["Red Sea Governorate, Egypt"] = {},
["New Valley Governorate, Egypt"] = {},
["South Sinai Governorate, Egypt"] = {},
}
-- governorates of Egypt
export.egypt_group = {
key_to_placename = make_key_to_placename(", Egypt$", " Governorate$"),
placename_to_key = make_placename_to_key(", Egypt", " Governorate"),
default_container = "Mesir",
default_placetype = "kegabenoran",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Belanda"] = {},
["Flevoland, Belanda"] = {},
["Friesland, Belanda"] = {},
["Gelderland, Belanda"] = {},
["Groningen, Belanda"] = {wp = "%l (province)"},
["Limburg, Belanda"] = {wp = "%l (%c)"},
["North Brabant, Belanda"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Belanda"] = {alias_of = "North Brabant, Belanda", display = true},
["North Holland, Belanda"] = {},
["Noord-Holland, Belanda"] = {alias_of = "North Holland, Belanda", display = true},
["Overijssel, Belanda"] = {},
["South Holland, Belanda"] = {},
["Zuid-Holland, Belanda"] = {alias_of = "South Holland, Belanda", display = true},
["Utrecht, Belanda"] = {wp = "%l (province)"},
["Zeeland, Belanda"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Belanda",
default_placetype = "province",
default_divs = "municipalities",
data = export.netherlands_provinces,
}
export.new_zealand_regions = {
-- North Island regions
["Northland, New Zealand"] = {wp = "%l Region"}, -- ISO 3166-2 code NZ-NTL, number 1, capital [[Whangārei]]
["Auckland, New Zealand"] = {wp = "%l Region"}, -- ISO 3166-2 code NZ-AUK, number 2, capital [[Auckland]]
["Waikato, New Zealand"] = {}, -- ISO 3166-2 code NZ-WKO, number 3, capital [[Hamilton, New Zealand|Hamilton]]
["Bay of Plenty, New Zealand"] = {the = true, wp = "%l Region"}, -- ISO 3166-2 code NZ-BOP, number 4, capital [[Whakatāne]]
["Gisborne, New Zealand"] = {placetype = {"wilayah", "daerah"}, wp = "%l District"}, -- ISO 3166-2 code NZ-GIS, number 5, capital [[Gisborne, New Zealand|Gisborne]]
["Hawke's Bay, New Zealand"] = {}, -- ISO 3166-2 code NZ-HKB, number 6, capital [[Napier, New Zealand|Napier]]
["Taranaki, New Zealand"] = {}, -- ISO 3166-2 code NZ-TKI, number 7, capital [[Stratford, New Zealand|Stratford]]
["Manawatū-Whanganui, New Zealand"] = {}, -- ISO 3166-2 code NZ-MWT, number 8, capital [[Palmerston North]]
["Manawatu-Whanganui, New Zealand"] = {alias_of = "Manawatū-Whanganui, New Zealand", display = true},
["Manawatu-Wanganui, New Zealand"] = {alias_of = "Manawatū-Whanganui, New Zealand", display = true},
["Wellington, New Zealand"] = {wp = "%l Region"}, -- ISO 3166-2 code NZ-WGN, number 9, capital [[Wellington]]
-- South Island regions
["Tasman, New Zealand"] = {placetype = {"wilayah", "daerah"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"wilayah", "bandar"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"wilayah", "daerah"}, wp = "%l District"}, -- ISO 3166-2 code NZ-MBH, number 12, capital [[Blenheim, New Zealand|Blenheim]]
["West Coast, New Zealand"] = {the = true, wp = "%l Region"}, -- ISO 3166-2 code NZ-WTC, number 13, capital [[Greymouth]]
["Canterbury, New Zealand"] = {wp = "%l Region"}, -- ISO 3166-2 code NZ-CAN, number 14, capital [[Christchurch]]
["Otago, New Zealand"] = {}, -- ISO 3166-2 code NZ-OTA, number 15, capital [[Dunedin]]
["Southland, New Zealand"] = {wp = "%l Region"}, -- ISO 3166-2 code NZ-STL, number 16, capital [[Invercargill]]
}
-- regions of New Zealand
export.new_zealand_group = {
default_container = "New Zealand",
default_placetype = "wilayah",
data = export.new_zealand_regions,
}
export.nigeria_states = {
["Abia State, Nigeria"] = {},
["Adamawa State, Nigeria"] = {},
["Akwa Ibom State, Nigeria"] = {},
["Anambra State, Nigeria"] = {},
["Bauchi State, Nigeria"] = {},
["Bayelsa State, Nigeria"] = {},
["Benue State, Nigeria"] = {},
["Borno State, Nigeria"] = {},
["Cross River State, Nigeria"] = {},
["Delta State, Nigeria"] = {},
["Ebonyi State, Nigeria"] = {},
["Edo State, Nigeria"] = {},
["Ekiti State, Nigeria"] = {},
["Enugu State, Nigeria"] = {},
["Federal Capital Territory, Nigeria"] = {
-- not a state but allow it to be referenced as one in holonyms
placetype = {"wilayah persekutuan", "territory", "negeri"}, the = true, wp = "%l (%c)",
},
["Gombe State, Nigeria"] = {},
["Imo State, Nigeria"] = {},
["Jigawa State, Nigeria"] = {},
["Kaduna State, Nigeria"] = {},
["Kano State, Nigeria"] = {},
["Katsina State, Nigeria"] = {},
["Kebbi State, Nigeria"] = {},
["Kogi State, Nigeria"] = {},
["Kwara State, Nigeria"] = {},
["Lagos State, Nigeria"] = {},
["Nasarawa State, Nigeria"] = {},
["Niger State, Nigeria"] = {},
["Ogun State, Nigeria"] = {},
["Ondo State, Nigeria"] = {},
["Osun State, Nigeria"] = {},
["Oyo State, Nigeria"] = {},
["Plateau State, Nigeria"] = {},
["Rivers State, Nigeria"] = {},
["Sokoto State, Nigeria"] = {},
["Taraba State, Nigeria"] = {},
["Yobe State, Nigeria"] = {},
["Zamfara State, Nigeria"] = {},
}
-- states of Nigeria
export.nigeria_group = {
key_to_placename = make_key_to_placename(", Nigeria$", " State$"),
placename_to_key = make_placename_to_key(", Nigeria", " State"),
default_container = "Nigeria",
default_placetype = "negeri",
data = export.nigeria_states,
}
export.north_korea_provinces = {
["Chagang Province, North Korea"] = {},
["North Hamgyong Province, North Korea"] = {},
["South Hamgyong Province, North Korea"] = {},
["North Hwanghae Province, North Korea"] = {},
["South Hwanghae Province, North Korea"] = {},
["Kangwon Province, North Korea"] = {wp = "%l (%c)"},
["North Pyongan Province, North Korea"] = {},
["South Pyongan Province, North Korea"] = {},
["Ryanggang Province, North Korea"] = {},
}
-- provinces of North Korea
export.north_korea_group = {
key_to_placename = make_key_to_placename(", North Korea$", " Province$"),
placename_to_key = make_placename_to_key(", North Korea", " Province"),
default_container = "North Korea",
default_placetype = "province",
data = export.north_korea_provinces,
}
export.norwegian_counties = {
["Oslo, Norway"] = {},
["Rogaland, Norway"] = {},
["Møre og Romsdal, Norway"] = {},
["Nordland, Norway"] = {},
["Østfold, Norway"] = {},
["Akershus, Norway"] = {},
["Buskerud, Norway"] = {},
-- the following two were merged into Innlandet
-- ["Hedmark, Norway"] = {},
-- ["Oppland, Norway"] = {},
["Innlandet, Norway"] = {},
["Vestfold, Norway"] = {},
["Telemark, Norway"] = {},
-- the following two were merged into Agder
-- ["Aust-Agder, Norway"] = {},
-- ["Vest-Agder, Norway"] = {},
["Agder, Norway"] = {},
-- the following two were merged into Vestland
-- ["Hordaland, Norway"] = {},
-- ["Sogn og Fjordane, Norway"] = {},
["Vestland, Norway"] = {},
["Trøndelag, Norway"] = {},
["Troms, Norway"] = {},
["Finnmark, Norway"] = {},
}
-- counties of Norway
export.norway_group = {
default_container = "Norway",
default_placetype = "kaunti",
data = export.norwegian_counties,
}
export.pakistan_provinces_and_territories = {
["Azad Kashmir, Pakistan"] = {
placetype = {"administrative territory", "autonomous territory", "territory"},
},
["Azad Jammu and Kashmir, Pakistan"] = {alias_of = "Azad Kashmir, Pakistan", display = true},
["Balochistan, Pakistan"] = {wp = "%l, %c"},
["Gilgit-Baltistan, Pakistan"] = {
placetype = {"administrative territory", "territory"},
},
["Islamabad Capital Territory, Pakistan"] = {
the = true,
divs = {}, -- no divisions
placetype = {"wilayah persekutuan", "administrative territory", "territory"},
},
-- Islamabad is an accepted alias for Islamabad Capital Territory given the above placetypes
["Islamabad, Pakistan"] = {alias_of = "Islamabad Capital Territory, Pakistan"},
["Khyber Pakhtunkhwa, Pakistan"] = {},
["Punjab, Pakistan"] = {wp = "%l, %c"},
["Sindh, Pakistan"] = {},
}
-- provinces and territories of Pakistan
export.pakistan_group = {
default_container = "Pakistan",
default_placetype = "province",
default_divs = "divisions",
data = export.pakistan_provinces_and_territories,
}
export.philippines_provinces = {
["Abra, Filipina"] = {wp = "%l (province)"},
["Agusan del Norte, Filipina"] = {},
["Agusan del Sur, Filipina"] = {},
["Aklan, Filipina"] = {},
["Albay, Filipina"] = {},
["Antique, Filipina"] = {wp = "%l (province)"},
["Apayao, Filipina"] = {},
["Aurora, Filipina"] = {wp = "%l (province)"},
["Basilan, Filipina"] = {},
["Bataan, Filipina"] = {},
["Batanes, Filipina"] = {},
["Batangas, Filipina"] = {},
["Benguet, Filipina"] = {},
["Biliran, Filipina"] = {},
["Bohol, Filipina"] = {},
["Bukidnon, Filipina"] = {},
["Bulacan, Filipina"] = {},
["Cagayan, Filipina"] = {},
["Camarines Norte, Filipina"] = {},
["Camarines Sur, Filipina"] = {},
["Camiguin, Filipina"] = {},
["Capiz, Filipina"] = {},
["Catanduanes, Filipina"] = {},
["Cavite, Filipina"] = {},
["Cebu, Filipina"] = {},
["Cotabato, Filipina"] = {},
["Davao de Oro, Filipina"] = {},
["Davao del Norte, Filipina"] = {},
["Davao del Sur, Filipina"] = {},
["Davao Occidental, Filipina"] = {},
["Davao Oriental, Filipina"] = {},
["Dinagat Islands, Filipina"] = {the = true},
["Eastern Samar, Filipina"] = {},
["Guimaras, Filipina"] = {},
["Ifugao, Filipina"] = {},
["Ilocos Norte, Filipina"] = {},
["Ilocos Sur, Filipina"] = {},
["Iloilo, Filipina"] = {},
["Isabela, Filipina"] = {wp = "%l (province)"},
["Kalinga, Filipina"] = {wp = "%l (province)"},
["La Union, Filipina"] = {},
["Laguna, Filipina"] = {wp = "%l (province)"},
["Lanao del Norte, Filipina"] = {},
["Lanao del Sur, Filipina"] = {},
["Leyte, Filipina"] = {wp = "%l (province)"},
["Maguindanao del Norte, Filipina"] = {},
["Maguindanao del Sur, Filipina"] = {},
["Marinduque, Filipina"] = {},
["Masbate, Filipina"] = {},
["Misamis Occidental, Filipina"] = {},
["Misamis Oriental, Filipina"] = {},
["Mountain Province, Filipina"] = {},
["Negros Occidental, Filipina"] = {},
["Negros Oriental, Filipina"] = {},
["Northern Samar, Filipina"] = {},
["Nueva Ecija, Filipina"] = {},
["Nueva Vizcaya, Filipina"] = {},
["Occidental Mindoro, Filipina"] = {},
["Oriental Mindoro, Filipina"] = {},
["Palawan, Filipina"] = {},
["Pampanga, Filipina"] = {},
["Pangasinan, Filipina"] = {},
["Quezon, Filipina"] = {},
["Quirino, Filipina"] = {},
["Rizal, Filipina"] = {wp = "%l (province)"},
["Romblon, Filipina"] = {},
["Samar, Filipina"] = {wp = "%l (province)"},
["Sarangani, Filipina"] = {},
["Siquijor, Filipina"] = {},
["Sorsogon, Filipina"] = {},
["South Cotabato, Filipina"] = {},
["Southern Leyte, Filipina"] = {},
["Sultan Kudarat, Filipina"] = {},
["Sulu, Filipina"] = {},
["Surigao del Norte, Filipina"] = {},
["Surigao del Sur, Filipina"] = {},
["Tarlac, Filipina"] = {},
["Tawi-Tawi, Filipina"] = {},
["Zambales, Filipina"] = {},
["Zamboanga del Norte, Filipina"] = {},
["Zamboanga del Sur, Filipina"] = {},
["Zamboanga Sibugay, Filipina"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Filipina"] = {placetype = {"wilayah", "province"}},
}
-- provinces of the Philippines
export.philippines_group = {
default_container = "Philippines",
default_placetype = "province",
default_divs = {"municipalities", "barangays"},
data = export.philippines_provinces,
}
export.poland_voivodeships = {
["Lower Silesian Voivodeship, Poland"] = {}, -- abbr DS, code 02, capital Wrocław
["Kuyavian-Pomeranian Voivodeship, Poland"] = {}, -- abbr KP, code 04, capital Bydgoszcz (seat of voivode), Toruń (seat of sejmik and marshal)
["Lublin Voivodeship, Poland"] = {}, -- abbr LU, code 06, capital Lublin
["Lubusz Voivodeship, Poland"] = {}, -- abbr LB, code 08, capital Gorzów Wielkopolski (seat of voivode), Zielona Góra (seat of sejmik and marshal)
["Lodz Voivodeship, Poland"] = {wp = "Łódź Voivodeship"}, -- abbr LD, code 10, capital Łódź
["Łódź Voivodeship, Poland"] = {alias_of = "Lodz Voivodeship, Poland", display = true, display_as_full = true},
["Lesser Poland Voivodeship, Poland"] = {}, -- abbr MA, code 12, capital Kraków
["Masovian Voivodeship, Poland"] = {}, -- abbr MZ, code 14, capital Warsaw
["Opole Voivodeship, Poland"] = {}, -- abbr OP, code 16, capital Opole
["Subcarpathian Voivodeship, Poland"] = {}, -- abbr PK, code 18, capital Rzeszów
["Podlaskie Voivodeship, Poland"] = {}, -- abbr PD, code 20, capital Białystok
["Pomeranian Voivodeship, Poland"] = {}, -- abbr PM, code 22, capital Gdańsk
["Silesian Voivodeship, Poland"] = {}, -- abbr SL, code 24, capital Katowice
["Holy Cross Voivodeship, Poland"] = {wp = "Świętokrzyskie Voivodeship"}, -- abbr SK, code 26, capital Kielce
["Świętokrzyskie Voivodeship, Poland"] = {alias_of = "Holy Cross Voivodeship, Poland", display = true, display_as_full = true},
["Warmian-Masurian Voivodeship, Poland"] = {}, -- abbr WN, code 28, capital Olsztyn
["Greater Poland Voivodeship, Poland"] = {}, -- abbr WP, code 30, capital Poznań
["West Pomeranian Voivodeship, Poland"] = {}, -- abbr ZP, code 32, capital Szczecin
}
-- voivodeships of Poland
export.poland_group = {
key_to_placename = make_key_to_placename(", Poland$", " Voivodeship$"),
placename_to_key = make_placename_to_key(", Poland", " Voivodeship"),
default_container = "Poland",
default_placetype = "voivodeship",
default_divs = {
-- "kaunti", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "kampung", prep = "di"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "wilayah"}},
["Aveiro District, Portugal"] = {},
["Beja District, Portugal"] = {},
["Braga District, Portugal"] = {},
["Bragança District, Portugal"] = {},
["Castelo Branco District, Portugal"] = {},
["Coimbra District, Portugal"] = {},
["Évora District, Portugal"] = {},
["Faro District, Portugal"] = {},
["Guarda District, Portugal"] = {},
["Leiria District, Portugal"] = {},
["Lisbon District, Portugal"] = {},
["Lisboa District, Portugal"] = {alias_of = "Lisbon District, Portugal", display = true},
["Madeira, Portugal"] = {placetype = {"autonomous region", "wilayah"}},
["Portalegre District, Portugal"] = {},
["Porto District, Portugal"] = {},
["Santarém District, Portugal"] = {},
["Setúbal District, Portugal"] = {},
["Viana do Castelo District, Portugal"] = {},
["Vila Real District, Portugal"] = {},
["Viseu District, Portugal"] = {},
}
local function portugal_placename_to_key(placename)
if placename == "Azores" or placename == "Madeira" then
return placename .. ", Portugal"
end
if placename:find(" District$") then
return placename .. ", Portugal"
end
return placename .. " District, Portugal"
end
-- districts and autonomous regions of Portugal
export.portugal_group = {
key_to_placename = make_key_to_placename(", Portugal$", " District$"),
placename_to_key = portugal_placename_to_key,
default_container = "Portugal",
default_placetype = "daerah",
default_divs = "municipalities",
data = export.portugal_districts_and_autonomous_regions,
}
export.romania_counties = {
["Alba County, Romania"] = {},
["Arad County, Romania"] = {},
["Argeș County, Romania"] = {},
["Bacău County, Romania"] = {},
["Bihor County, Romania"] = {},
["Bistrița-Năsăud County, Romania"] = {},
["Botoșani County, Romania"] = {},
["Brașov County, Romania"] = {},
["Brăila County, Romania"] = {},
-- Bucharest: not in a county
["Buzău County, Romania"] = {},
["Caraș-Severin County, Romania"] = {},
["Cluj County, Romania"] = {},
["Constanța County, Romania"] = {},
["Covasna County, Romania"] = {},
["Călărași County, Romania"] = {},
["Dolj County, Romania"] = {},
["Dâmbovița County, Romania"] = {},
["Galați County, Romania"] = {},
["Giurgiu County, Romania"] = {},
["Gorj County, Romania"] = {},
["Harghita County, Romania"] = {},
["Hunedoara County, Romania"] = {},
["Ialomița County, Romania"] = {},
["Iași County, Romania"] = {},
["Ilfov County, Romania"] = {},
["Maramureș County, Romania"] = {},
["Mehedinți County, Romania"] = {},
["Mureș County, Romania"] = {},
["Neamț County, Romania"] = {},
["Olt County, Romania"] = {},
["Prahova County, Romania"] = {},
["Satu Mare County, Romania"] = {},
["Sibiu County, Romania"] = {},
["Suceava County, Romania"] = {},
["Sălaj County, Romania"] = {},
["Teleorman County, Romania"] = {},
["Timiș County, Romania"] = {},
["Tulcea County, Romania"] = {},
["Vaslui County, Romania"] = {},
["Vrancea County, Romania"] = {},
["Vâlcea County, Romania"] = {},
}
-- counties of Romania
export.romania_group = {
key_to_placename = make_key_to_placename(", Romania$", " County$"),
placename_to_key = make_placename_to_key(", Romania", " County"),
default_container = "Romania",
default_placetype = "kaunti",
default_divs = "communes",
data = export.romania_counties,
}
local function make_russia_federal_subject_spec(spectype, use_the, wp)
return {
placetype = spectype,
the = not not use_the,
bare_category_parent_type = {"federal subjects", spectype .. "s"},
wp = wp,
}
end
local russia_autonomous_okrug_no_the =
{placetype = {"autonomous okrug", "okrug"}, bare_category_parent_type = {"federal subjects", "autonomous okrugs"}}
local russia_autonomous_okrug_the =
{placetype = {"autonomous okrug", "okrug"}, bare_category_parent_type = {"federal subjects", "autonomous okrugs"},
the = true}
local russia_krai = make_russia_federal_subject_spec("krai")
local russia_oblast = make_russia_federal_subject_spec("oblast")
local russia_republic_the = make_russia_federal_subject_spec("republic", "use the")
local russia_republic_no_the = make_russia_federal_subject_spec("republic")
export.russia_federal_subjects = {
-- autonomous oblasts
["Jewish Autonomous Oblast, Rusia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Rusia"] = russia_autonomous_okrug_the,
["Chukotka, Rusia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Rusia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Rusia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Rusia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Rusia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Rusia"] = russia_autonomous_okrug_the,
["Nenetsia, Rusia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Rusia"] = russia_autonomous_okrug_the,
["Yamalia, Rusia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Rusia"] = russia_krai,
["Kamchatka Krai, Rusia"] = russia_krai,
["Khabarovsk Krai, Rusia"] = russia_krai,
["Krasnodar Krai, Rusia"] = russia_krai,
["Krasnoyarsk Krai, Rusia"] = russia_krai,
["Perm Krai, Rusia"] = russia_krai,
["Primorsky Krai, Rusia"] = russia_krai,
["Stavropol Krai, Rusia"] = russia_krai,
["Zabaykalsky Krai, Rusia"] = russia_krai,
-- oblasts
["Amur Oblast, Rusia"] = russia_oblast,
["Arkhangelsk Oblast, Rusia"] = russia_oblast,
["Astrakhan Oblast, Rusia"] = russia_oblast,
["Belgorod Oblast, Rusia"] = russia_oblast,
["Bryansk Oblast, Rusia"] = russia_oblast,
["Chelyabinsk Oblast, Rusia"] = russia_oblast,
["Irkutsk Oblast, Rusia"] = russia_oblast,
["Ivanovo Oblast, Rusia"] = russia_oblast,
["Kaliningrad Oblast, Rusia"] = russia_oblast,
["Kaluga Oblast, Rusia"] = russia_oblast,
["Kemerovo Oblast, Rusia"] = russia_oblast,
["Kirov Oblast, Rusia"] = russia_oblast,
["Kostroma Oblast, Rusia"] = russia_oblast,
["Kurgan Oblast, Rusia"] = russia_oblast,
["Kursk Oblast, Rusia"] = russia_oblast,
["Leningrad Oblast, Rusia"] = russia_oblast,
["Lipetsk Oblast, Rusia"] = russia_oblast,
["Magadan Oblast, Rusia"] = russia_oblast,
["Moscow Oblast, Rusia"] = russia_oblast,
["Murmansk Oblast, Rusia"] = russia_oblast,
["Nizhny Novgorod Oblast, Rusia"] = russia_oblast,
["Novgorod Oblast, Rusia"] = russia_oblast,
["Novosibirsk Oblast, Rusia"] = russia_oblast,
["Omsk Oblast, Rusia"] = russia_oblast,
["Orenburg Oblast, Rusia"] = russia_oblast,
["Oryol Oblast, Rusia"] = russia_oblast,
["Penza Oblast, Rusia"] = russia_oblast,
["Pskov Oblast, Rusia"] = russia_oblast,
["Rostov Oblast, Rusia"] = russia_oblast,
["Ryazan Oblast, Rusia"] = russia_oblast,
["Sakhalin Oblast, Rusia"] = russia_oblast,
["Samara Oblast, Rusia"] = russia_oblast,
["Saratov Oblast, Rusia"] = russia_oblast,
["Smolensk Oblast, Rusia"] = russia_oblast,
["Sverdlovsk Oblast, Rusia"] = russia_oblast,
["Tambov Oblast, Rusia"] = russia_oblast,
["Tomsk Oblast, Rusia"] = russia_oblast,
["Tula Oblast, Rusia"] = russia_oblast,
["Tver Oblast, Rusia"] = russia_oblast,
["Tyumen Oblast, Rusia"] = russia_oblast,
["Ulyanovsk Oblast, Rusia"] = russia_oblast,
["Vladimir Oblast, Rusia"] = russia_oblast,
["Volgograd Oblast, Rusia"] = russia_oblast,
["Vologda Oblast, Rusia"] = russia_oblast,
["Voronezh Oblast, Rusia"] = russia_oblast,
["Yaroslavl Oblast, Rusia"] = russia_oblast,
-- republics
--
-- We only need to include cases that aren't just shortened versions of the full federal subject name (i.e. where
-- words like "Republic" and "Oblast" are omitted but the name is not otherwise modified; these are handled by
-- key_to_placename). Non-display-canonicalizing aliases are generally due to differences in the presence or absence
-- of "the".
["Adygea, Rusia"] = russia_republic_no_the,
["Republic of Adygea, Rusia"] = {alias_of = "Adygea, Russia", the = true},
["Bashkortostan, Rusia"] = russia_republic_no_the,
["Republic of Bashkortostan, Rusia"] = {alias_of = "Bashkortostan, Russia", the = true},
["Bashkiria, Rusia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Rusia"] = russia_republic_no_the,
["Republic of Buryatia, Rusia"] = {alias_of = "Buryatia, Russia", the = true},
["Dagestan, Rusia"] = russia_republic_no_the,
["Republic of Dagestan, Rusia"] = {alias_of = "Dagestan, Russia", the = true},
["Ingushetia, Rusia"] = russia_republic_no_the,
["Republic of Ingushetia, Rusia"] = {alias_of = "Ingushetia, Russia", the = true},
["Kalmykia, Rusia"] = russia_republic_no_the,
["Republic of Kalmykia, Rusia"] = {alias_of = "Kalmykia, Russia", the = true},
["Karelia, Rusia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Rusia"] = {alias_of = "Karelia, Russia", the = true},
["Khakassia, Rusia"] = russia_republic_no_the,
["Republic of Khakassia, Rusia"] = {alias_of = "Khakassia, Russia", the = true},
["Mordovia, Rusia"] = russia_republic_no_the,
["Republic of Mordovia, Rusia"] = {alias_of = "Mordovia, Russia", the = true},
["North Ossetia-Alania, Rusia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Rusia"] = {alias_of = "North Ossetia-Alania, Russia", the = true},
["North Ossetia, Rusia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Rusia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Rusia"] = russia_republic_no_the,
["Republic of Tatarstan, Rusia"] = {alias_of = "Tatarstan, Russia", the = true},
["Altai Republic, Rusia"] = russia_republic_the,
["Chechnya, Rusia"] = russia_republic_no_the,
["Chechen Republic, Rusia"] = {alias_of = "Chechnya, Russia", the = true},
["Chuvashia, Rusia"] = russia_republic_no_the,
["Chuvash Republic, Rusia"] = {alias_of = "Chuvashia, Russia", the = true},
["Kabardino-Balkaria, Rusia"] = russia_republic_no_the,
["Kabardino-Balkariya, Rusia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Rusia"] = {alias_of = "Kabardino-Balkaria, Russia", the = true},
["Kabardino-Balkar Republic, Rusia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia", the = true},
["Karachay-Cherkessia, Rusia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Rusia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Rusia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Rusia"] = {alias_of = "Komi, Russia", the = true},
["Mari El, Rusia"] = russia_republic_no_the,
["Mari El Republic, Rusia"] = {alias_of = "Mari El, Russia", the = true},
["Sakha, Rusia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Rusia"] = {alias_of = "Sakha, Russia", the = true},
["Yakutia, Rusia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Rusia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Rusia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Rusia"] = russia_republic_no_the,
["Tyva, Rusia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Rusia"] = {alias_of = "Tuva, Russia", the = true},
["Tyva Republic, Rusia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia", the = true},
["Udmurtia, Rusia"] = russia_republic_no_the,
["Udmurt Republic, Rusia"] = {alias_of = "Udmurtia, Russia", the = true},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Rusia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Rusia"] = russia_republic_the,
-- ["Luhansk People's Republic, Rusia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Rusia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Rusia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Kherson Oblast"),
-- There are also federal cities (not included because they're cities):
-- Moscow, Saint Petersburg; Sevastopol (unrecognized; same status as for "Crimea, Russia" above)
}
local function russia_key_to_placename(key)
key = key:gsub(",.*", "")
local full_placename = key
if key == "Jewish Autonomous Oblast" then
return full_placename, full_placename
end
local elliptical_placename
for _, suffix in ipairs({"Krai", "Oblast"}) do
elliptical_placename = key:match("^(.*) " .. suffix .. "$")
if elliptical_placename then
return full_placename, elliptical_placename
end
end
return full_placename, full_placename
end
local function russia_placename_to_key(placename)
local key = placename .. ", Russia"
if export.russia_federal_subjects[key] then
return key
end
-- We allow the user to say e.g. "obl/Samara" in place of "obl/Samara Oblast".
for _, suffix in ipairs({"Krai", "Oblast"}) do
local suffixed_key = placename .. " " .. suffix .. ", Russia"
if export.russia_federal_subjects[suffixed_key] then
return suffixed_key
end
end
return placename .. ", Russia"
end
local function construct_russia_federal_subject_keydesc(_group, key, spec)
local placename = key:gsub(",.*", "")
local linked_placename = export.construct_linked_placename(spec, placename)
local placetype = spec.placetype
if type(placetype) == "table" then
placetype = placetype[1]
end
if placetype == "oblast" then
-- Hack: Oblasts generally don't have entries under "Foo Oblast"
-- but just under "Foo", so fix the linked key appropriately;
-- doesn't apply to the Jewish Autonomous Oblast
linked_placename = linked_placename:gsub(" Oblast%]%]", "%]%] Oblast")
end
return linked_placename .. ", a [[federal subject]] ([[" .. placetype .. "]]) of [[Russia]]"
end
-- federal subjects of Russia
export.russia_group = {
key_to_placename = russia_key_to_placename,
placename_to_key = russia_placename_to_key,
default_container = "Russia",
default_keydesc = construct_russia_federal_subject_keydesc,
default_overriding_bare_label_parents = {"federal subjects of Russia", "+++"},
data = export.russia_federal_subjects,
}
export.saudi_arabia_provinces = {
["Riyadh Province, Arab Saudi"] = {},
["Mecca Province, Arab Saudi"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Arab Saudi"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Arab Saudi"] = {wp = "%l (%c)"},
["Aseer Province, Arab Saudi"] = {wp = "Asir"},
["Asir Province, Arab Saudi"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Arab Saudi"] = {},
["Qassim Province, Arab Saudi"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Arab Saudi"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Arab Saudi"] = {},
["Hail Province, Arab Saudi"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Arab Saudi"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Arab Saudi"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Arab Saudi"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Arab Saudi"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Arab Saudi"] = {},
["Northern Borders Province, Arab Saudi"] = {},
["Al-Bahah Province, Arab Saudi"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Arab Saudi$", " Province$"),
placename_to_key = make_placename_to_key(", Arab Saudi", " Province"),
default_container = "Arab Saudi",
default_placetype = "wilayah",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, Afrika Selatan"] = {the = true},
["Free State, Afrika Selatan"] = {the = true, wp = "%l (province)"},
["Gauteng, Afrika Selatan"] = {},
["KwaZulu-Natal, Afrika Selatan"] = {},
["Limpopo, Afrika Selatan"] = {},
["Mpumalanga, Afrika Selatan"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, Afrika Selatan"] = {wp = "%l (South African province)"},
["Northern Cape, Afrika Selatan"] = {the = true},
["Western Cape, Afrika Selatan"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "Afrika Selatan",
default_placetype = "province",
default_divs = "municipalities",
data = export.south_africa_provinces,
}
export.south_korea_provinces = {
["North Chungcheong Province, South Korea"] = {},
["South Chungcheong Province, South Korea"] = {},
["Gangwon Province, South Korea"] = {wp = "%l, %c"},
["Gyeonggi Province, South Korea"] = {},
["North Gyeongsang Province, South Korea"] = {},
["South Gyeongsang Province, South Korea"] = {},
["North Jeolla Province, South Korea"] = {},
["South Jeolla Province, South Korea"] = {},
["Jeju Province, South Korea"] = {},
}
-- provinces of South Korea
export.south_korea_group = {
key_to_placename = make_key_to_placename(", South Korea$", " Province$"),
placename_to_key = make_placename_to_key(", South Korea", " Province"),
default_container = "South Korea",
default_placetype = "province",
data = export.south_korea_provinces,
}
export.spain_autonomous_communities = {
["Andalusia, Spain"] = {},
["Aragon, Spain"] = {},
["Asturias, Spain"] = {},
["Balearic Islands, Spain"] = {the = true},
["Basque Country, Spain"] = {the = true, wp = "%l (autonomous community)"},
["Canary Islands, Spain"] = {the = true},
["Cantabria, Spain"] = {},
["Castile and León, Spain"] = {},
["Castilla-La Mancha, Spain"] = {wp = "Castilla–La Mancha"}, -- with en-dash
["Catalonia, Spain"] = {},
["Community of Madrid, Spain"] = {the = true},
["Extremadura, Spain"] = {},
["Galicia, Spain"] = {wp = "%l (Spain)"},
["La Rioja, Spain"] = {},
["Murcia, Spain"] = {wp = "Region of %l"},
["Navarre, Spain"] = {},
["Valencia, Spain"] = {wp = "Valencian Community"},
["Valencian Community, Spain"] = {alias_of = "Valencia, Spain", the = true},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Spain",
default_placetype = "autonomous community",
default_divs = {"municipalities", "comarcas"},
data = export.spain_autonomous_communities,
}
export.taiwan_counties = {
["Changhua County, Taiwan"] = {},
["Chiayi County, Taiwan"] = {},
["Hsinchu County, Taiwan"] = {},
["Hualien County, Taiwan"] = {},
["Kinmen County, Taiwan"] = {wp = "Kinmen"},
["Lienchiang County, Taiwan"] = {wp = "Matsu Islands"},
["Miaoli County, Taiwan"] = {},
["Nantou County, Taiwan"] = {},
["Penghu County, Taiwan"] = {wp = "Penghu"},
["Pingtung County, Taiwan"] = {},
["Taitung County, Taiwan"] = {},
["Yilan County, Taiwan"] = {wp = "%l, %c"},
["Yunlin County, Taiwan"] = {},
}
-- counties of Taiwan
export.taiwan_group = {
key_to_placename = make_key_to_placename(", Taiwan$", " County$"),
placename_to_key = make_placename_to_key(", Taiwan", " County"),
default_container = "Taiwan",
default_placetype = "kaunti",
default_divs = {"daerah", "townships"},
data = export.taiwan_counties,
}
export.thailand_provinces = {
-- Bangkok (special administrative area)
["Amnat Charoen Province, Thailand"] = {},
["Ang Thong Province, Thailand"] = {},
["Bueng Kan Province, Thailand"] = {},
["Buriram Province, Thailand"] = {},
["Chachoengsao Province, Thailand"] = {},
["Chai Nat Province, Thailand"] = {},
["Chaiyaphum Province, Thailand"] = {},
["Chanthaburi Province, Thailand"] = {},
["Chiang Mai Province, Thailand"] = {},
["Chiang Rai Province, Thailand"] = {},
["Chonburi Province, Thailand"] = {},
["Chumphon Province, Thailand"] = {},
["Kalasin Province, Thailand"] = {},
["Kamphaeng Phet Province, Thailand"] = {},
["Kanchanaburi Province, Thailand"] = {},
["Khon Kaen Province, Thailand"] = {},
["Krabi Province, Thailand"] = {},
["Lampang Province, Thailand"] = {},
["Lamphun Province, Thailand"] = {},
["Loei Province, Thailand"] = {},
["Lopburi Province, Thailand"] = {},
["Mae Hong Son Province, Thailand"] = {},
["Maha Sarakham Province, Thailand"] = {},
["Mukdahan Province, Thailand"] = {},
["Nakhon Nayok Province, Thailand"] = {},
["Nakhon Pathom Province, Thailand"] = {},
["Nakhon Phanom Province, Thailand"] = {},
["Nakhon Ratchasima Province, Thailand"] = {},
["Nakhon Sawon Province, Thailand"] = {},
["Nakhon Si Thammarat Province, Thailand"] = {},
["Nan Province, Thailand"] = {},
["Narathiwat Province, Thailand"] = {},
["Nong Bua Lamphu Province, Thailand"] = {},
["Nong Khai Province, Thailand"] = {},
["Nonthaburi Province, Thailand"] = {},
["Pathum Thani Province, Thailand"] = {},
["Pattani Province, Thailand"] = {},
["Phang Nga Province, Thailand"] = {},
["Phatthalung Province, Thailand"] = {},
["Phayao Province, Thailand"] = {},
["Phetchabun Province, Thailand"] = {},
["Phetchaburi Province, Thailand"] = {},
["Phichit Province, Thailand"] = {},
["Phitsanulok Province, Thailand"] = {},
["Phra Nakhon Si Ayutthaya Province, Thailand"] = {},
["Phrae Province, Thailand"] = {},
["Phuket Province, Thailand"] = {},
["Prachinburi Province, Thailand"] = {},
["Prachuap Khiri Khan Province, Thailand"] = {},
["Ranong Province, Thailand"] = {},
["Ratchaburi Province, Thailand"] = {},
["Rayong Province, Thailand"] = {},
["Roi Et Province, Thailand"] = {},
["Sa Kaeo Province, Thailand"] = {},
["Sakon Nakhon Province, Thailand"] = {},
["Samut Prakan Province, Thailand"] = {},
["Samut Sakhon Province, Thailand"] = {},
["Samut Songkhram Province, Thailand"] = {},
["Saraburi Province, Thailand"] = {},
["Satun Province, Thailand"] = {},
["Sing Buri Province, Thailand"] = {},
["Sisaket Province, Thailand"] = {},
["Songkhla Province, Thailand"] = {},
["Sukhothai Province, Thailand"] = {},
["Suphan Buri Province, Thailand"] = {},
["Surat Thani Province, Thailand"] = {},
["Surin Province, Thailand"] = {},
["Tak Province, Thailand"] = {},
["Trang Province, Thailand"] = {},
["Trat Province, Thailand"] = {},
["Ubon Ratchathani Province, Thailand"] = {},
["Udon Thani Province, Thailand"] = {},
["Uthai Thani Province, Thailand"] = {},
["Uttaradit Province, Thailand"] = {},
["Yala Province, Thailand"] = {},
["Yasothon Province, Thailand"] = {},
}
-- provinces of Thailand
export.thailand_group = {
key_to_placename = make_key_to_placename(", Thailand$", "Wilayah "),
placename_to_key = make_placename_to_key(", Thailand", "Wilayah "),
default_container = "Thailand",
default_placetype = "wilayah",
default_divs = "daerah",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "Wilayah %e",
data = export.thailand_provinces,
}
export.turkey_provinces = {
["Adana Province, Turkey"] = {}, -- code 01
["Adıyaman Province, Turkey"] = {}, -- code 02
["Afyonkarahisar Province, Turkey"] = {}, -- code 03
["Ağrı Province, Turkey"] = {}, -- code 04
["Amasya Province, Turkey"] = {}, -- code 05
["Ankara Province, Turkey"] = {}, -- code 06
["Antalya Province, Turkey"] = {}, -- code 07
["Artvin Province, Turkey"] = {}, -- code 08
["Aydın Province, Turkey"] = {}, -- code 09
["Balıkesir Province, Turkey"] = {}, -- code 10
["Bilecik Province, Turkey"] = {}, -- code 11
["Bingöl Province, Turkey"] = {}, -- code 12
["Bitlis Province, Turkey"] = {}, -- code 13
["Bolu Province, Turkey"] = {}, -- code 14
["Burdur Province, Turkey"] = {}, -- code 15
["Bursa Province, Turkey"] = {}, -- code 16
["Çanakkale Province, Turkey"] = {}, -- code 17
["Çankırı Province, Turkey"] = {}, -- code 18
["Çorum Province, Turkey"] = {}, -- code 19
["Denizli Province, Turkey"] = {}, -- code 20
["Diyarbakır Province, Turkey"] = {}, -- code 21
["Edirne Province, Turkey"] = {}, -- code 22
["Elazığ Province, Turkey"] = {}, -- code 23
["Elâzığ Province, Turkey"] = {alias_of = "Elazığ Province, Turkey", display = true},
["Erzincan Province, Turkey"] = {}, -- code 24
["Erzurum Province, Turkey"] = {}, -- code 25
["Eskişehir Province, Turkey"] = {}, -- code 26
["Gaziantep Province, Turkey"] = {}, -- code 27
["Giresun Province, Turkey"] = {}, -- code 28
["Gümüşhane Province, Turkey"] = {}, -- code 29
["Hakkâri Province, Turkey"] = {}, -- code 30
["Hakkari Province, Turkey"] = {alias_of = "Hakkâri Province, Turkey", display = true},
["Hatay Province, Turkey"] = {}, -- code 31
["Isparta Province, Turkey"] = {}, -- code 32
["Mersin Province, Turkey"] = {}, -- code 33
-- ["Istanbul Province, Turkey"] = {}, -- code 34; this is coextensive with the city itself
["İzmir Province, Turkey"] = {}, -- code 35
["Izmir Province, Turkey"] = {alias_of = "İzmir Province, Turkey", display = true},
["Kars Province, Turkey"] = {}, -- code 36
["Kastamonu Province, Turkey"] = {}, -- code 37
["Kayseri Province, Turkey"] = {}, -- code 38
["Kırklareli Province, Turkey"] = {}, -- code 39
["Kırşehir Province, Turkey"] = {}, -- code 40
["Kocaeli Province, Turkey"] = {}, -- code 41
["Konya Province, Turkey"] = {}, -- code 42
["Kütahya Province, Turkey"] = {}, -- code 43
["Malatya Province, Turkey"] = {}, -- code 44
["Manisa Province, Turkey"] = {}, -- code 45
["Kahramanmaraş Province, Turkey"] = {}, -- code 46
["Mardin Province, Turkey"] = {}, -- code 47
["Muğla Province, Turkey"] = {}, -- code 48
["Muş Province, Turkey"] = {}, -- code 49
["Nevşehir Province, Turkey"] = {}, -- code 50
["Niğde Province, Turkey"] = {}, -- code 51
["Ordu Province, Turkey"] = {}, -- code 52
["Rize Province, Turkey"] = {}, -- code 53
["Sakarya Province, Turkey"] = {}, -- code 54
["Samsun Province, Turkey"] = {}, -- code 55
["Siirt Province, Turkey"] = {}, -- code 56
["Sinop Province, Turkey"] = {}, -- code 57
["Sivas Province, Turkey"] = {}, -- code 58
["Tekirdağ Province, Turkey"] = {}, -- code 59
["Tokat Province, Turkey"] = {}, -- code 60
["Trabzon Province, Turkey"] = {}, -- code 61
["Tunceli Province, Turkey"] = {}, -- code 62
["Şanlıurfa Province, Turkey"] = {}, -- code 63
["Uşak Province, Turkey"] = {}, -- code 64
["Van Province, Turkey"] = {}, -- code 65
["Yozgat Province, Turkey"] = {}, -- code 66
["Zonguldak Province, Turkey"] = {}, -- code 67
["Aksaray Province, Turkey"] = {}, -- code 68
["Bayburt Province, Turkey"] = {}, -- code 69
["Karaman Province, Turkey"] = {}, -- code 70
["Kırıkkale Province, Turkey"] = {}, -- code 71
["Batman Province, Turkey"] = {}, -- code 72
["Şırnak Province, Turkey"] = {}, -- code 73
["Bartın Province, Turkey"] = {}, -- code 74
["Ardahan Province, Turkey"] = {}, -- code 75
["Iğdır Province, Turkey"] = {}, -- code 76
["Yalova Province, Turkey"] = {}, -- code 77
["Karabük Province, Turkey"] = {}, -- code 78
["Kilis Province, Turkey"] = {}, -- code 79
["Osmaniye Province, Turkey"] = {}, -- code 80
["Düzce Province, Turkey"] = {}, -- code 81
}
-- provinces of Turkey
export.turkey_group = {
key_to_placename = make_key_to_placename(", Turkey$", " Province$"),
placename_to_key = make_placename_to_key(", Turkey", " Province"),
default_container = "Turkey",
default_placetype = "province",
default_divs = "daerah",
data = export.turkey_provinces,
}
export.ukraine_oblasts = {
["Cherkasy Oblast, Ukraine"] = {}, -- capital [[Cherkasy]], license plate prefix CA, IA
["Chernihiv Oblast, Ukraine"] = {}, -- capital [[Chernihiv]], license plate prefix CB, IB
["Chernivtsi Oblast, Ukraine"] = {}, -- capital [[Chernivtsi]], license plate prefix CE, IE
-- apparently will be renamed to 'Dnipro Oblast'
["Dnipropetrovsk Oblast, Ukraine"] = {}, -- capital [[Dnipro]], license plate prefix AE, KE
["Donetsk Oblast, Ukraine"] = {}, -- capital ''[[Donetsk]] ([[Kramatorsk]])'', license plate prefix AH, KH
["Ivano-Frankivsk Oblast, Ukraine"] = {}, -- capital [[Ivano-Frankivsk]], license plate prefix AT, KT
["Kharkiv Oblast, Ukraine"] = {}, -- capital [[Kharkiv]], license plate prefix AX, KX
["Kherson Oblast, Ukraine"] = {}, -- capital ''[[Kherson]]'', license plate prefix ''BT, HT''
["Khmelnytskyi Oblast, Ukraine"] = {}, -- capital [[Khmelnytskyi]], license plate prefix BX, HX
-- apparently will be renamed to 'Kropyvnytskyi Oblast'
["Kirovohrad Oblast, Ukraine"] = {}, -- capital [[Kropyvnytskyi]], license plate prefix BA, HA
["Kyiv Oblast, Ukraine"] = {}, -- capital [[Kyiv]], license plate prefix AI, KI
["Kiev Oblast, Ukraine"] = {alias_of = "Kyiv Oblast, Ukraine", display = true},
["Luhansk Oblast, Ukraine"] = {}, -- capital ''[[Luhansk]] ([[Sievierodonetsk]])'', license plate prefix BB, HB
["Lviv Oblast, Ukraine"] = {}, -- capital [[Lviv]], license plate prefix BC, HC
["Mykolaiv Oblast, Ukraine"] = {}, -- capital [[Mykolaiv]], license plate prefix BE, HE
["Odesa Oblast, Ukraine"] = {}, -- capital [[Odesa]], license plate prefix BH, HH
["Odessa Oblast, Ukraine"] = {alias_of = "Odesa Oblast, Ukraine", display = true},
["Poltava Oblast, Ukraine"] = {}, -- capital [[Poltava]], license plate prefix BI, HI
["Rivne Oblast, Ukraine"] = {}, -- capital [[Rivne]], license plate prefix BK, HK
["Sumy Oblast, Ukraine"] = {}, -- capital [[Sumy]], license plate prefix BM, HM
["Ternopil Oblast, Ukraine"] = {}, -- capital [[Ternopil]], license plate prefix BO, HO
["Vinnytsia Oblast, Ukraine"] = {}, -- capital [[Vinnytsia]], license plate prefix AB, KB
["Volyn Oblast, Ukraine"] = {}, -- capital [[Lutsk]], license plate prefix AC, KC
["Zakarpattia Oblast, Ukraine"] = {}, -- capital [[Uzhhorod]], license plate prefix AO, KO
["Zaporizhzhia Oblast, Ukraine"] = {}, -- capital ''[[Zaporizhzhia]]'', license plate prefix AP, KP
["Zaporizhia Oblast, Ukraine"] = {alias_of = "Zaporizhzhia Oblast, Ukraine", display = true},
["Zhytomyr Oblast, Ukraine"] = {}, -- capital [[Zhytomyr]], license plate prefix AM, KM
}
-- oblasts of Ukraine
export.ukraine_group = {
key_to_placename = make_key_to_placename(", Ukraine$", " Oblast$"),
placename_to_key = make_placename_to_key(", Ukraine", " Oblast"),
default_container = "Ukraine",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"kaunti",
"daerah",
{type = "local government districts", cat_as = "daerah"},
{
type = "local government districts with borough status",
cat_as = {"daerah", "boroughs"},
},
{type = "boroughs", cat_as = {"daerah", "boroughs"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"negara bahagian", "province", "negara"},
divs = {"kaunti", "daerah"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"daerah",
}},
["Wales"] = {divs = {
"kaunti",
{type = "county boroughs", container_parent_type = false},
{type = "communities", container_parent_type = false},
{type = "Welsh communities", cat_as = {{type = "communities", container_parent_type = false}}},
}},
}
-- constituent countries and provinces of the United Kingdom
export.united_kingdom_group = {
placename_to_key = false,
default_container = "United Kingdom",
default_placetype = {"negara bahagian", "negara"},
addl_divs = {
"traditional counties",
{type = "historical counties", cat_as = "traditional counties"},
},
-- Don't create categories like 'Category:en:Towns in the United Kingdom'
-- or 'Category:en:Places in the United Kingdom'.
default_no_container_cat = true,
data = export.united_kingdom_constituent_countries,
}
export.england_counties = {
-- NOTE: We used to have various other "no longer" counties commented out, which seems to refer to counties that
-- existed officially at some point between 1889 and 1974, which I have removed. I have only kept the three
-- ceremonial counties that existed from 1974 (when ceremonial counties were created) to 1996, as well as those
-- still considered "historic counties" per [[w:Historic counties of England]].
-- ["Avon, England"] = {wp = "%l (county)"}, -- no longer (1974 to 1996)
["Bedfordshire, England"] = {},
["Berkshire, England"] = {},
-- ["Brighton and Hove, England"] = {}, -- city
-- ["Bristol, England"] = {}, -- city
["Buckinghamshire, England"] = {},
["Cambridgeshire, England"] = {},
["Cheshire, England"] = {},
-- ["Cleveland, England"] = {wp = "%l (county)"}, -- no longer (1974 to 1996)
["Cornwall, England"] = {},
-- ["Cumberland, England"] = {}, -- no longer (historic county)
["Cumbria, England"] = {},
["Derbyshire, England"] = {},
["Devon, England"] = {},
["Dorset, England"] = {},
["County Durham, England"] = {},
["East Sussex, England"] = {},
["Essex, England"] = {},
["Gloucestershire, England"] = {},
["Greater London, England"] = {},
["Greater Manchester, England"] = {},
["Hampshire, England"] = {},
["Herefordshire, England"] = {},
["Hertfordshire, England"] = {},
-- ["Humberside, England"] = {}, -- no longer (1974 to 1996)
-- ["Huntingdonshire, England"] = {}, -- no longer (historic county)
["Isle of Wight, England"] = {the = true},
["Kent, England"] = {},
["Lancashire, England"] = {},
["Leicestershire, England"] = {},
["Lincolnshire, England"] = {},
["Merseyside, England"] = {},
-- ["Middlesex, England"] = {}, -- no longer (historic county)
["Norfolk, England"] = {},
["Northamptonshire, England"] = {},
["Northumberland, England"] = {},
["North Yorkshire, England"] = {},
["Nottinghamshire, England"] = {},
["Oxfordshire, England"] = {},
["Rutland, England"] = {},
["Shropshire, England"] = {},
["Somerset, England"] = {},
["South Humberside, England"] = {},
["South Yorkshire, England"] = {},
["Staffordshire, England"] = {},
["Suffolk, England"] = {},
["Surrey, England"] = {},
-- ["Sussex, England"] = {}, -- no longer (historic county)
["Tyne and Wear, England"] = {},
["Warwickshire, England"] = {},
["West Midlands, England"] = {the = true, wp = "%l (county)"},
-- ["Westmorland, England"] = {}, -- no longer (historic county)
["West Sussex, England"] = {},
["West Yorkshire, England"] = {},
["Wiltshire, England"] = {},
["Worcestershire, England"] = {},
-- ["Yorkshire, England"] = {}, -- no longer (historic county)
["East Riding of Yorkshire, England"] = {the = true},
}
-- counties of England
export.england_group = {
default_container = {key = "England", placetype = "negara bahagian"},
default_placetype = "kaunti",
default_divs = {
"daerah",
{type = "local government districts", cat_as = "daerah"},
{
type = "local government districts with borough status",
cat_as = {"daerah", "boroughs"},
},
{type = "boroughs", cat_as = {"daerah", "boroughs"}},
"civil parishes",
},
data = export.england_counties,
}
export.northern_ireland_counties = {
["County Antrim, Northern Ireland"] = {},
["County Armagh, Northern Ireland"] = {},
["City of Belfast, Northern Ireland"] = {the = true, is_city = true, wp = "Belfast"},
["County Down, Northern Ireland"] = {},
["County Fermanagh, Northern Ireland"] = {},
["County Londonderry, Northern Ireland"] = {},
["City of Derry, Northern Ireland"] = {the = true, is_city = true, wp = "Derry"},
["County Tyrone, Northern Ireland"] = {},
}
-- counties of Northern Ireland
export.northern_ireland_group = {
key_to_placename = make_irish_type_key_to_placename(", Northern Ireland$"),
placename_to_key = make_irish_type_placename_to_key(", Northern Ireland"),
default_container = {key = "Northern Ireland", placetype = "negara bahagian"},
default_placetype = "kaunti",
data = export.northern_ireland_counties,
}
export.scotland_council_areas = {
["Aberdeenshire, Scotland"] = {},
["Angus, Scotland"] = {wp = "%l, %c"},
["Argyll and Bute, Scotland"] = {},
["City of Aberdeen, Scotland"] = {the = true, wp = "Aberdeen"},
["Aberdeen"] = {alias_of = "City of Aberdeen, Scotland"},
["Aberdeen City"] = {alias_of = "City of Aberdeen, Scotland"},
["City of Dundee, Scotland"] = {the = true, wp = "Dundee"},
["Dundee"] = {alias_of = "City of Dundee, Scotland"},
["Dundee City"] = {alias_of = "City of Dundee, Scotland"},
["City of Edinburgh, Scotland"] = {the = true, wp = "%l council area"},
["Edinburgh"] = {alias_of = "City of Edinburgh, Scotland"},
["City of Glasgow, Scotland"] = {the = true, wp = "Glasgow"},
["Glasgow"] = {alias_of = "City of Glasgow, Scotland"},
["Clackmannanshire, Scotland"] = {},
["Dumfries and Galloway, Scotland"] = {},
["East Ayrshire, Scotland"] = {},
["East Dunbartonshire, Scotland"] = {},
["East Lothian, Scotland"] = {},
["East Renfrewshire, Scotland"] = {},
["Falkirk, Scotland"] = {wp = "%l council area"},
["Fife, Scotland"] = {},
["Highland, Scotland"] = {wp = "%l council area"},
["Inverclyde, Scotland"] = {},
["Midlothian, Scotland"] = {},
["Moray, Scotland"] = {},
["North Ayrshire, Scotland"] = {},
["North Lanarkshire, Scotland"] = {},
["Orkney Islands, Scotland"] = {the = true},
["Perth and Kinross, Scotland"] = {},
["Renfrewshire, Scotland"] = {},
["Scottish Borders, Scotland"] = {the = true},
["Shetland Islands, Scotland"] = {the = true},
["South Ayrshire, Scotland"] = {},
["South Lanarkshire, Scotland"] = {},
["Stirling, Scotland"] = {wp = "%l council area"},
["West Dunbartonshire, Scotland"] = {},
["West Lothian, Scotland"] = {},
["Western Isles, Scotland"] = {the = true, wp = "Outer Hebrides"},
["Na h-Eileanan Siar, Scotland"] = {alias_of = "Western Isles, Scotland"},
}
-- council areas of Scotland
export.scotland_group = {
default_container = {key = "Scotland", placetype = "negara bahagian"},
default_placetype = "council area",
data = export.scotland_council_areas,
}
export.wales_principal_areas = {
["Blaenau Gwent, Wales"] = {},
["Bridgend, Wales"] = {wp = "%l County Borough"},
["Caerphilly, Wales"] = {wp = "%l County Borough"},
-- ["Cardiff, Wales"] = {placetype = "bandar"},
["Carmarthenshire, Wales"] = {placetype = "kaunti"},
["Ceredigion, Wales"] = {placetype = "kaunti"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "kaunti"},
["Flintshire, Wales"] = {placetype = "kaunti"},
["Gwynedd, Wales"] = {placetype = "kaunti"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "kaunti"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "kaunti"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "bandar", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "kaunti"},
["Powys, Wales"] = {placetype = "kaunti"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "bandar"},
["Torfaen, Wales"] = {},
["Vale of Glamorgan, Wales"] = {the = true},
["Wrexham, Wales"] = {wp = "%l County Borough"},
}
-- principal areas (cities, counties and county boroughs) of Wales
export.wales_group = {
default_container = {key = "Wales", placetype = "negara bahagian"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "kaunti"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"kaunti", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"kaunti", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polinesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "kaunti"},
{type = "parish seats", container_parent_type = "county seats"},
}},
["Maine, USA"] = {},
["Maryland, USA"] = {},
["Massachusetts, USA"] = {},
["Michigan, USA"] = {},
["Minnesota, USA"] = {},
["Mississippi, USA"] = {},
["Missouri, USA"] = {},
["Montana, USA"] = {},
["Nebraska, USA"] = {},
["Nevada, USA"] = {},
["New Hampshire, USA"] = {},
["New Jersey, USA"] = {divs = {
"kaunti", "county seats",
{type = "boroughs", prep = "di"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"kaunti", "county seats",
{type = "boroughs", prep = "di"},
}},
["Rhode Island, USA"] = {},
["South Carolina, USA"] = {},
["South Dakota, USA"] = {},
["Tennessee, USA"] = {},
["Texas, USA"] = {},
["Utah, USA"] = {},
["Vermont, USA"] = {},
["Virginia, USA"] = {},
["Washington, USA"] = {wp = "%l (state)"},
["West Virginia, USA"] = {},
["Wisconsin, USA"] = {},
["Wyoming, USA"] = {},
}
-- states of the United States
export.united_states_group = {
placename_to_key = make_placename_to_key(", USA"),
default_container = "Amerika Syarikat",
default_placetype = "negeri",
default_divs = {"kaunti", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "di"},
{type = "unincorporated communities", prep = "di"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang Province, Vietnam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn Province, Vietnam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng Province, Vietnam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang Province, Vietnam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn Province, Vietnam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ Province, Vietnam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh Province, Vietnam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên Province, Vietnam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang Province, Vietnam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai Province, Vietnam"] = {}, -- capital [[Lào Cai]]
["Yên Bái Province, Vietnam"] = {}, -- capital [[Yên Bái]]
["Điện Biên Province, Vietnam"] = {}, -- capital [[Điện Biên Phủ]]
["Hoà Bình Province, Vietnam"] = {}, -- capital [[Hoà Bình City|Hoà Bình]]
["Hòa Bình Province, Vietnam"] = {alias_of = "Hoà Bình Province, Vietnam", display = true},
["Lai Châu Province, Vietnam"] = {}, -- capital [[Lai Châu]]
["Sơn La Province, Vietnam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh Province, Vietnam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam Province, Vietnam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương Province, Vietnam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên Province, Vietnam"] = {}, -- capital [[Hưng Yên]]
["Nam Định Province, Vietnam"] = {}, -- capital [[Nam Định]]
["Ninh Bình Province, Vietnam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình Province, Vietnam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc Province, Vietnam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "bandar"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "bandar"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh Province, Vietnam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An Province, Vietnam"] = {}, -- capital [[Vinh]]
["Quảng Bình Province, Vietnam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị Province, Vietnam"] = {}, -- capital [[Đông Hà]]
["Thanh Hoá Province, Vietnam"] = {}, -- capital [[Thanh Hoá]]
["Thanh Hóa Province, Vietnam"] = {alias_of = "Thanh Hoá Province, Vietnam", display = true},
-- ["Hue"] = {placetype = {"municipality", "bandar"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk Province, Vietnam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông Province, Vietnam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai Province, Vietnam"] = {}, -- capital [[Pleiku]]
["Kon Tum Province, Vietnam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng Province, Vietnam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định Province, Vietnam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận Province, Vietnam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hoà Province, Vietnam"] = {}, -- capital [[Nha Trang]]
["Khánh Hòa Province, Vietnam"] = {alias_of = "Khánh Hoà Province, Vietnam", display = true},
["Ninh Thuận Province, Vietnam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên Province, Vietnam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam Province, Vietnam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi Province, Vietnam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "bandar"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu Province, Vietnam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương Province, Vietnam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước Province, Vietnam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai Province, Vietnam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh Province, Vietnam"] = {}, -- capital [[Tây Ninh]]
-- ["Ho Chi Minh City"] = {placetype = {"municipality", "bandar"}}, -- capital [[District 1, Ho Chi Minh City|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang Province, Vietnam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu Province, Vietnam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre Province, Vietnam"] = {}, -- capital [[Bến Tre]]
["Cà Mau Province, Vietnam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp Province, Vietnam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang Province, Vietnam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang Province, Vietnam"] = {}, -- capital [[Rạch Giá]]
["Long An Province, Vietnam"] = {}, -- capital [[Tân An]]
["Sóc Trăng Province, Vietnam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang Province, Vietnam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh Province, Vietnam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long Province, Vietnam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "bandar"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Vietnam$", " Province$"),
placename_to_key = make_placename_to_key(", Vietnam", " Province"),
default_container = "Vietnam",
default_placetype = "province",
-- There may not be enough districts to subcategorize like this.
-- default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
data = export.vietnam_provinces,
}
-----------------------------------------------------------------------------------
-- City data --
-----------------------------------------------------------------------------------
export.australia_cities = {
["Adelaide"] = {container = "South Australia"}, -- 1,450,000 (Agglomeration)
["Brisbane"] = {container = "Queensland"}, -- 3,450,000 (Conglomeration; including the Gold Coast [750,997 2024 estiamte])
["Canberra"] = {container = {key = "Australian Capital Territory, Australia", placetype = "territory"}}, -- 510,641 (2024 estimate)
["Melbourne"] = {container = "Victoria"}, -- 5,200,000 (Agglomeration)
["Newcastle, New South Wales"] = {container = "New South Wales", wp = "%l, %c"}, -- 534,033 (2024 estimate)
["Newcastle"] = {alias_of = "Newcastle, New South Wales"},
["Perth"] = {container = "Western Australia"}, -- 2,350,000 (Agglomeration)
["Sydney"] = {container = "New South Wales"}, -- 5,100,000 (Agglomeration)
}
export.australia_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Australia", "negeri"),
default_placetype = "bandar",
data = export.australia_cities,
}
export.brazil_cities = {
-- Figures from citypopulation.de; retrieved 2025-04-27; reference date 2025-01-01.
["São Paulo"] = {container = "São Paulo"}, -- 22,600,000 (Consolidated Urban Area; including Guarulhos)
["Sao Paulo"] = {alias_of = "São Paulo", display = true},
["Rio de Janeiro"] = {container = "Rio de Janeiro"}, -- 13,600,000 (Consolidated Urban Area)
["Belo Horizonte"] = {container = "Minas Gerais"}, -- 5,300,000
["Recife"] = {container = "Pernambuco"}, -- 4,100,000
["Porto Alegre"] = {container = "Rio Grande do Sul"}, -- 3,950,000 (Consolidated Urban Area)
["Brasília"] = {container = "Distrito Federal"}, -- 3,850,000
["Brasilia"] = {alias_of = "Brasília", display = true},
["Fortaleza"] = {container = "Ceará"}, -- 3,825,000
["Salvador"] = {container = "Bahia", wp = "%l, %c", commonscat = "%l (%c)"}, -- 3,400,000
["Curitiba"] = {container = "Paraná"}, -- 3,375,000
["Campinas"] = {container = "São Paulo"}, -- 3,250,000
["Goiânia"] = {container = "Goiás"}, -- 2,525,000
["Goiania"] = {alias_of = "Goiânia", display = true},
["Manaus"] = {container = "Amazonas"}, -- 2,275,000
["Belém"] = {container = "Pará"}, -- 2,200,000
["Belem"] = {alias_of = "Belém", display = true},
["Vitória"] = {container = "Espírito Santo", wp = "%l, %c"}, -- 1,870,000
["Vitoria"] = {alias_of = "Vitória", display = true},
["Santos"] = {container = "São Paulo", wp = "%l, %c"}, -- 1,760,000
["São Luís"] = {container = "Maranhão", wp = "%l, %c"}, -- 1,530,000
["Sao Luis"] = {alias_of = "São Luís", display = true},
["Natal"] = {container = "Rio Grande do Norte", wp = "%l, %c"}, -- 1,360,000
["Florianópolis"] = {container = "Santa Catarina"}, -- 1,260,000
["Florianopolis"] = {alias_of = "Florianópolis", display = true},
["Maceió"] = {container = "Alagoas"}, -- 1,220,000
["Maceio"] = {alias_of = "Maceió", display = true},
["João Pessoa"] = {container = "Paraíba", wp = "%l, %c"}, -- 1,210,000
["Joao Pessoa"] = {alias_of = "João Pessoa", display = true},
["São José dos Campos"] = {container = "São Paulo"}, -- 1,090,000
["Sao Jose dos Campos"] = {alias_of = "São José dos Campos", display = true},
["Londrina"] = {container = "Paraná"}, -- 1,050,000
["Teresina"] = {container = "Piauí"}, -- 1,040,000
}
export.brazil_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Brazil", "negeri"),
default_placetype = "bandar",
data = export.brazil_cities,
}
export.canada_cities = {
-- Figures from citypopulation.de; retrieved 2025-04-27; reference date 2025-01-01.
["Toronto"] = {container = "Ontario"}, -- 7,850,000 (Consolidated Urban Area; including Hamilton)
["Montreal"] = {container = "Quebec"}, -- 4,500,000 (Consolidated Urban Area)
["Vancouver"] = {container = "British Columbia"}, -- 3,175,000 (Consolidated Urban Area)
["Calgary"] = {container = "Alberta"}, -- 1,510,000 (Consolidated Urban Area)
["Edmonton"] = {container = "Alberta"}, -- 1,460,000 (Consolidated Urban Area)
["Ottawa"] = {container = "Ontario"}, -- 1,390,000 (Consolidated Urban Area)
["Quebec City"] = {container = "Quebec"}, -- 839,311 metro per Wikipedia (2021 census)
["Winnipeg"] = {container = "Manitoba"}, -- 834,678 metro per Wikipedia (2021 census)
["Hamilton"] = {container = "Ontario", wp = "%l, %c"}, -- 785,184 metro per Wikipedia (2021 census)
["Kitchener"] = {container = "Ontario", wp = "%l, %c"}, -- 575,847 metro per Wikipedia (2021 census)
}
export.canada_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Canada", "province"),
default_placetype = "bandar",
data = export.canada_cities,
}
export.france_cities = {
-- Figures from citypopulation.de unless otherwise indicated; retrieved 2025-04-26; reference date 2025-01-01.
["Paris"] = {container = "Île-de-France"}, -- 11,500,000 (Conglomeration)
["Lyon"] = {container = "Auvergne-Rhône-Alpes"}, -- 2,050,000 (Conglomeration)
["Lyons"] = {alias_of = "Lyon", display = true},
["Marseille"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 1,710,000 (Conglomeration)
["Marseilles"] = {alias_of = "Marseille", display = true},
["Lille"] = {container = "Hauts-de-France"}, -- 1,320,000 (Conglomeration)
["Bordeaux"] = {container = "Nouvelle-Aquitaine"}, -- 1,160,000 (Conglomeration)
["Toulouse"] = {container = "Occitania"}, -- 1,150,000 (Conglomeration)
["Nice"] = {container = "Provence-Alpes-Côte d'Azur"},
["Nantes"] = {container = "Pays de la Loire"},
["Strasbourg"] = {container = "Grand Est"},
["Rennes"] = {container = "Brittany"},
}
export.france_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", France", "wilayah"),
default_placetype = "bandar",
data = export.france_cities,
}
export.germany_cities = {
-- Figures from citypopulation.de unless otherwise indicated; retrieved 2025-04-26; reference date 2025-01-01.
-- listed under Rhein-Ruhr Area, total population 10,900,000 (Consolidated Urban Area)
["Cologne"] = {container = "North Rhine-Westphalia"},
["Köln"] = {alias_of = "Cologne", display = true},
["Düsseldorf"] = {container = "North Rhine-Westphalia"},
["Dusseldorf"] = {alias_of = "Düsseldorf", display = true},
["Dortmund"] = {container = "North Rhine-Westphalia"},
["Essen"] = {container = "North Rhine-Westphalia"},
["Duisberg"] = {container = "North Rhine-Westphalia"},
["Berlin"] = {}, -- 4,700,000
["Frankfurt"] = {container = "Hesse"}, -- 3,225,000
["Frankfurt am Main"] = {alias_of = "Frankfurt"}, -- not a display alias as it's longer
["Hamburg"] = {}, -- 2,900,000
["Munich"] = {container = "Bavaria"}, -- 2,300,000
["Stuttgart"] = {container = "Baden-Württemberg"}, -- 2,300,000
["Mannheim"] = {container = "Baden-Württemberg"}, -- 1,550,000
["Nuremberg"] = {container = "Bavaria"}, -- 1,120,000
["Hanover"] = {"Lower Saxony"}, -- 1,090,000
["Bielefeld"] = {container = "North Rhine-Westphalia"}, -- 1,080,000
["Leipzig"] = {container = "Saxony"}, -- 1,080,000
["Aachen"] = {container = "North Rhine-Westphalia"}, -- 1,000,000
["Aix-la-Chapelle"] = {alias_of = "Aachen"}, -- historical; not a display alias
["Bremen"] = {},
}
export.germany_cities_group = {
default_container = "Germany",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "negeri"),
default_placetype = "bandar",
data = export.germany_cities,
}
export.india_cities = {
-- This lists the 65 metro areas per Demographia's 2023 estimates, as found in
-- [[w:List_of_million-plus_urban_agglomerations_in_India]]. The last census in India (as of April 2025) was
-- conducted in 2011, and the results are not accurate any more.
["Delhi"] = {container = {key = "Delhi, India", placetype = "union territory"}}, -- 31,190,000
["Mumbai"] = {container = "Maharashtra"}, -- 25,189,000
["Kolkata"] = {container = "West Bengal"}, -- 21,747,000
["Bangalore"] = {container = "Karnataka", wp = "Bengaluru"}, -- 15,257,000
["Bengaluru"] = {alias_of = "Bangalore"},
["Chennai"] = {container = "Tamil Nadu"}, -- 11,570,000
["Hyderabad"] = {container = "Telangana"}, -- 9,797,000
["Ahmedabad"] = {container = "Gujarat"}, -- 8,006,000
["Pune"] = {container = "Maharashtra"}, -- 6,819,000
["Surat"] = {container = "Gujarat"}, -- 6,601,000
["Lucknow"] = {container = "Uttar Pradesh"}, -- 4,661,000
["Jaipur"] = {container = "Rajasthan"}, -- 4,360,000
["Kanpur"] = {container = "Uttar Pradesh"}, -- 4,350,000
["Indore"] = {container = "Madhya Pradesh"}, -- 3,765,000
["Nagpur"] = {container = "Maharashtra"}, -- 3,493,000
["Patna"] = {container = "Bihar"}, -- 3,331,000
["Varanasi"] = {container = "Uttar Pradesh"}, -- 3,229,000
["Kozhikode"] = {container = "Kerala"}, -- 3,049,000
["Thiruvananthapuram"] = {container = "Kerala"}, -- 2,851,000
["Agra"] = {container = "Uttar Pradesh"}, -- 2,737,000
["Bhopal"] = {container = "Madhya Pradesh"}, -- 2,562,000
["Coimbatore"] = {container = "Tamil Nadu"}, -- 2,551,000
["Allahabad"] = {container = "Uttar Pradesh", wp = "Prayagraj"}, -- 2,438,000
["Prayagraj"] = {alias_of = "Allahabad"},
["Kochi"] = {container = "Kerala"}, -- 2,381,000
["Ludhiana"] = {container = "Punjab"}, -- 2,205,000
["Vadodara"] = {container = "Gujarat"}, -- 2,182,000
["Chandigarh"] = {container = {key = "Chandigarh, India", placetype = "union territory"}}, -- 2,168,000
["Madurai"] = {container = "Tamil Nadu"}, -- 2,048,000
["Meerut"] = {container = "Uttar Pradesh"}, -- 2,011,000
["Visakhapatnam"] = {container = "Andhra Pradesh"}, -- 2,005,000
["Jamshedpur"] = {container = "Jharkhand"}, -- 1,925,000
["Malappuram"] = {container = "Kerala"}, -- 1,868,000
["Nashik"] = {container = "Maharashtra"}, -- 1,810,000
["Asansol"] = {container = "West Bengal"}, -- 1,720,000
["Aligarh"] = {container = "Uttar Pradesh"}, -- 1,660,000
["Ranchi"] = {container = "Jharkhand"}, -- 1,638,000
["Thrissur"] = {container = "Kerala"}, -- 1,578,000
["Kollam"] = {container = "Kerala"}, -- 1,576,000
["Jabalpur"] = {container = "Madhya Pradesh"}, -- 1,533,000
["Dhanbad"] = {container = "Jharkhand"}, -- 1,503,000
["Jodhpur"] = {container = "Rajasthan"}, -- 1,497,000
["Aurangabad"] = {container = "Maharashtra"}, -- 1,490,000
["Chhatrapati Sambhajinagar"] = {alias_of = "Aurangabad"},
["Rajkot"] = {container = "Gujarat"}, -- 1,487,000
["Gwalior"] = {container = "Madhya Pradesh"}, -- 1,477,000
["Raipur"] = {container = "Chhattisgarh"}, -- 1,429,000
["Gorakhpur"] = {container = "Uttar Pradesh"}, -- 1,410,000
["Kannur"] = {container = "Kerala"}, -- 1,360,000
["Bareilly"] = {container = "Uttar Pradesh"}, -- 1,355,000
["Guwahati"] = {container = "Assam"}, -- 1,355,000
["Moradabad"] = {container = "Uttar Pradesh"}, -- 1,345,000
["Amritsar"] = {container = "Punjab"}, -- 1,313,000
["Mysore"] = {container = "Karnataka"}, -- 1,296,000
["Bhilai"] = {container = "Chhattisgarh"}, -- 1,293,000
["Durg-Bhilainagar"] = {alias_of = "Bhilai"},
["Durg-Bhilai"] = {alias_of = "Bhilai"},
["Durg"] = {alias_of = "Bhilai"},
["Bhilainagar"] = {alias_of = "Bhilai"},
["Vijayawada"] = {container = "Andhra Pradesh"}, -- 1,232,000
["Srinagar"] = {container = {key = "Jammu and Kashmir, India", placetype = "union territory"}}, -- 1,212,000
["Salem"] = {container = "Tamil Nadu", wp = "%l, %c"}, -- 1,189,000
["Kota"] = {container = "Rajasthan"}, -- 1,172,000
["Jalandhar"] = {container = "Punjab"}, -- 1,165,000
["Saharanpur"] = {container = "Uttar Pradesh"}, -- 1,152,000
["Dehradun"] = {container = "Uttarakhand"}, -- 1,136,000
["Tiruchirappalli"] = {container = "Tamil Nadu"}, -- 1,131,000
["Bhubaneswar"] = {container = "Odisha"}, -- 1,112,000
["Jammu"] = {container = {key = "Jammu and Kashmir, India", placetype = "union territory"}}, -- 1,103,000
["Solapur"] = {container = "Maharashtra"}, -- 1,082,000
["Hubli-Dharwad"] = {container = "Karnataka", wp = "Hubli–Dharwad"}, -- 1,062,000; wp with en dash
["Hubli"] = {alias_of = "Hubli-Dharwad"},
["Dharwad"] = {alias_of = "Hubli-Dharwad"},
["Puducherry"] = {container = {key = "Puducherry, India", placetype = "union territory"}}, -- 1,024,000
["Pondicherry"] = {alias_of = "Puducherry", display = true},
-- satellite/secondary cities of metro area (none in citypopulation.de)
["Ghaziabad"] = {container = "Uttar Pradesh"}, -- 1,729,000 city, 2,358,525 urban agglomeration per 2011 census; 3,406,061 2025 estimate from official website; part of Delhi metro area
["Faridabad"] = {container = "Haryana"}, -- 1,414,050 city per 2011 census; part of Delhi metro area
["Thane"] = {container = "Maharashtra"}, -- 1,841,488 city per 2011 census; part of Mumbai metro area
["Kalyan-Dombivli"] = {container = "Maharashtra"}, -- 1,246,381 city per 2011 census; part of Mumbai metro area
["Kalyan-Dombivali"] = {alias_of = "Kalyan-Dombivli", display = true},
["Kalyan"] = {alias_of = "Kalyan-Dombivli"},
["Dombivli"] = {alias_of = "Kalyan-Dombivli"},
["Dombivali"] = {alias_of = "Kalyan-Dombivli"},
["Vasai-Virar"] = {container = "Maharashtra"}, -- 1,221,233 city per 2011 census; part of Mumbai metro area
["Vasai"] = {alias_of = "Vasai-Virar"},
["Virar"] = {alias_of = "Vasai-Virar"},
["Navi Mumbai"] = {container = "Maharashtra"}, -- 1,120,547 city per 2011 census; part of Mumbai metro area
["Howrah"] = {container = "West Bengal"}, -- 1,077,075 city ("metropolis"), 2,811,344 "metro" per 2011 census; part of Kolkata metro area
["Pimpri-Chinchwad"] = {container = "Maharashtra"}, -- 1,727,692 per 2011 census; part of Pune metro area
["Pimpri Chinchwad"] = {alias_of = "Pimpri-Chinchwad", display = true},
}
export.india_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", India", "negeri"),
default_placetype = "bandar",
data = export.india_cities,
}
export.indonesia_cities = {
-- cities where the city proper has more than 1,000,000 people as of mid-2023 estimate
["Jakarta"] = {container = "Special Capital Region of Jakarta", divs = {
{type = "subdaerah", container_parent_type = false},
}},
["Surabaya"] = {container = "East Java"},
["Bekasi"] = {container = "West Java"}, -- part of Jakarta metro area
["Bandung"] = {container = "West Java"},
["Medan"] = {container = "North Sumatra"},
["Depok"] = {container = "West Java"}, -- part of Jakarta metro area
["Tangerang"] = {container = "Banten"}, -- part of Jakarta metro area
["Palembang"] = {container = "South Sumatra"},
["Semarang"] = {container = "Central Java"},
["Makassar"] = {container = "South Sulawesi"},
["South Tangerang"] = {container = "Banten"}, -- part of Jakarta metro area
["Batam"] = {container = "Riau Islands"},
["Bogor"] = {container = "West Java"}, -- part of Jakarta metro area
["Pekanbaru"] = {container = "Riau"},
["Bandar Lampung"] = {container = "Lampung"},
-- other metro areas over 1,000,000 people
["Padang"] = {container = "West Sumatra"},
["Samarinda"] = {container = "East Kalimantan"},
["Malang"] = {container = "East Java"},
["Yogyakarta"] = {container = "Special Region of Yogyakarta"},
["Denpasar"] = {container = "Bali"},
["Cirebon"] = {container = "West Java"},
["Surakarta"] = {container = "Central Java"},
["Banjarmasin"] = {container = "South Kalimantan"},
["Tasikmalaya"] = {container = "West Java"},
}
export.indonesia_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Indonesia", "province"),
default_placetype = "bandar",
data = export.indonesia_cities,
}
export.italy_cities = {
-- Data per [[w:List_of_metropolitan_areas_of_Italy]]. There are several lists given; the most recent one, used
-- here, only gives estimates as of Jan 1, 2014.
["Milan"] = {container = "Lombardy"}, -- 6,623,798
["Naples"] = {container = "Campania"}, -- 5,294,546
["Rom"] = {container = "Lazio"}, -- 4,447,881
["Turin"] = {container = "Piedmont"}, -- 1,865,284
["Venice"] = {container = "Veneto"}, -- 1,645,900
["Florence"] = {container = "Tuscany"}, -- 1,485,030
["Bari"] = {container = "Apulia"}, -- 1,257,459
["Palermo"] = {container = "Sicily"}, -- 1,183,084
-- include a few just below 1,000,000 metro area that may be above it by now (depending on the definition).
["Catania"] = {container = "Sicily"}, -- 988,240
["Brescia"] = {container = "Lombardy"}, -- 924,090
["Genoa"] = {container = "Liguria"}, -- 861,318
}
export.italy_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Itali", "wilayah"),
default_placetype = "bandar",
data = export.italy_cities,
}
export.japan_cities = {
-- Population figures from [[w:List of cities in Japan]]. Metro areas from
-- [[w:List of metropolitan areas in Japan]].
["Tokyo"] = {keydesc = "[[Tokyo]] Metropolis, the [[capital city]] and a [[prefecture]] of [[Japan]] (which is a country in [[Asia]])",
placetype = {"bandar", "prefecture"},
divs = {
{type = "special wards", container_parent_type = false},
{type = "bandar", prep = "di"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Osaka"] = {container = "Osaka"}, -- 2,668,586
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaido"}, -- 1,918,096
["Fukuoka"] = {container = "Fukuoka"}, -- 1,581,527
["Kobe"] = {container = "Hyōgo"}, -- 1,530,847
["Kyoto"] = {container = "Kyoto"}, -- 1,474,570
["Kawasaki"] = {container = "Kanagawa", wp = "%l, Kanagawa"}, -- 1,373,630
["Saitama"] = {container = "Saitama", wp = "%l (city)", commonscat = "%l, %c"}, -- 1,192,418
["Hiroshima"] = {container = "Hiroshima"}, -- 1,163,806
["Sendai"] = {container = "Miyagi"}, -- 1,029,552
-- the remaining cities are considered "central cities" in a 1,000,000+ metro area
-- (sometimes there is more than one central city in the area).
["Kitakyushu"] = {container = "Fukuoka"}, -- 986,998
["Chiba"] = {container = "Chiba", wp = "%l (city)", commonscat = "%l, %c"}, -- 938,695
["Sakai"] = {container = "Osaka"}, -- 835,333
["Niigata"] = {container = "Niigata", wp = "%l (city)", commonscat = "%l, %c"}, -- 813,053
["Hamamatsu"] = {container = "Shizuoka"}, -- 811,431
["Shizuoka"] = {container = "Shizuoka", wp = "%l (city)", commonscat = "%l, %c"}, -- 710,944
["Sagamihara"] = {container = "Kanagawa"}, -- 706,342
["Okayama"] = {container = "Okayama"}, -- 701,293
["Kumamoto"] = {container = "Kumamoto"}, -- 670,348
["Kagoshima"] = {container = "Kagoshima"}, -- 605,196
-- skipped 6 cities (Funabashi, Hachiōji, Kawaguchi, Himeji, Matsuyama, Higashiōsaka)
-- with population in the range 509k - 587k because not central cities in any
-- 1,000,000+ metro area.
["Utsunomiya"] = {container = "Tochigi"}, -- 507,833
}
export.japan_cities_group = {
default_container = "Japan",
canonicalize_key_container = make_canonicalize_key_container(" Prefecture, Jepun", "prefecture"),
default_placetype = "bandar",
data = export.japan_cities,
}
export.mexico_cities = {
["Mexico City"] = {}, -- its own state
["Monterrey"] = {container = "Nuevo León"},
["Guadalajara"] = {container = "Jalisco"},
["Puebla"] = {container = "Puebla", wp = "%l (city)"},
["Toluca"] = {container = "State of Mexico"},
["Tijuana"] = {container = "Baja California"},
-- Include the state in the category for León due to possible confusion with León, Spain.
["León, Guanajuato"] = {container = "Guanajuato", wp = "%l, %c"},
["León"] = {alias_of = "León, Guanajuato"},
["Leon"] = {alias_of = "León, Guanajuato", display = true},
["Querétaro"] = {container = "Querétaro", wp = "%l (city)"},
["Queretaro"] = {alias_of = "Querétaro", display = true},
["Ciudad Juárez"] = {container = "Chihuahua"},
["Juárez"] = {alias_of = "Ciudad Juárez"},
["Juarez"] = {alias_of = "Ciudad Juárez", display = "Juárez"},
["Torreón"] = {container = "Coahuila"},
["Torreon"] = {alias_of = "Torreón", display = true},
-- Include the state in the category for Mérida due to possible confusion with Mérida, Spain or
-- Mérida, Venezuela.
["Mérida, Yucatán"] = {container = "Yucatán", wp = "%l, %c"},
["Mérida"] = {alias_of = "Mérida, Yucatán"},
["Merida"] = {alias_of = "Mérida, Yucatán", display = true},
["San Luis Potosí"] = {container = "San Luis Potosí", wp = "%l (city)"},
["San Luis Potosi"] = {alias_of = "San Luis Potosí", display = true},
["Aguascalientes"] = {container = "Aguascalientes", wp = "%l (city)"},
["Mexicali"] = {container = "Baja California"},
}
export.mexico_cities_group = {
default_container = "Mexico",
canonicalize_key_container = make_canonicalize_key_container(", Mexico", "negeri"),
default_placetype = "bandar",
data = export.mexico_cities,
}
export.nigeria_cities = {
-- Figures from citypopulation.de unless otherwise indicated; retrieved 2025-04-26; reference date 2025-01-01.
["Lagos"] = {container = "Lagos"}, -- 21,300,000 (unindicated; population of low reliability)
["Kano"] = {container = "Kano", wp = "%l (city)"}, -- 5,350,000 (unindicated; population of low reliability)
["Ibadan"] = {container = "Oyo"}, -- 3,400,000 (unindicated; population of low reliability)
["Abuja"] = {container = {key = "Federal Capital Territory, Nigeria", placetype = "wilayah persekutuan"}}, -- 3,050,000 (unindicated; population of low reliability)
["Port Harcourt"] = {container = "Rivers"}, -- 2,250,000 (unindicated; population of low reliability)
["Kaduna"] = {container = "Kaduna"}, -- 1,980,000 (unindicated; population of low reliability)
["Benin City"] = {container = "Edo"}, -- 1,790,000 (unindicated; population of low reliability)
["Aba"] = {container = "Abia", wp = "%l, Nigeria"}, -- 1,280,000 (unindicated; population of low reliability)
["Onitsha"] = {container = "Anambra"}, -- 1,230,000 (unindicated; population of low reliability)
["Maiduguri"] = {container = "Borno"}, -- 1,190,000 (unindicated; population of low reliability)
["Ilorin"] = {container = "Kwara"}, -- 1,160,000 (unindicated; population of low reliability)
["Sokoto"] = {container = "Sokoto", wp = "%l (city)"}, -- 1,140,000 (unindicated; population of low reliability)
["Jos"] = {container = "Plateau"}, -- 1,110,000 (unindicated; population of low reliability)
["Zaria"] = {container = "Kaduna"}, -- 1,050,000 (unindicated; population of low reliability)
["Enugu"] = {container = "Enugu", wp = "%l (city)"}, -- 1,010,000 (unindicated; population of low reliability)
}
export.nigeria_cities_group = {
default_container = "Nigeria",
canonicalize_key_container = make_canonicalize_key_container(" State, Nigeria", "negeri"),
default_placetype = "bandar",
data = export.nigeria_cities,
}
export.pakistan_cities = {
-- Figures from citypopulation.de; retrieved 2025-04-26; reference date 2025-01-01.
["Karachi"] = {container = "Sindh"}, -- 21,000,000 (Consolidated Urban Area)
["Lahore"] = {container = "Punjab"}, -- 14,600,000 (Consolidated Urban Area)
["Rawalpindi"] = {container = "Punjab"}, -- 5,600,000 (Consolidated Urban Area; including Islamabad)
["Islamabad"] = {container = {key = "Islamabad Capital Territory, Pakistan", placetype = "wilayah persekutuan"}}, -- 5,600,000 (Consolidated Urban Area; including Rawalpindi)
["Faisalabad"] = {container = "Punjab"}, -- 4,125,000 (Consolidated Urban Area)
["Gujranwala"] = {container = "Punjab"}, -- 3,450,000 (Consolidated Urban Area)
-- there is also Hyderabad in India (very confusing)
["Hyderabad, Pakistan"] = {container = "Sindh", wp = "%l, %c"}, -- 2,475,000 (Consolidated Urban Area)
["Hyderabad"] = {alias_of = "Hyderabad, Pakistan"},
["Multan"] = {container = "Punjab"}, -- 2,425,000 (Consolidated Urban Area)
["Peshawar"] = {container = "Khyber Pakhtunkhwa"}, -- 2,150,000 (Consolidated Urban Area)
["Quetta"] = {container = "Balochistan"}, -- 1,720,000 (Urban Area)
["Sargodha"] = {container = "Punjab"}, -- 1,080,000 (Urban Area)
["Sialkot"] = {container = "Punjab"}, -- 1,050,000 (Consolidated Urban Area)
}
export.pakistan_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Pakistan", "province"),
default_placetype = "bandar",
data = export.pakistan_cities,
}
export.philippines_cities = {
-- Skipped some cities in Metro Manila (Taguig, Pasig) which don't have districts.
-- Other cities outside Metro Manila skipped as not central city in their urban area.
["Quezon City"] = {container = {key = "Metro Manila, Philippines", placetype = "wilayah"}},
-- Don't display-canonicalize Foo to Foo City as it may make the display weird.
["Quezon"] = {alias_of = "Quezon City"},
["Manila"] = {container = {key = "Metro Manila, Philippines", placetype = "wilayah"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "wilayah"}},
["Zamboanga City"] = {container = "Zamboanga del Sur"},
["Zamboanga"] = {alias_of = "Zamboanga City"},
["Cebu City"] = {container = "Cebu"},
["Cebu"] = {alias_of = "Cebu City"},
["Antipolo"] = {container = "Rizal"},
["Cagayan de Oro"] = {container = "Misamis Oriental"},
["Dasmariñas"] = {container = "Cavite"},
["Dasmarinas"] = {alias_of = "Dasmariñas", display = true},
["General Santos"] = {container = "South Cotabato"},
["San Jose del Monte"] = {container = "Bulacan"},
["Bacolod"] = {container = "Negros Occidental"},
["Calamba"] = {container = "Laguna", wp = "%l, %c"},
["Angeles"] = {container = "Pampanga", wp = "Angeles City"},
["Angeles City"] = {alias_of = "Angeles"},
["Iloilo City"] = {container = "Iloilo"},
["Iloilo"] = {alias_of = "Iloilo City"},
}
export.philippines_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Philippines", "province"),
default_placetype = "bandar",
data = export.philippines_cities,
}
export.russia_cities = {
-- Figures from citypopulation.de; retrieved 2025-04-26; reference date 2025-01-01.
["Moscow"] = {}, -- 18,800,000 (Agglomeration)
["Saint Petersburg"] = {}, -- 6,350,000 (Agglomeration)
["Novosibirsk"] = {container = "Novosibirsk Oblast"}, -- 1,820,000 (Agglomeration)
["Yekaterinburg"] = {container = "Sverdlovsk Oblast"}, -- 1,810,000 (Agglomeration)
["Nizhny Novgorod"] = {container = "Nizhny Novgorod Oblast"}, -- 1,620,000 (Agglomeration)
["Kazan"] = {container = {key = "Tatarstan, Russia", placetype = "republic"}}, -- 1,560,000 (Agglomeration)
["Chelyabinsk"] = {container = "Chelyabinsk Oblast"}, -- 1,430,000 (Agglomeration)
["Rostov-on-Don"] = {container = "Rostov Oblast"}, -- 1,390,000 (Agglomeration)
["Rostov-na-Donu"] = {alias_of = "Rostov-on-Don", display = true},
["Krasnodar"] = {container = {key = "Krasnodar Krai, Russia", placetype = "krai"}}, -- 1,370,000 (Agglomeration)
["Samara"] = {container = "Samara Oblast"}, -- 1,350,000 (Agglomeration)
["Krasnoyarsk"] = {container = {key = "Krasnoyarsk Krai, Russia", placetype = "krai"}}, -- 1,270,000 (Agglomeration)
["Ufa"] = {container = {key = "Bashkortostan, Russia", placetype = "republic"}}, -- 1,230,000 (Agglomeration)
["Saratov"] = {container = "Saratov Oblast"}, -- 1,170,000 (Agglomeration)
["Omsk"] = {container = "Omsk Oblast"}, -- 1,140,000 (Agglomeration)
["Voronezh"] = {container = "Voronezh Oblast"}, -- 1,130,000 (Agglomeration)
["Volgograd"] = {container = "Volgograd Oblast"}, -- 1,080,000 (Agglomeration)
["Perm"] = {container = {key = "Perm Krai, Russia", placetype = "krai"}, wp = "%l, Russia"}, -- 1,070,000 (Agglomeration)
}
export.russia_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Russia", "oblast"),
default_container = "Russia",
default_placetype = "bandar",
data = export.russia_cities,
}
export.saudi_arabia_cities = {
-- Figures for the first five from [[w:List of cities and towns in Saudi Arabia]] as of 2022. Unclear if these are
-- metro, urban or city proper figures.
["Riyadh"] = {container = "Riyadh"}, -- 7,000,100; 7,700,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Jeddah"] = {container = "Mecca"}, -- 3,751,917; 3,950,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Jedda"] = {alias_of = "Jeddah", display = true},
["Jiddah"] = {alias_of = "Jeddah", display = true},
["Jidda"] = {alias_of = "Jeddah", display = true},
["Dammam"] = {container = "Eastern"}, -- 2,638,166; 2,925,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Mecca"] = {container = "Mecca"}, -- 2,385,509; 2,675,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Makkah"] = {alias_of = "Mecca", display = true},
["Medina"] = {container = "Medina"}, -- 1,477,023; 1,530,000 per citypopulation.de 2025-01-01 (City)
["Hofuf"] = {container = "Eastern"}, -- 1,060,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Khamis Mushait"] = {container = "Aseer"}, -- 1,030,000 per citypopulation.de 2025-01-01 (Agglomeration)
["Khamis Mushayt"] = {alias_of = "Khamis Mushait", display = true},
}
export.saudi_arabia_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(" Province, Saudi Arabia", "province"),
default_placetype = "bandar",
data = export.saudi_arabia_cities,
}
export.south_korea_cities = {
-- All cities listed are not associated with any county.
["Seoul"] = {},
["Busan"] = {},
["Incheon"] = {},
["Daegu"] = {},
["Daejeon"] = {},
["Gwangju"] = {},
["Ulsan"] = {},
}
export.south_korea_cities_group = {
default_container = "South Korea",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "bandar",
data = export.south_korea_cities,
}
export.spain_cities = {
["Madrid"] = {container = "Community of Madrid"},
["Barcelona"] = {container = "Catalonia"},
["Valencia"] = {container = "Valencia"},
["Seville"] = {container = "Andalusia"},
["Bilbao"] = {container = "Basque Country"},
}
export.spain_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", Spain", "autonomous community"),
default_placetype = "bandar",
data = export.spain_cities,
}
export.taiwan_cities = {
["New Taipei City"] = {},
["New Taipei"] = {alias_of = "New Taipei City", display = true},
["Taichung"] = {},
["Kaohsiung"] = {wp = "%l, Taiwan"},
["Taipei"] = {},
["Taoyuan"] = {},
["Tainan"] = {},
-- these last three are not special municipalities
["Chiayi"] = {placetype = "bandar"},
["Hsinchu"] = {placetype = "bandar"},
["Keelung"] = {placetype = "bandar"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "kaunti"),
default_container = "Taiwan",
default_placetype = {"special municipality", "municipality", "bandar"},
default_is_city = true,
default_divs = {"daerah"},
data = export.taiwan_cities,
}
-- NOTE: It's OK to mix cities from different constituent countries; as long as the immediate container is correct,
-- everything else will be figured out.
export.united_kingdom_cities = {
["London"] = {container = "Greater London"},
["Manchester"] = {container = "Greater Manchester"},
["Birmingham"] = {container = "West Midlands"},
["Liverpool"] = {container = "Merseyside"},
["Glasgow"] = {container = {key = "City of Glasgow, Scotland", placetype = "council area"}},
["Leeds"] = {container = "West Yorkshire"},
["Newcastle upon Tyne"] = {container = "Tyne and Wear"},
["Newcastle"] = {alias_of = "Newcastle upon Tyne"},
["Bristol"] = {container = {key = "England", placetype = "negara bahagian"}},
["Cardiff"] = {container = {key = "Wales", placetype = "negara bahagian"}},
["Portsmouth"] = {container = "Hampshire"},
["Edinburgh"] = {container = {key = "City of Edinburgh, Scotland", placetype = "council area"}},
-- under 1,000,000 people but principal areas of Wales; requested by [[User:Donnanz]]
["Swansea"] = {container = {key = "Wales", placetype = "negara bahagian"}},
["Newport"] = {container = {key = "Wales", placetype = "negara bahagian"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "kaunti"),
default_placetype = "bandar",
data = export.united_kingdom_cities,
}
export.united_states_cities = {
-- top 50 CSA's by population, with the top and sometimes 2nd or 3rd city listed
["New York City"] = {container = "New York", wp = "%l", divs = {
{type = "boroughs", container_parent_type = false},
}},
-- Don't display-canonicalize as it may make the display weird (e.g. in the context New York, New York).
["New York"] = {alias_of = "New York City"},
["Newark"] = {container = "New Jersey"},
["Los Angeles"] = {container = "California", wp = "%l"},
["Long Beach"] = {container = "California"},
["Riverside"] = {container = "California"},
["Chicago"] = {container = "Illinois", wp = "%l"},
["Washington, D.C."] = {wp = "%l"},
["Washington, DC"] = {alias_of = "Washington, D.C.", display = true},
["Washington D.C."] = {alias_of = "Washington, D.C.", display = true},
["Washington DC"] = {alias_of = "Washington, D.C.", display = true},
-- Don't display-canonicalize as it may make the display weird (e.g. if the holonym is followed by a District of
-- Columbia holonym).
["Washington"] = {alias_of = "Washington, D.C."},
["Baltimore"] = {container = "Maryland", wp = "%l"},
-- to avoid conflict with San Jose in Costa Rica
["San Jose, California"] = {container = "California"},
["San Jose"] = {alias_of = "San Jose, California"},
["San Francisco"] = {container = "California", wp = "%l"},
["Oakland"] = {container = "California"},
["Boston"] = {container = "Massachusetts", wp = "%l"},
["Providence"] = {container = "Rhode Island"},
["Dallas"] = {container = "Texas", wp = "%l", commonscat = "%l, %c"},
["Fort Worth"] = {container = "Texas"},
["Philadelphia"] = {container = "Pennsylvania", wp = "%l"},
["Houston"] = {container = "Texas", wp = "%l"},
["Miami"] = {container = "Florida", wp = "%l", commonscat = "%l, %c"},
["Atlanta"] = {container = "Georgia", wp = "%l"},
["Detroit"] = {container = "Michigan", wp = "%l"},
["Phoenix"] = {container = "Arizona", wp = "%l", commonscat = "%l, %c"},
["Mesa"] = {container = "Arizona"},
["Seattle"] = {container = "Washington", wp = "%l"},
["Orlando"] = {container = "Florida"},
["Minneapolis"] = {container = "Minnesota", wp = "%l"},
["Cleveland"] = {container = "Ohio", wp = "%l", commonscat = "%l, %c"},
["Denver"] = {container = "Colorado", wp = "%l", commonscat = "%l, %c"},
["San Diego"] = {container = "California", wp = "%l", commonscat = "%l, %c"},
["Portland"] = {container = "Oregon"},
["Tampa"] = {container = "Florida"},
["St. Louis"] = {container = "Missouri", wp = "%l", commonscat = "%l, %c"},
["Saint Louis"] = {alias_of = "St. Louis", display = true},
["Charlotte"] = {container = "North Carolina"},
["Sacramento"] = {container = "California"},
["Pittsburgh"] = {container = "Pennsylvania", wp = "%l"},
["Salt Lake City"] = {container = "Utah", wp = "%l"},
["San Antonio"] = {container = "Texas", wp = "%l", commonscat = "%l, %c"},
["Columbus"] = {container = "Ohio"},
["Kansas City"] = {container = "Missouri", wp = "%l metropolitan area", commonscat = "%l, %c"},
["Indianapolis"] = {container = "Indiana", wp = "%l"},
["Las Vegas"] = {container = "Nevada", wp = "%l"},
["Cincinnati"] = {container = "Ohio", wp = "%l", commonscat = "%l, %c"},
["Austin"] = {container = "Texas"},
["Milwaukee"] = {container = "Wisconsin", wp = "%l", commonscat = "%l, %c"},
["Raleigh"] = {container = "North Carolina"},
["Nashville"] = {container = "Tennessee"},
["Virginia Beach"] = {container = "Virginia"},
["Norfolk"] = {container = "Virginia"},
["Greensboro"] = {container = "North Carolina"},
["Winston-Salem"] = {container = "North Carolina"},
["Jacksonville"] = {container = "Florida"},
["New Orleans"] = {container = "Louisiana", wp = "%l"},
["Louisville"] = {container = "Kentucky"},
["Greenville"] = {container = "South Carolina"},
["Hartford"] = {container = "Connecticut"},
["Oklahoma City"] = {container = "Oklahoma", wp = "%l"},
["Grand Rapids"] = {container = "Michigan"},
["Memphis"] = {container = "Tennessee"},
["Birmingham, Alabama"] = {container = "Alabama"},
["Birmingham"] = {alias_of = "Birmingham, Alabama"},
["Fresno"] = {container = "California"},
["Richmond"] = {container = "Virginia"},
["Harrisburg"] = {container = "Pennsylvania"},
-- any major city of top 50 MSA's that's missed by previous
["Buffalo"] = {container = "New York"},
-- any of the top 50 city by city population that's missed by previous
["El Paso"] = {container = "Texas"},
["Albuquerque"] = {container = "New Mexico"},
["Tucson"] = {container = "Arizona"},
["Colorado Springs"] = {container = "Colorado"},
["Omaha"] = {container = "Nebraska"},
["Tulsa"] = {container = "Oklahoma"},
-- skip Arlington, Texas; too obscure and likely to be interpreted as Arlington, Virginia
}
export.united_states_cities_group = {
default_container = "Amerika Syarikat",
canonicalize_key_container = make_canonicalize_key_container(", USA", "negeri"),
default_placetype = "bandar",
default_wp = "%l, %c",
data = export.united_states_cities,
}
export.new_york_boroughs = {
["Bronx"] = {the = true, wp = "The Bronx"},
["Brooklyn"] = {},
["Manhattan"] = {},
["Queens"] = {},
["Staten Island"] = {},
}
export.new_york_boroughs_group = {
default_container = {key = "New York City", placetype = "bandar"},
default_placetype = "borough",
default_is_city = true,
data = export.new_york_boroughs,
}
export.vietnam_cities = {
-- Figures from citypopulation.de (retrieved 2025-04-26; reference date 2025-01-01) unless otherwise indicated.
["Ho Chi Minh City"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Saigon"] = {alias_of = "Ho Chi Minh City"},
["Hanoi"] = {}, -- 7,350,000 (Agglomeration)
["Da Nang"] = {}, -- 1,500,000 (Agglomeration)
["Danang"] = {alias_of = "Da Nang", display = true},
["Haiphong"] = {}, -- 1,450,000 (Agglomeration)
["Hai Phong"] = {alias_of = "Haiphong", display = true},
-- This is the one entry in this list that is not a province-level municipality; instead it's a "provincial city"
-- meaning it is directly under its province as opposed to being contained in a district.
["Bien Hoa"] = {placetype = "bandar", container = "Đồng Nai", wp = "Biên Hòa"}, -- 1,272,235 (2022 city population per Wikipedia)
["Biên Hòa"] = {alias_of = "Bien Hoa", display = true},
["Biên Hoà"] = {alias_of = "Bien Hoa", display = true},
-- These two not in citypopulation.de because the urban population may be slightly under 1,000,000, but they are
-- both province-level municipalities and close to the 1,000,000 mark.
["Can Tho"] = {wp = "Cần Thơ"}, -- 1,456,000 municipality (2019 census), 994,704 urban (2022 General Statistics Office of Vietnam estimate); capital [[Ninh Kiều district]]
["Cần Thơ"] = {alias_of = "Can Tho", display = true},
["Hue"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Huế"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Vietnam",
canonicalize_key_container = make_canonicalize_key_container(" Province, Vietnam", "province"),
-- Most of the cities listed are province-level municipalities in addition, which contain a certain amount of
-- rural territory surrounding the city, but not enough to separate the municipality from the city as distinct
-- known locations.
default_placetype = {"municipality", "bandar"},
default_is_city = true,
-- There may not be enough districts to subcategorize like this.
-- default_divs = "districts",
data = export.vietnam_cities,
}
export.misc_cities = {
------------------ Africa -------------------
-- Sorted by country and then within the country, by decreasing population; figures from citypopulation.de
-- (retrieved 2025-04-26; reference date 2025-01-01) unless otherwise indicated; combined with data from
-- [[w:List of urban areas in Africa by population]].
["Algiers"] = {container = "Algeria"}, -- 4,325,000 (Consolidated Urban Area)
["Oran"] = {container = "Algeria"}, -- 1,640,000 (Consolidated Urban Area)
["Luanda"] = {container = "Angola"}, -- 9,650,000 (Urban Area)
["Benguela"] = {container = "Angola"}, -- 1,420,000 (Urban Area)
["Cotonou"] = {container = "Benin"}, -- 2,150,000 (Agglomeration)
["Ouagadougou"] = {container = "Burkina Faso"}, -- 3,425,000 (Agglomeration)
["Bobo-Dioulasso"] = {container = "Burkina Faso"}, -- 1,100,000 (Agglomeration)
["Bujumbura"] = {container = "Burundi"}, -- 1,143,202 (Urban Area 2023 per PopulationStat, cited in Wikipedia)
["Yaoundé"] = {container = "Cameroon"}, -- 3,975,000 (City)
["Yaounde"] = {alias_of = "Yaoundé", display = true},
["Douala"] = {container = "Cameroon"}, -- 3,900,000 (City)
["Bangui"] = {container = "Republik Afrika Tengah"}, -- 1,680,000 (Agglomeration)
["N'Djamena"] = {container = "Chad"}, -- 1,950,000 (City)
["Ndjamena"] = {alias_of = "N'Djamena", display = true},
["Kinshasa"] = {container = "Democratic Republic of the Congo"}, -- 16,300,000 (City; population of low reliability)
["Lubumbashi"] = {container = "Democratic Republic of the Congo"}, -- 2,875,000 (City; population of low reliability)
["Mbuji-Mayi"] = {container = "Democratic Republic of the Congo"}, -- 2,500,000 (City; population of low reliability)
["Kananga"] = {container = "Democratic Republic of the Congo"}, -- 1,370,000 (City; population of low reliability)
["Kisangani"] = {container = "Democratic Republic of the Congo"}, -- 1,300,000 (City; population of low reliability)
["Bukavu"] = {container = "Democratic Republic of the Congo"}, -- 1,100,000 (City; population of low reliability)
["Goma"] = {container = "Democratic Republic of the Congo"}, -- 1,010,000 (City; population of low reliability)
["Tshikapa"] = {container = "Democratic Republic of the Congo"}, -- 1,020,468 (2023 Wikipedia [[w:List of cities with over one million inhabitants]] from populationstat.com; not in citypopulation.de)
["Kaherah"] = {container = "Mesir"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Iskandariah"] = {container = "Mesir"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Mesir"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Mesir"}, -- 1,240,239 (2021 from citypopulation.de)
["Asmara"] = {container = "Eritrea"}, -- 1,090,000 (City; population of low reliability)
["Asmera"] = {alias_of = "Asmara", display = true},
["Addis Ababa"] = {container = "Habsyah"}, -- 4,825,000 (Agglomeration)
["Banjul"] = {container = "Gambia"}, -- 1,170,000 (Agglomeration)
["Accra"] = {container = "Ghana"}, -- 6,800,000 (Agglomeration)
["Kumasi"] = {container = "Ghana"}, -- 2,900,000 (Agglomeration)
["Conakry"] = {container = "Guinea"}, -- 2,975,000 (Consolidated Urban Area)
["Abidjan"] = {container = "Ivory Coast"}, -- 7,050,000 (Agglomeration)
["Nairobi"] = {container = "Kenya"}, -- 6,900,000 (unindicated)
["Mombasa"] = {container = "Kenya"}, -- 1,370,000 (City)
["Monrovia"] = {container = "Liberia"}, -- 1,940,000 (Urban Area)
["Tripoli"] = {container = "Libya", wp = "%l, %c"}, -- 1,870,000 (unindicated)
["Antananarivo"] = {container = "Madagascar"}, -- 3,150,000 (Agglomeration)
["Lilongwe"] = {container = "Malawi"}, -- 1,210,000 (City)
["Bamako"] = {container = "Mali"}, -- 5,700,000 (Agglomeration)
["Nouakchott"] = {container = "Mauritania"}, -- 1,500,000 (City)
["Casablanca"] = {container = {key = "Casablanca-Settat, Morocco", placetype = "wilayah"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "wilayah"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "wilayah"}}, -- 1,410,000 (Municipality (urban population))
["Tanger"] = {alias_of = "Tangier", display = true},
["Tangiers"] = {alias_of = "Tangier", display = true},
["Fez"] = {container = {key = "Fez-Meknes, Morocco", placetype = "wilayah"}, wp = "%l, Morocco"}, -- 1,310,000 (Municipality (urban population))
["Fes"] = {alias_of = "Fez", display = true},
["Fès"] = {alias_of = "Fez", display = true},
["Agadir"] = {container = {key = "Souss-Massa, Morocco", placetype = "wilayah"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "wilayah"}}, -- 1,140,000 (Municipality (urban population))
["Marrakech"] = {alias_of = "Marrakesh", display = true},
["Maputo"] = {container = "Mozambique"}, -- 2,575,000 (Agglomeration)
["Niamey"] = {container = "Niger"}, -- 1,530,000 (City)
["Brazzaville"] = {container = "Republik Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republik Congo"}, -- 1,480,000 (City)
["Kigali"] = {container = "Rwanda"}, -- 1,960,000 (Municipality (urban population))
["Dakar"] = {container = "Senegal"}, -- 4,225,000 (Agglomeration)
["Touba"] = {container = "Senegal"}, -- 1,320,000 (Agglomeration)
["Freetown"] = {container = "Sierra Leone"}, -- 1,420,000 (Agglomeration)
["Mogadishu"] = {container = "Somalia"}, -- 2,250,000 (unindicated; population of low reliability)
["Johannesburg"] = {container = {key = "Gauteng, South Africa", placetype = "province"}}, -- 14,800,000 (Consolidated Urban Area; including Pretoria, Soweto, etc.)
["Cape Town"] = {container = {key = "Western Cape, South Africa", placetype = "province"}}, -- 5,100,000 (Consolidated Urban Area)
["Durban"] = {container = {key = "KwaZulu-Natal, South Africa", placetype = "province"}}, -- 3,900,000 (Consolidated Urban Area)
["Pretoria"] = {container = {key = "Gauteng, South Africa", placetype = "province"}}, -- 2,921,488 (2011 census)
["Port Elizabeth"] = {container = {key = "Eastern Cape, South Africa", placetype = "province"}, wp = "Gqeberha"}, -- 1,200,000 (Consolidated Urban Area)
["Gqeberha"] = {alias_of = "Port Elizabeth"}, -- official name; not a display alias
["Khartoum"] = {container = "Sudan"}, -- 7,200,000 (unindicated; population of low reliability)
["Dar es Salaam"] = {container = "Tanzania"}, -- 6,650,000 (Agglomeration)
["Mwanza"] = {container = "Tanzania"}, -- 1,340,000 (Agglomeration)
["Mwanza City"] = {alias_of = "Mwanza", display = true},
["Arusha"] = {container = "Tanzania"}, -- 1,190,000 (Agglomeration)
["Zanzibar"] = {container = "Tanzania"}, -- 1,030,000 (Agglomeration)
["Lomé"] = {container = "Togo"}, -- 2,625,000 (unindicated)
["Lome"] = {alias_of = "Lomé", display = true},
["Tunis"] = {container = "Tunisia"}, -- 2,725,000 (Municipality (urban population))
["Sousse"] = {container = "Tunisia"}, -- 1,180,000 (Municipality (urban population))
["Soussa"] = {alias_of = "Sousse", display = true},
["Kampala"] = {container = "Uganda"}, -- 4,300,000 (unindicated)
["Lusaka"] = {container = "Zambia"}, -- 3,000,000 (Consolidated Urban Area)
["Harare"] = {container = "Zimbabwe"}, -- 2,675,000 (Agglomeration)
------------------ Asia -------------------
-- sorted by country and then within the country, by decreasing population; figures from citypopulation.de
-- (retrieved 2025-04-26; reference date 2025-01-01) unless otherwise indicated.
["Kabul"] = {container = "Afghanistan"}, -- 5,250,000 (Agglomeration)
["Baku"] = {container = "Azerbaijan"}, -- 3,725,000 (Administrative Area (urban population))
["Manama"] = {container = "Bahrain"}, -- 1,560,000 (unindicated)
["Dhaka"] = {container = {key = "Dhaka Division, Bangladesh", placetype = "division"}}, -- 23,100,000 (Agglomeration)
["Dacca"] = {alias_of = "Dhaka", display = true},
["Chittagong"] = {container = {key = "Chittagong Division, Bangladesh", placetype = "division"}}, -- 5,050,000 (Agglomeration)
["Gazipur"] = {container = {key = "Dhaka Division, Bangladesh", placetype = "division"}}, -- 2,674,697 (City per 2022; countied in citypopulation.de as part of Dhaka metro area)
["Khulna"] = {container = {key = "Khulna Division, Bangladesh", placetype = "division"}}, -- 1,210,000 (Agglomeration)
["Phnom Penh"] = {container = "Kemboja"}, -- 2,925,000 (Agglomeration)
["Tehran"] = {container = {key = "Tehran Province, Iran", placetype = "province"}}, -- 16,800,000 (Agglomeration)
["Teheran"] = {alias_of = "Tehran", display = true},
["Mashhad"] = {container = {key = "Razavi Khorasan Province, Iran", placetype = "province"}}, -- 3,475,000 (Agglomeration)
["Mashad"] = {alias_of = "Mashhad", display = true},
["Meshhed"] = {alias_of = "Mashhad", display = true},
["Meshed"] = {alias_of = "Mashhad", display = true},
["Isfahan"] = {container = {key = "Isfahan Province, Iran", placetype = "province"}}, -- 3,425,000 (Agglomeration)
["Esfahan"] = {alias_of = "Isfahan", display = true},
["Tabriz"] = {container = {key = "East Azerbaijan Province, Iran", placetype = "province"}}, -- 1,970,000 (Agglomeration)
["Shiraz"] = {container = {key = "Fars Province, Iran", placetype = "province"}}, -- 1,950,000 (Agglomeration)
["Ahvaz"] = {container = {key = "Khuzestan Province, Iran", placetype = "province"}}, -- 1,550,000 (Agglomeration)
["Qom"] = {container = {key = "Qom Province, Iran", placetype = "province"}}, -- 1,450,000 (City)
["Kermanshah"] = {container = {key = "Kermanshah Province, Iran", placetype = "province"}}, -- 1,130,000 (City)
["Baghdad"] = {container = "Iraq"}, -- 7,800,000 (Administrative Area (urban population))
["Basra"] = {container = "Iraq"}, -- 1,710,000 (Administrative Area (urban population))
["Mosul"] = {container = "Iraq"}, -- 1,550,000 (Administrative Area (urban population))
["Erbil"] = {container = "Iraq"}, -- 1,220,000 (Administrative Area (urban population))
["Kirkuk"] = {container = "Iraq"}, -- 1,160,000 (Administrative Area (urban population))
["Najaf"] = {container = "Iraq"}, -- 1,050,000 (Administrative Area (urban population))
["Tel Aviv"] = {container = "Israel"}, -- 3,000,000 (Agglomeration)
-- Jerusalem is not recognized internationally as part of either Israel or Palestine, but as a
-- [[w:corpus separatum]], so put the container as "Asia" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "Asia", placetype = "benua"},
addl_parents = {"Israel", "Palestine"}}, -- 1,080,000 (Agglomeration)
["Amman"] = {container = "Jordan"}, -- 6,150,000 (unindicated)
["Irbid"] = {container = "Jordan"}, -- 1,070,000 (unindicated)
["Almaty"] = {container = "Kazakhstan"}, -- 2,700,000 (Agglomeration)
["Alma-Ata"] = {alias_of = "Almaty"}, -- former name, sometimes still used; don't display-canonicalize
["Astana"] = {container = "Kazakhstan"}, -- 1,600,000 (Agglomeration)
["Shymkent"] = {container = "Kazakhstan"}, -- 1,370,000 (Agglomeration)
["Kuwait City"] = {container = "Kuwait"}, -- 5,050,000 (Agglomeration)
["Bishkek"] = {container = "Kyrgyzstan"}, -- 1,540,000 (Agglomeration)
["Beirut"] = {container = "Lebanon"}, -- 1,930,000 (unindicated; population of low reliability)
-- Kuala Lumpur is a federal capital city, not in any state
["Kuala Lumpur"] = {container = "Malaysia"}, -- 9,550,000 (Agglomeration)
-- there are various George Towns and Georgetowns
["George Town, Malaysia"] = {container = {key = "Pulau Pinang, Malaysia", placetype = "negeri"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mongolia"}, -- 1,610,000 (City)
["Ulan Bator"] = {alias_of = "Ulaanbaatar", display = true},
["Yangon"] = {container = "Myanmar"}, -- 5,650,000 (Municipality (urban population))
["Rangoon"] = {alias_of = "Yangon", display = true},
["Mandalay"] = {container = "Myanmar"}, -- 1,600,000 (Municipality (urban population))
["Kathmandu"] = {container = "Nepal"}, -- 3,175,000 (Agglomeration)
-- Pyongyang is a directly governed city, not in any province
["Pyongyang"] = {container = "North Korea"}, -- 3,025,000 (Administrative Area (urban population))
["Muscat"] = {container = "Oman"}, -- 1,620,000 (Agglomeration)
["Gaza"] = {container = "Palestine", wp = "Gaza City"}, -- 2,275,000 (unindicated)
["Gaza City"] = {alias_of = "Gaza"},
["Doha"] = {container = "Qatar"}, -- 2,650,000 (Agglomeration)
["Colombo"] = {container = "Sri Lanka"}, -- 4,975,000 (unindicated)
["Damascus"] = {container = "Syria"}, -- 3,975,000 (unindicated; population of low reliability)
["Aleppo"] = {container = "Syria"}, -- 1,980,000 (unindicated; population of low reliability)
["Dushanbe"] = {container = "Tajikistan"}, -- 1,270,000 (City)
["Bangkok"] = {container = "Thailand"}, -- 21,800,000 (Agglomeration)
-- Chiang Mai not in citypopulation.de, but 1,198,000 urban population in 2021 per Wikipedia
-- [[w:List_of_municipalities_in_Thailand#Largest_cities_by_urban_population]]
["Chiang Mai"] = {container = {key = "Chiang Mai Province, Thailand", placetype = "province"}},
["Chonburi"] = {container = {key = "Chonburi Province, Thailand", placetype = "province"}}, -- 1,570,000 (Agglomeration; including Pattaya)
-- metro area population stats from https://www.statista.com/statistics/255483/biggest-cities-in-turkey/ as of 2021;
-- second source is citypopulation.de reference date 2025-01-01.
["Istanbul"] = {placetype = {"bandar", "province"}, divs = {"daerah"}, container = "Turkey"}, -- 15.2 million; 16,000,000 (Agglomeration)
["İstanbul"] = {alias_of = "Istanbul", display = true},
["Ankara"] = {container = {key = "Ankara Province, Turkey", placetype = "province"}}, -- 5.15 million; 5,200,000 (Agglomeration)
["Izmir"] = {container = {key = "İzmir Province, Turkey", placetype = "province"}, wp = "İzmir"}, -- 2.95 million; 3,025,000 (Agglomeration)
["İzmir"] = {alias_of = "Izmir", display = true},
["Bursa"] = {container = {key = "Bursa Province, Turkey", placetype = "province"}}, -- 2.02 million; 2,200,000 (Agglomeration)
["Adana"] = {container = {key = "Adana Province, Turkey", placetype = "province"}}, -- 1.77 million; 1,780,000 (Agglomeration)
["Gaziantep"] = {container = {key = "Gaziantep Province, Turkey", placetype = "province"}}, -- 1.71 million; 1,750,000 (Agglomeration)
["Antalya"] = {container = {key = "Antalya Province, Turkey", placetype = "province"}}, -- 1.3 million; 1,400,000 (Agglomeration)
["Konya"] = {container = {key = "Konya Province, Turkey", placetype = "province"}}, -- 1.35 million; 1,390,000 (Agglomeration)
["Diyarbakır"] = {container = {key = "Diyarbakır Province, Turkey", placetype = "province"}}, -- 1.07 million; 1,100,000 (Agglomeration)
-- Diyarbakır is more common per Ngrams and Google Scholar, but Diyarbakir is the Kurdish form, so we should not
-- display-canonicalize to the Turkish form Diyarbakır.
["Diyarbakir"] = {alias_of = "Diyarbakır"},
["Mersin"] = {container = {key = "Mersin Province, Turkey", placetype = "province"}}, -- 1.03 million; 1,060,000 (Agglomeration)
["Ashgabat"] = {container = "Turkmenistan"}, -- 1,150,000 (Agglomeration)
["Dubai"] = {container = "United Arab Emirates"}, -- 6,050,000 (Agglomeration; including Sharjah)
["Abu Dhabi"] = {container = "United Arab Emirates"}, -- 1,850,000 (City)
["Sharjah"] = {container = "United Arab Emirates"}, -- 1,800,000 (Metro area 2022-2023 per Wikipedia; separate from Dubai)
["Tashkent"] = {container = "Uzbekistan"}, -- 3,850,000 (unindicated)
["Sanaa"] = {container = "Yemen"}, -- 3,275,000 (City; population of low reliability)
["Sana'a"] = {alias_of = "Sanaa", display = true},
["Aden"] = {container = "Yemen"}, -- 1,079,060 (?; 2023 estimate from World Population Review per Wikipedia)
------------------ Europe or Europe-like (Caucasus etc.) ---------------------
["Yerevan"] = {container = "Armenia"}, -- 1,520,000 (Agglomeration)
["Vienna"] = {container = "Austria"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Belgium"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Belgium"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Republik Czech"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Republik Czech"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Republik Czech"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Denmark"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "wilayah"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Greece"},
["Thessaloniki"] = {container = "Greece"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "kaunti"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Belanda", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Belanda", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Belanda", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "wilayah"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "kaunti"}},
["Warsaw"] = {container = {key = "Masovian Voivodeship, Poland", placetype = "voivodeship"}},
["Katowice"] = {container = {key = "Silesian Voivodeship, Poland", placetype = "voivodeship"}},
--- Ngrams (up through 2022) and Google Scholar (>= 2024) confirms the common form "Krakow" without accent.
["Krakow"] = {container = {key = "Lesser Poland Voivodeship, Poland", placetype = "voivodeship"}, wp = "Kraków"},
["Kraków"] = {alias_of = "Krakow", display = true},
["Cracow"] = {alias_of = "Krakow", display = true},
--- Ngrams (up through 2022) and Google Scholar (>= 2024) confirm "Gdańsk" and "Poznań" with accent.
["Gdańsk"] = {container = {key = "Pomeranian Voivodeship, Poland", placetype = "voivodeship"}},
["Gdansk"] = {alias_of = "Gdańsk", display = true},
["Poznań"] = {container = {key = "Greater Poland Voivodeship, Poland", placetype = "voivodeship"}},
["Poznan"] = {alias_of = "Poznań", display = true},
--- Ngrams (up through 2022) and Google Scholar (>= 2024) confirms the common form "Lodz" without accents.
["Lodz"] = {container = {key = "Lodz Voivodeship, Poland", placetype = "voivodeship"}, wp = "Łódź"},
["Łódź"] = {alias_of = "Lodz", display = true},
["Lisbon"] = {container = {key = "Lisbon District, Portugal", placetype = "daerah"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "daerah"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Sweden"},
["Zurich"] = {container = "Switzerland"},
--- Ngrams (up through 2022) and Google Scholar (>= 2024) confirms the common form "Zurich" without umlaut.
--- Even Wikipedia uses the form without umlaut.
["Zürich"] = {alias_of = "Zurich", display = true},
["Kyiv"] = {container = "Ukraine"}, -- not in Kyiv Oblast
-- Don't display-canonicalize Kiev -> Kyiv because in ancient contexts, Kiev is still more common.
["Kiev"] = {alias_of = "Kyiv"},
["Kharkiv"] = {container = {key = "Kharkiv Oblast, Ukraine", placetype = "oblast"}},
["Odessa"] = {container = {key = "Odesa Oblast, Ukraine", placetype = "oblast"}, wp = "Odesa"},
-- Don't display-canonicalize Odesa -> Odessa because it may be interpreted as a political statement.
["Odesa"] = {alias_of = "Odessa"},
------------------ North America, South America ---------------------
-- Primary figures from citypopulation.de retrieved on 2025-04-26 (reference date 2025-01-01);
-- Wikipedia metropolitan figures from [[w:List of metropolitan areas in the Americas]] based on per-country data;
-- Wikipedia city limits figures from [[w:List of largest cities in the Americas]].
["Buenos Aires"] = {container = "Argentina"}, -- 16,800,000 (Consolidated Urban Area; 13,985,794 metropolitan area per Wikipedia)
["Córdoba, Argentina"] = {container = "Argentina", wp = "%l, %c"}, -- 1,810,000 (Consolidated Urban Area; 1,505,25 city limits per Wikipedia)
-- to avoid confusion with Córdoba in Spain
["Córdoba"] = {alias_of = "Córdoba, Argentina"},
["Cordoba"] = {alias_of = "Córdoba, Argentina", display = "Córdoba"},
["Rosario"] = {container = "Argentina", wp = "%l, Santa Fe"}, -- 1,510,000 (Consolidated Urban Area; 1,348,725 metropolitan area per Wikipedia)
["Mendoza"] = {container = "Argentina", wp = "%l, %c"}, -- 1,180,000 (Consolidated Urban Area)
["San Miguel de Tucumán"] = {container = "Argentina"}, -- 1,110,000 (Consolidated Urban Area)
["Tucumán"] = {alias_of = "San Miguel de Tucumán"},
["Tucuman"] = {alias_of = "San Miguel de Tucumán", display = "Tucumán"},
["Santa Cruz de la Sierra"] = {container = "Bolivia"}, -- 1,960,000 (Consolidated Urban Area); 1,606,671 (city limits per Wikipedia)
["Santa Cruz"] = {alias_of = "Santa Cruz de la Sierra"},
["La Paz"] = {container = "Bolivia"}, -- 1,870,000 (Consolidated Urban Area; composed of El Alto, now slightly larger, and La Paz)
["El Alto"] = {container = "Bolivia"},
["Cochabamba"] = {container = "Bolivia"}, -- 1,280,000 (Consolidated Urban Area)
["Santiago"] = {container = "Chile"}, -- 8,400,000 (Consolidated Urban Area; 6,903,479 city limits? per Wikipedia)
["Valparaíso"] = {container = "Chile"}, -- 1,060,000 (Consolidated Urban Area)
["Valparaiso"] = {alias_of = "Valparaíso"}, -- 1,060,000 (Consolidated Urban Area)
["Bogotá"] = {container = "Colombia"}, -- 10,600,000 (Agglomeration; 12,772,828 metropolitan area per Wikipedia)
["Bogota"] = {alias_of = "Bogotá", display = true},
["Medellín"] = {container = "Colombia"}, -- 4,350,000 (Agglomeration; 4,068,000 metropolitan area per Wikipedia)
["Medellin"] = {alias_of = "Medellín", display = true},
["Cali"] = {container = "Colombia"}, -- 2,975,000 (Agglomeration; 2,837,000 metropolitan area per Wikipedia)
["Barranquilla"] = {container = "Colombia"}, -- 2,375,000 (Agglomeration; 1,341,160 city limits per Wikipedia)
["Bucaramanga"] = {container = "Colombia"}, -- 1,380,000 (Agglomeration)
["Cartagena, Colombia"] = {container = "Colombia", wp = "%l, %c"}, -- 1,250,000 (Agglomeration)
-- to avoid confusion with Cartagena, Spain
["Cartagena"] = {alias_of = "Cartagena, Colombia"},
["Cúcuta"] = {container = "Colombia"}, -- 1,130,000 (Agglomeration)
["Cucuta"] = {alias_of = "Cúcuta", display = true},
-- to avoid conflict with San Jose, California
["San José, Costa Rica"] = {container = "Costa Rica", wp = "%l, %c"}, -- 2,450,000 (Municipality (urban population); 3,160,000 metropolitan area per Wikipedia)
["San José"] = {alias_of = "San José, Costa Rica"},
["San Jose"] = {alias_of = "San José, Costa Rica"}, -- display = "San José"; causes error due to San Jose alias for California city; FIXME
["Havana"] = {container = "Cuba"}, -- 2,150,000 (City; 2,137,847 city limits? per Wikipedia)
["Santo Domingo"] = {container = "Dominican Republic"}, -- 3,900,000 (Municipality (urban population); 4,274,651 ??? per Wikipedia)
["Guayaquil"] = {container = "Ecuador"}, -- 3,350,000 (Agglomeration; 3,092,000 metro area? per Wikipedia)
["Quito"] = {container = "Ecuador"}, -- 2,875,000 (Agglomeration; 2,889,703 metro area? per Wikipedia)
["San Salvador"] = {container = "El Salvador"}, -- 1,580,000 (Municipality (urban population))
["Guatemala City"] = {container = "Guatemala"}, -- 3,375,000 (Municipality (urban population); 3,160,000 metro area? per Wikipedia)
["Port-au-Prince"] = {container = "Haiti"}, -- 3,050,000 (Agglomeration; population of low reliability; 2,915,000 metro area? per Wikipedia)
["San Pedro Sula"] = {container = "Honduras"}, -- 1,330,000 (Consolidated Urban Area)
["Tegucigalpa"] = {container = "Honduras"}, -- 1,220,000 (Urban Area)
["Managua"] = {container = "Nicaragua"}, -- 1,400,000 (Consolidated Urban Area)
["Panama City"] = {container = "Panama"}, -- 1,430,000 (Urban Area)
["Asunción"] = {container = "Paraguay"}, -- 2,350,000 (Municipality (urban population))
["Lima"] = {container = "Peru"}, -- 12,000,000 (Agglomeration; 11,283,787 ??? per Wikipedia)
["Arequipa"] = {container = "Peru"}, -- 1,210,000 (Agglomeration)
["San Juan"] = {container = {key = "Puerto Rico", placetype = "commonwealth"}, wp = "%l, %c"}, -- 1,910,000 (Consolidated Urban Area)
["Montevideo"] = {container = "Uruguay"}, -- 1,810,000 (Agglomeration; 1,302,954 ??? per Wikipedia)
["Caracas"] = {container = "Venezuela"}, -- 3,850,000 (Consolidated Urban Area; 5,243,301 ??? per Wikipedia)
["Maracaibo"] = {container = "Venezuela"}, -- 2,825,000 (Consolidated Urban Area; 5,278,448 ??? per Wikipedia)
-- to avoid confusion with Valencia (city and autonomous community of Spain)
["Valencia, Venezuela"] = {container = "Venezuela", wp = "%l, %c"}, -- 2,100,000 (Consolidated Urban Area)
["Valencia"] = {alias_of = "Valencia, Venezuela"},
["Maracay"] = {container = "Venezuela"}, -- 1,480,000 (Consolidated Urban Area)
["Barquisimeto"] = {container = "Venezuela"}, -- 1,360,000 (Consolidated Urban Area)
}
export.misc_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(nil, "negara"),
default_placetype = "bandar",
data = export.misc_cities,
}
--[==[ var:
List of all known locations, in groups. The first group lists continents and continental regions, followed by three
groups listing top-level locations: countries, "country-like entities" (de-facto/unrecognized/etc. countries and
dependent territories) and former polities (countries, empires, etc.). After that come first-level subpolities
(administrative divisions) of several, mostly large, countries, followed by groups of cities. China and the United
Kingdom include second-level subpolities (in the case of China, only the largest ones as the full list runs in the
hundreds).
]==]
export.locations = {
export.continents_group,
export.countries_group,
export.country_like_entities_group,
export.former_countries_group,
export.australia_group,
export.austria_group,
export.bangladesh_group,
export.brazil_group,
export.canada_group,
export.china_group,
export.china_prefecture_level_cities_group,
export.china_prefecture_level_cities_group_2,
export.egypt_group,
export.finland_group,
export.france_group,
export.france_departments_group,
export.germany_group,
export.greece_group,
export.india_group,
export.indonesia_group,
export.iran_group,
export.ireland_group,
export.italy_group,
export.japan_group,
export.laos_group,
export.lebanon_group,
export.malaysia_group,
export.malta_group,
export.mexico_group,
export.moldova_group,
export.morocco_group,
export.netherlands_group,
export.new_zealand_group,
export.nigeria_group,
export.north_korea_group,
export.norway_group,
export.pakistan_group,
export.philippines_group,
export.poland_group,
export.portugal_group,
export.romania_group,
export.russia_group,
export.saudi_arabia_group,
export.south_africa_group,
export.south_korea_group,
export.spain_group,
export.taiwan_group,
export.thailand_group,
export.turkey_group,
export.ukraine_group,
export.united_kingdom_group,
export.united_states_group,
export.england_group,
export.northern_ireland_group,
export.scotland_group,
export.wales_group,
export.vietnam_group,
export.australia_cities_group,
export.brazil_cities_group,
export.canada_cities_group,
export.france_cities_group,
export.germany_cities_group,
export.india_cities_group,
export.indonesia_cities_group,
export.italy_cities_group,
export.japan_cities_group,
export.mexico_cities_group,
export.nigeria_cities_group,
export.pakistan_cities_group,
export.philippines_cities_group,
export.russia_cities_group,
export.saudi_arabia_cities_group,
export.south_korea_cities_group,
export.spain_cities_group,
export.taiwan_cities_group,
export.united_kingdom_cities_group,
export.united_states_cities_group,
export.new_york_boroughs_group,
export.vietnam_cities_group,
export.misc_cities_group,
}
return export
crjve337t9971s9aeob8clks2dvlqdx
Modul:place
828
76178
375874
344220
2026-09-25T12:51:05Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/92708922|92708922]])
375874
Scribunto
text/plain
local export = {}
local force_cat = false -- set to true for testing
local m_placetypes = require("Module:place/placetypes")
local m_links = require("Module:links")
local memoize = require("Module:memoize")
local m_strutils = require("Module:string utilities")
local m_table = require("Module:table")
local debug_track_module = "Module:debug/track"
local en_utilities_module = "Module:en-utilities"
local form_of_module = "Module:form of"
local languages_module = "Module:languages"
local parse_interface_module = "Module:parse interface"
local parse_utilities_module = "Module:parse utilities"
local parameter_utilities_module = "Module:parameter utilities"
local utilities_module = "Module:utilities"
local enlang = require(languages_module).getByCode("en")
local rmatch = m_strutils.match
local rfind = m_strutils.find
local split = m_strutils.split
local dump = mw.dumpObject
local insert = table.insert
local concat = table.concat
local pluralize = require(en_utilities_module).pluralize
local extend = m_table.extend
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local internal_error = m_placetypes.internal_error
local placetype_data = m_placetypes.placetype_data
--[==[ intro:
===Introduction===
This module implements {{tl|place}}, which is a template for standardizing the description and categorization of
toponyms (terms that refer to locations such as cities, countries, rivers, etc.). The following modules support this
template:
* [[Module:place]]: The main module.
* [[Module:place/placetypes]]: A module containing data on placetypes, as well as utilities for working with placetypes;
category generation handlers for adding categories based on placetypes; and display handlers for displaying holonyms
(i.e. containing locations) of a specific type. FIXME: Maybe split out the code from the data.
* [[Module:place/locations]]: A module containing data on known locations, as well as utilities for working with
such locations. FIXME: Maybe split out the code from the data.
* [[Module:category tree/topic/Places]]: A category tree module for generating the descriptions of all
categories generated by {{tl|place}}.
* [[Module:place doc]]: A module that generates documentation tables describing known placetypes and locations.
===Basic terminology===
The basic terminology used in this and associated {{tl|place}} modules is:
* A ''location'' (or equivalently, a ''place'') is any geographic feature (either natural or geopolitical), either on
the surface of the Earth or elsewhere. Examples of types of natural places are rivers, mountains, seas and moons;
examples of types of geopolitical places are cities, countries, neighborhoods and roads. A ''known location'' is
specifically a location whose properties are specified in the {{tl|place}} modules; more on them below.
* Specific places are identified by names, referred to as ''toponyms'' or ''placenames''. A given place will often have
multiple names, and a given toponym may be ambiguous, referring to multiple possible locations. Specifically:
** There may be names including different amounts of disambiguating information (`Tucson` vs. `Tucson, Arizona` vs.
`Tucson, Arizona, USA` or `New York` vs. `New York City` vs. `New York, New York`); abbreviations (`NYC`
for `New York City`, `USA` for `United States of America`); ''official'' vs. ''short'' names (e.g.
`Union of Soviet Socialist Republics` vs. `Soviet Union`); spelling variations (`Cracow` vs. `Krakow` vs. `Kraków`);
current vs. former names (`Saint Petersburg` vs. `Leningrad` vs. `Petrograd`); [[exonym]]s vs. [[endonym]]s (e.g.
`Tavastia Proper` vs. `Kanta-Häme`, both referring to the same administrative region in Finland); alternative names
not due to any of the above reasons (`Bashkiria` vs. `Bashkortostan`); etc. In addition, each language that has an
opportunity to refer to the place will have its own name, with the same sorts of variations as exist in English.
** Examples of ambiguous toponyms are `New York` (either a city or a state); `Georgia` (either a state of the US or an
independent country in the Caucasus Mountains); `Paris` (either the capital of France or various small cities and
towns in the US); `Mexico` (either a country, a state of that country, or the capital city of that country); and
`San Antonio` (besides being a major city in Texas, it is the name of dozens of settlements of all sorts throughout
the US and Latin America, and a least 181 distinct [[barangay]]s in the Philippines).
* A ''placetype'' is the (or a) type that a location belongs to (e.g. `city`, `state`, `river`, `administrative region`,
`[[regional county municipality]]`, etc.).
** It is common for locations to be described using multiple placetypes, and even sometimes known locations have
multiple placetypes that they may be identified by (e.g. American Samoa can be identified either as an
`unincorporated territory`, an `overseas territory` or just a `territory`). Both the {{tl|place}} template and the
known location data allow a given location to be identified by multiple placetypes. When in doubt as to the correct
placetype or placetypes for a given location, generally follow how Wikipedia describes the place.
** Some placetypes themselves are ambiguous; e.g. an ''area'' can variously refer to a top-level administrative division
(specifically of Kuwait); a geographic region, generally without unambiguously defined borders; or a section of a
city, similar to a neighborhood. The term ''district'' is similarly ambiguous. A ''[[prefecture]]'' in the context of
Japan is similar to a province, but a prefecture in France is the capital of a ''[[department]]'' (which is similar
to a county). Some of this ambiguity is currently handled automatically; e.g. the ambiguity of areas and districts is
handled by looking at the ''holonyms'', or containing locations, specified for a given place. But sometimes it is
necessary to use a qualifier before the placetype to disambiguate; for example to refer to a French prefecture, use
the placetype `French prefecture` instead of just `prefecture`. (FIXME: Handle this automatically.)
* A ''holonym'', in the context of a description of a place, is a placename that refers to a larger-sized entity that
contains the location being described. For example, `Arizona` and `United States` are holonyms of `Tucson`, and
`United States` is a holonym of `Arizona`.
* A ''place invocation'' consists of the invocation of {{tl|place}}, including all its parameters. Place invocations
may contain one or more ''place descriptions'', each of which provides a description of the location, including its
placetype or types, any holonyms, and any additional raw text needed to properly explain the place in context. Place
invocations may also contain named parameters specifying zero or more English ''glosses'' or translations (for
foreign-language toponyms) and any attached ''extra information'' such as the capital, largest city, official name,
modern name or full name. Multiple place descriptions in a single invocation are separated by a numbered parameter
starting with a semicolon, and are used when it is necessary to provide two or more definitions of a single location
for proper categorization. For example, [[Vatican City]] is defined both as a city-state in Southern Europe and as an
enclave within the city of Rome, follows:
: {{tl|place|en|city-state|r/Southern Europe|;,|an <<enclave>> within the city of [[Rome]], [[Italy]]|cat=Places in Rome|official=Vatican City State}}.
Similar things need to be done for places like [[Crimea]] that are claimed by two different countries with different
definitions and administrative structures.
** There are two types of place descriptions, ''new-style'' and ''old-style''. (The use of the terms "new" and "old"
indicates chronological precedence in the development of {{tl|place}}, but is not meant to pass any value judgments
on the two types, and does not indicate any intent to deprecate old-style descriptions. Both types of descriptions
are useful; for example, old-style descriptions are generally more succinct but less flexible.) The above invocation
shows both types: an old-style description followed by a new-style description. Old style descriptions use multiple
numbered parameters, where the first parameter (after the language code) specifies the placetype or types, and
following parameters specify either holonyms (which are always of the form ` ``placetype``/``placename`` `) or raw
text (which is identifiable by not having a slash in it). New-style descriptions use a single parameter, where both
placetypes and holonyms are surrounded by double angle brackets, and all remaining text is raw (displayed as-is). In
both types of descriptions, holonyms include a slash in them to separate the placetype (which is mandatory and often
abbreviated) from the placename.
** In the context of a place description, there are two types of placetypes. The ''entry placetypes'' are the placetypes
of the place being described, while the ''holonym placetypes'' are the placetypes of the holonyms that the place
being described is located within. Currently, a given place can have multiple placetypes specified (e.g. [[Normandy]]
is specified using the ''compound placetype'' `administrative region/former province/and/medieval kingdom`) while a
given holonym can have only one placetype associated with it. Holonym placetypes are frequently abbreviated (e.g.
`r` for `region`, `s` for `state`, `co` for `county`, etc.), while stylistically it is preferred to spell out the
entry placetype (except for some long placetypes with well-known abbreviations, such as `CDP` or `cdp` for
`[[census-designated place]]`).
** All holonyms in place descriptions are automatically linked as if surrounded by {{tl|l|en|...}}; i.e. if double
brackets do not occur in the holonym, the entire holonym will be linked to the corresponding Wiktionary article. For
this reason, the holonym should generally be in the same format as the canonical Wiktionary article describing the
location; see below).
* A ''known location'' is a location whose properties are specifically defined in the {{tl|place}} modules. Generally
each such location has an associated category, and known locations exist in a containment hierarchy, where the
immediately containing known location is known as the ''container'' of the location and the chain of successive
containing locations is known as the ''container trail''. Generally the location's container corresponds to the first
parent of its category. Note that some known locations belong to more than one immediate container; for example,
Russia belongs to both Europe and Asia.
===More about placetypes===
# The following general categories of placetypes exist:
## ''Natural features'' such as lakes, mountains, mountain ranges, islands, archipelagoes, moons, stars, asteroids, etc.
## ''Continents'', ''supercontinents'' (groupings of continents where it makes sense, such as `America` and `Eurasia`)
and ''continent-level regions'' (grouping of countries in a given continent, such as `Central America` and
`Polynesia`).
## ''Political entities'', which are generally classified as either ''polities'' (top-level entities such as countries),
''subpolities'' or ''political divisions'' (non-sovereign divisions, often specifically ''administrative divisions'',
of a polity, where an administrative division has a governmental or statistical function and almost always has
unambiguously defined boundaries), or ''settlements'' (e.g. cities; towns; villages; and divisions of a city such as
neighborhoods, wards, [[barrio]]s and [[barangay]]s, which may or may not be formal administrative divisions and
may or may not have unambiguous boundaries).
## ''Geographic regions'', which refer to recognized areas of the Earth (either with a natural geographic, political or
cultural significance, often of a historical nature). Such regions can be of greatly varying size, may exist either
within a single country or spanning multiple countries or (more often) parts of multiple countries, and may not have
well-defined boundaries. They should be distinguished from ''administrative regions'', which exist within a single
country and have well-defined boundaries and a political or administrative function. Geographic regions are
categorized using the generic term ''geographic and cultural areas'' to emphasize that (a) they have no
administrative significance; (b) they may vary greatly in size; and (c) their cohesion is due either to natural
geographic boundaries, such as rivers or mountain ranges, or to sharing some cultural characteristics.
## ''Man-made structures'' below the level of a settlement or neighborhood, such as airports, roads, individual
buildings, and the like. (Note that such structures, even if named, often do not meet the [[WT:CFI]] criteria; this
is particularly the case for roads.)
# Placetypes support aliases, and the mapping to canonical form happens early on in the processing. For example, `state`
can be abbreviated as `s`; `administrative region` as `adr`; `regional county municipality` as `rcomun`; etc. Some
placetype aliases handle alternative spellings rather than abbreviations. For example, `departmental capital` maps to
`department capital`, and `home-rule city` maps to `home rule city`. Placetype abbreviations are particularly useful
in holonym specs, because every holonym must be accompanied by its placetype, for disambiguation purposes.
# A ''placetype qualifier'' is an adjective prepended to the placetype to give additional information about the
place being described. For example, a given place may be described as a `small city`; logically this is still a city,
but the qualifier `small` gives additional information about the place. Multiple qualifiers can be stacked, e.g.
`small affluent beachfront unincorporated community`, where `unincorporated community` is a recognized placetype and
`small`, `affluent` and `beachfront` are qualifiers. (As shown here, it may not always be obvious where the qualifiers
end and the placetype begins.) For the most part, placetype qualifiers do not affect categorization; a `small city`
is still a city and an `affluent beachfront unincorporated community` is still an unincorporated community, and both
should still be categorized as such. But some qualifiers do change the categorization. In particular, a
`former province` is no longer a province and should not be categorized in e.g. [[:Category:Provinces of Italy]], but
instead in a different set of categories, e.g. [[:Category:Historical political subdivisions]]. There are several
terms treated as equivalent for this purpose: `abandoned` `ancient`, `extinct`, `historic(al)`, `medi(a)eval` and
`traditional`. Another set of qualifiers that change categorization are `fictional` and `mythological`, which cause
any term using the qualifier to be categorized respectively into [[:Category:Fictional locations]] and
[[:Category:Mythological locations]].
===More about toponyms===
# Toponyms may be:
## ''simple'' (not including any containing location in its name, such as `Tucson`) or ''multipart'' (including one or
more containing locations, such as `Tucson, Arizona` or `Tucson, USA` or even `Tucson, Arizona, USA`);
## ''bare'' (not including the word `the` if the location normally requires this article when following a preposition,
such as `United States`, `Gambia` or 'Community of Madrid') or ''prefixed'' (including the word `the` as needed, such
as `the United States`, `the Gambia` or `the Community of Madrid`);
## ''elliptical'' (just the placename without any disambiguating placetype, such as `Durham`, `New York` or `Mexico`) or
''full'' (containing a disambiguating placetype or similar identifier if one is commonly included, such as
the city of `Durham` (in England) vs. its containing county `County Durham`; the US city `New York City` vs. its
containing state `New York`; or the three-way distinction between `Mexico` (the country), `Mexico City` (the capital
of this country) and `(the) State of Mexico` (one of the states of the country Mexico, mostly surrounding but not
including Mexico City)).
# The ''canonical Wiktionary article'' is the main article on Wiktionary where a location is described. Canonical
articles, per the above terminology, are generally ''simple'' and ''bare'', but may be either ''full'' or
''elliptical''. The fact that a given article is canonical is often identifiable by the fact that translations are
housed there an not somewhere else. For example, most counties of the US and Canada include the word `County` in their
canonical article name, but most counties elsewhere do not. `Washington, D.C.` is one of the few cases where a
non-simple toponym is used as the canonical article; this is based on common usage, especially by residents of the
city in question (who commonly refer to it as "D.C." but rarely just as "Washington").
===More about known locations===
# The following types of known locations are defined in this module:
## Continents, supercontinents and continent-level regions, into which countries are grouped. Specifically:
### At the top level below `Earth` are the supercontinents `America` and `Eurasia` and the continents `Africa`,
`Oceania` and `Antartica`.
### `America` is further broken down into the continents `North America` (in turn containing the continental regions
`Central America` and `Caribbean`, with the United States, Canada and Mexico directly under North America) and
`South America`.
### `Eurasia` is further broken down into the continents `Europe` and `Asia`.
### `Oceania` is further broken down into the continental regions `Melanesia`, `Micronesia` and `Polynesia`, with
Australia` directly under `Oceania.
### Under the above-specified divisions are countries. Some countries are placed in more than one continent or
continent-level region, either because they actually span two continents (e.g. Russia, Turkey, Kazakhstan, Egypt) or
because they are politically considered to belong to a continent different from the one they are geographically in
(Cyprus, Georgia, Armenia, etc.).
## Political entities, including:
### Top-level political entities, which includes:
#### Countries, with a fairly liberal definition, notably including all UN-recognized countries plus some others that
are commonly considered countries, even if not all other countries recognize them as such or consider them
completely independent (notably, Kosovo, Palestine, Taiwan, Western Sahara, Niue and the Cook Islands).
#### Pseudo-countries, which include areas calling themselves countries that are de-facto not under the control of the
country that they are internationally considered part of (e.g. Abkhazia, South Ossetia, Transnistria);
dependent/external/etc. territories of countries (e.g. American Samoa [US], Bermuda [UK], Christmas Island
[Australia], Easter Island [Chile]); constituent countries, autonomous territories and the like (Aruba, Curaçao and
Sint Maarten of the Netherlands; Greenland and the Faroe Islands of Denmark; etc.; but notably not including
England, Scotland, Northern Ireland and Wales, which are treated as regular countries); and a grab bag of other
entities that have a semi-independent existence, such as Hong Kong, Macau, Guadeloupe, Martinique and the like.
Currently, the actual distinction in treatment between "countries" and "country-like entities" is minimal, but in
the future we might restrict the sorts of subcategories of country-like entities more than regular countries.
#### Former countries, e.g. the Soviet Union, Yugoslavia, West Germany and the Roman Empire. These are much more limited
in the sorts of subcategories allowed, because generally locations, especially cities, should be described from the
perspective of which political entity they are currently located in (e.g. "an ancient Roman town in modern Syria")
and categorized as such.
### Subpolities. Generally we only list top-level administrative divisions of countries (and only fairly major countries
are usually included), but sometimes we list second-level administrative divisions, as in the case of the
United Kingdom (where the top-level administrative divisions of the four constituent countries are listed) and China
(where major prefecture-level cities are listed, and are considered administrative divisions rather than cities).
### Cities. Only major cities get categories, with the definition of "major" varying by country but often including
those where the city population itself (sometimes the metro area) is >= 1,000,000 people.
# A distinction should be made in the {{tl|place}} modules between ''keys'' and ''placenames''. Placenames are as the
location appears in a holonym, and are generally in the same format as the canonical Wiktionary article describing the
location so that when formatted as a link, the link goes to the right article; i.e. they are simple and bare, and may
be full or elliptical according to Wiktionary conventions. The ''canonical key'' of a location is how the location's
category is named, and always uniquely identifies the location from among the known locations in this module (but
not necessarily among all possible locations). In particular, subpolities usually have multipart keys that include the
containing location, such as `Anhui, China` (not just `Anhui`); `Arizona, USA` (not just `Arizona`, and also not
`Arizona, United States`); and `Herefordshire, England` (not just `Herefordshire`, and also in this case not
`Herefordshire, UK` or `Herefordshire, England, UK` or any other possible variation). Cities are normally simple, but
some cities are multipart for disambiguation purposes (e.g. `Newcastle, New South Wales` for the city in Australia vs.
`Newcastle upon Tyne` for the identically-named city in England). Canonical keys may have ''key aliases'', other
ways of referring to the location that are not necessarily unique (e.g. `Newcastle` is a key alias for both of the
above-mentioned cities), and city keys with diacritics generally have diacriticless aliases, such as canonical key
`Düsseldorf` vs. key alias `Dusseldorf`, or canonical key `Łódź` vs. key alias `Lodz`.
# Known locations are gathered into ''groups'' with similar properties, such as all the states of the United States;
all the (ceremonial) counties of England (see below); and all the "sufficiently major" prefecture-level cities in
China (where a prefecture-level city is a prefecture surrounding a major city with a unified government and is more
like a prefecture, i.e. a major administrative division just underneath a province, than like a city, and where
"sufficiently major" is defined according to the population of either the total prefecture or the urban area of the
city). Note that there are multiple types of counties in England, with overlapping but non-identical names and
boundaries; there are, in particular, ''ceremonial counties'', ''local government counties'' and ''historic
counties''; ''ceremonial counties'' have only ceremonial administrative functionality but unlike local government
counties (a) don't frequently change their boundaries or nature, (b) correspond more closely to historic county
boundaries and names, and (c) are what Englanders usually identify themselves with, and so they are used as top-level
divisions rather than local government counties.
# Some known locations have ''aliases'' defined, which are of two types. ''Display aliases'' map holonyms to their
canonical form near the beginning of processing (in particular before the displayed output is formatted). For example,
`US`, `U.S.`, `USA`, `U.S.A.` and `United States of America` are all canonicalized to `United States` (if identified
as a country), and display as `United States`. Similarly, the foreign forms `Occitanie` (as a region or administrative
region) and `Noord-Brabant` (as a province) are mapped to `Occitania` and `North Brabant` for display purposes. There
are also ''category aliases'', so that if e.g. `Republic of Macedonia` is encountered, it will display as such but
categorize as `North Macedonia`. (This is because, among other reasons, `Republic of Macedonia` is normally preceded
by `"the"` while `North Macedonia` is not, so a call {{tl|place|en|a <<city>> in the <<c/Republic of Macedonia>>}}
would look wrong if `Republic of Macedonia` were converted to `North Macedonia` during display, as the result would be
`a city in the North Macedonia`. There are also frequently political connotations to different category aliases, e.g.
`Burma` vs. `Myanmar`.) All of these aliases are sensitive to the placetype specified. For example, `Mexico` as a
state is categorized under `State of Mexico, Mexico` but `Mexico` the country is categorized as just `Mexico`.
===Categories===
There are two main types of categories:
# Categories for known locations, divided into:
## Top-level polity categories (e.g. [[:Category:United States]], [[:Category:Taiwan]], [[:Category:South Ossetia]],
[[:Category:Bermuda]], [[:Category:Soviet Union]], [[:Category:West Germany]]).
## Subpolity categories ([[:Category:Arizona, USA]], [[:Category:Hunan]], [[:Category:Kagoshima Prefecture]],
[[:Category:Cluj County, Romania]]). For historical reasons, different formats are used for the subpolities of
different polities. Increasingly, we are moving towards always including the polity name in the subpolity category,
but whether the subpolity type is included and where it is included (cf. [[:Category:Cluj County, Romania]] vs.
[[:Category:County Cork, Ireland]] is still inconsistent and will probably remain that way, based on how the
subpolity is normally referred to.
## City categories ([[:Category:Tokyo]], [[:Category:New York City]], [[:Category:Jaipur]]). Normally these do not
include the containing subpolity, but may do so in order to disambiguate.
# Categories for placetypes, divided into:
## "Immediate" political and non-political division categories ([[:Category:States of the United States]],
[[:Category:Municipalities of Tocantins, Brazil]], [[:Category:Ghost towns in Arizona, USA]]). These are name
categories, whose purpose is to contain locations of the specified type. "Immediate" here refers to the fact that
the location in the category name is the immediately-containing polity. Usually these categories use the preposition
"of", but sometimes "di". (Specifically, "of" typically implies that the placetype in question has an official or
semi-official status, whereas "di" implies there is no such official status, but common usage may override this.)
The form of the toponym appearing in these categories is always the same as that of the corresponding toponym
category except that the word "the" may appear (e.g. [[:Category:States of the United States]]), whereas it doesn't
appear in the toponym category itself ([[:Category:United States]], no "the").
## "Skip-polity" categories for second-level political and non-political divisions of a country or other top-level
polity (e.g. [[:Category:Counties of the United States]], [[:Category:Municipalities of Brazil]] and
[[:Category:Subprefectures of Japan]]). These have several purposes:
* They group the immediate division categories mentioned previously.
* They categorize "straggler" topoynms that (often improperly) fail to mention the subpolity they belong to, but
only the top-level polity.
* If categories do not exist for the first-level divisions of a country (and sometimes even when they do), they group
all toponyms of the specified type for the specified country. For example, Lithuania is divided into first-level
counties and second-level municipalities, but since we don't currently have categories for Lithuanian counties,
all municipalities go under [[:Category:Municipalities of Lithuania]] rather than under a category for a specific
county. In addition, even though we do have categories for Japanese prefectures (a first-level division), all
subprefectures (a second-level division) go under [[:Category:Subprefectures of Japan]] because there aren't very
many of them (see below).
## "Generic placetype" categories, both of the immediate and skip-polity type (immediate
[[:Category:Cities in California, USA]] and [[:Category:Neighborhoods of the Bronx]]; skip-polity
[[:Category:Villages in Ivory Coast]], [[:Category:Geographic and cultural areas of England]],
[[:Category:Rivers in Egypt]] and [[:Category:Places in the Philippines]]). As mentioned above, "generic" placetypes
occur in every polity (although the set of generic placetypes allowed for cities is a subset of those allowed for
top-level polities and subpolities). Usually these categories use the preposition "di", but sometimes "of". As above,
skip-polity categories group immediate categories, and in addition there are various reasons a toponym entry is
categorized into a skip-polity category. (For example, as a general rule, geographic and cultural areas only
categorize at the country level, not the subpolity level, both because there often aren't very many in a given
country and because they often span multiple subpolities.)
The parent categories of a given category depend on its type. Generally, location categories have placetype categories
as their first parent, and vice-versa. Specifically:
# Top-level country categories have as their parent e.g. [[:Category:Countries in Europe]],
[[:Category:Countries in Central America]] or [[:Category:Countries in Polynesia]], using the most specific
continental-level region the country is contained in.
# Pseudo-countries are under [[:Category:Country-like entities]] as a neutral designation. There aren't enough of them
to subcategorize under continent-level regions.
# Former countries are under [[:Category:Former countries and country-like entities]].
# Subpolity categories are usually under a placetype category whose placetype is the canonical (first-listed) placetype
of the subpolity and whose toponym is the immediately containing polity, but there are exceptions. Specifically,
sometimes if a polity has multiple types of subpolities, they are combined (e.g. [[:Category:States and territories of
Australia]], [[:Category:Federal subjects of Russia]]). In addition, sometimes a less specific but more identifiable
placetype is used instead of the canonical one (e.g. [[:Category:Regions of France]] when the canonical placetype is
"administrative region"). The same rules and exceptions generally apply when categorizing subpolities themselves; e.g.
both the Australian state of Queensland and territory of Northern Territory go under
[[:Category:en:States and territories of Australia]] rather than separately under [[:Category:en:States of Australia]]
and [[:Category:en:Territories of Australia]]. In addition, sometimes subpolities may "skip a level" if there aren't
very many. For example, there are only 26 subprefectures of Japan (14 under Hokkaido and 12 more scattered under five
other prefectures). Rather than have e.g. [[:Category:en:Subprefectures of Kagoshima Prefecture]] containing at most
two entries and [[:Category:en:Subprefectures of Miyazaki Prefecture]] containing at most one, they are all grouped
under the so-called "skip-subpolity category" [[:Category:en:Subprefectures of Japan]].
# City categories are always under e.g. [[:Category:Cities in the United States]] (e.g. [[:Category:New York City]] is
so-placed, even though [[:Category:Cities in New York, USA]] exists). However, they may have a second, more-specific
parent (e.g. [[:Category:Cities in New York, USA]] in the case of New York City). The city entries themselves will
go under the more specific parent if it exists.
# Immediate placetype categories for second-level divisions of a country generally have, respectively, a
"toponym parent" that is the toponym mentioned in the category and a "skip-polity parent" that groups all subpolity
placetype categories of a specific type and containing polity. For example, [[:Category:Counties of Arizona, USA]] has
toponym parent [[:Category:en:Arizona, USA]] and skip-polity parent [[:Category:en:Counties of the United States]].
Sometimes the default skip-polity parent is overridden or disabled entirely. For example, in the US, most states are
divided into counties but Louisiana is divided into parishes and Alaska into boroughs. It would make no sense to put
[[:Category:Parishes of Louisiana, USA]] under [[:Category:Parishes of the United States]] (which would only have one
subcategory), so we include them under [[:Category:Counties of the United States]]. An alternative would be to name
the skip-polity category to explicitly include parishes and boroughs; this would get awkward here but is done in some
cases. Similarly, [[:Category:Regional county municipalities of Quebec]] is placed under
[[:Category:Regional municipalities of Canada]] since that name is used in other provinces. Meanwhile,
[[:Category:Regional districts of British Columbia]] disables its skip-polity category since no other province or
territory of Canada has regional districts or comparable subpolities under a different name (an alternative would be
to place them under [[:Category:Counties of Canada]], since they are sort of comparable to counties).
# Placetype categories for first-level divisions of a country similarly (e.g. [[:Category:States of the United States]])
have a toponym parent (in this case [[:Category:United States]]), but in place of the skip-polity parent they have two
other parents: a "bare placetype" parent (in this case [[:Category:States]]) and the "generic" parent
[[:Category:Political divisions of specific countries]]. (There is also a bare [[:Category:Political divisions]]
that groups "bare placetype" categories.) Skip-polity placetype categories for second-level divisions of a country
(e.g. [[:Category:Counties of the United States]]) work the same. Placetype categories for countries work likewise
except they are missing the generic parent.
===Place descriptions===
A given place description is defined internally in a table of the following form:
```{
placetypes = {"``placetype``", "``placetype``", ...},
holonyms = {
{ -- holonym object; see below
placetype = "``placetype``" or nil,
display_placename = "``placename``",
unlinked_placename = "``placename``",
langcode = "``langcode``" or nil,
no_display = BOOLEAN,
needs_article = BOOLEAN,
force_the = BOOLEAN,
affix_type = "``affix_type``" or nil,
pluralize_affix = BOOLEAN,
suppress_affix = BOOLEAN,
continue_cat_loop = BOOLEAN,
},
...
},
order = { ``order_item``, ``order_item``, ... }, -- (only for new-style place descriptions),
joiner = "``joiner_string``" or nil,
holonyms_by_placetype = {
``holonym_placetype`` = {"``placename``", "``placename``", ...},
``holonym_placetype`` = {"``placename``", "``placename``", ...},
...
},
}```
Holonym objects have the following fields:
* `placetype`: The canonicalized placetype if specified as e.g. `c/Australia`; nil if no slash is present (in which case
the placename in `display_placename` refers to raw text).
* `display_placename`: The placename or raw text, in the format to be displayed. Placename display aliases have already
been resolved. It is raw text if `placetype` is nil.
* `unlinked_placename`: Same as `display_placename` but with links and HTML removed.
* `langcode`: The language code prefix if specified as e.g. `c/fr:Australie`; otherwise nil.
* `no_display`: If true (holonym prefixed with !), don't display the holonym but use it for categorization.
* `needs_article`: If true, prepend an article if the placename needs one (e.g. `United States`).
* `force_the`: If true, always prepend the article `the`. Example use: holoynm 'city:pref:the/Gold Coast', which gets
formatted as `(the) city of the [[Gold Coast]]`.
* `affix_type`: Type of affix to prepend (values `pref` or `Pref`) or append (values `suf` or `Suf`). The actual affix
added is the placetype (capitalized if values `Pref` or `Suf` are given), or its plural if
`pluralize_affix` is given. Note that some placetypes (e.g. `district` and `department`) have inherent
affixes displayed after (or sometimes before) them.
* `pluralize_affix`: Pluralize any displayed affix. Used for holonyms like `c:pref/Canada,US`, which displays as
`the countries of Canada and the United States`.
* `suppress_affix`: Don't display any affix even if the placetype has an inherent affix. Used for the non-last
placenames when there are multiple and a suffix is present, and for the non-first placenames when
there are multiple and a prefix is present.
* `continue_cat_loop`: If true (holonym used :also), continue producing categories starting with this holonym when
preceding holonyms generated categories.
Note that new-style place descs (those specified as a single argument using <<...>> to denote placetypes, placetype
qualifiers and holonyms) have an additional `order` field to properly capture the raw text surrounding the items
denoted in double angle brackets. The ``order_item`` items in the `order` field are objects of the following form:
```{
type = "``order_type``",
value = "STRING" or INDEX,
}```
Here, the ``order_type`` is one of `"raw"`, `"qualifier"`, `"placetype"` or `"holonym"`:
* `"raw"` is used for raw text surrounding `<<...>>` specs.
* `"qualifier"` is used for `<<...>>` specs without slashes in them that consist only of qualifiers (e.g. the spec
`<<former>>` in `<<former>> French <<colony>>`).
* `"placetype"` is used for `<<...>>` `specs without slashes that do not consist only of qualifiers.
* `"holonym"` is used for holonyms, i.e. `<<...>>` specs with a slash in them.
For all types but `"holonym"`, the value is a string, specifying the text in question. For `"holonym"`, the value is a
numeric index into the `holonyms` field.
It should be noted that placetypes and placenames occurring inside the holonyms structure are canonicalized, but
placetypes inside the placetypes structure are as specified by the user. Stripping off of qualifiers and
canonicalization of qualifiers and bare placetypes happens later.
The information under `holonyms_by_placetype` is redundant to the information in holonyms but makes categorization
easier. The holonym placenames listed here already have category aliases applied.
For example, the call {{tl|place|en|city|s/Pennsylvania|c/US}} will result in the return value
```{
placetypes = {"bandar"},
holonyms = {
{ placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania" },
{ placetype = "negara", display_placename = "United States", unlinked_placename = "United States" },
},
holonyms_by_placetype = {
state = {"Pennsylvania"},
country = {"United States"},
},
}```
Here, the placetype aliases `s` and `c` have been expanded into `state` and `country` respectively, and the placename
display alias `US` has been expanded into `United States`. PLACETYPES is a list because there may be more than one. For
example, the call {{tl|place|en|city/and/municipality|p/[[Kwango]] Province|c/Congo}} will result in the return value
```
{
placetypes = {"bandar", "and", "municipality"},
holonyms = {
{ placetype = "province", display_placename = "[[Kwango]] Province", unlinked_placename = "Kwango Province" },
{ placetype = "negara", display_placename = "Congo", unlinked_placename = "Congo" },
},
holonyms_by_placetype = {
country = {"Congo"},
},
}```
Here, the `unlinked_placename` field has removed links from `display_placename`.
The value in the key/value pairs is likewise a list; e.g. the call {{tl|place|en|city|s/Kansas|and|s/Missouri}} will
return
```
{
placetypes = {"bandar"},
holonyms = {
{ placetype = "state", display_placename = "Kansas", unlinked_placename = "Kansas" },
{ display_placename = "and", unlinked_placename = "and" },
{ placetype = "state", display_placename = "Missouri", unlinked_placename = "Missouri" },
},
holonyms_by_placetype = {
state = {"Kansas", "Missouri"},
},
}
```
Note that in `get_cats()` (which runs after the display form has been generated), further changes to the holonym
structure are made to aid in categorization. For example, after `handle_category_implications()` and
`augment_holonyms_with_container()` are called, the above structure will look more like
```
{
placetypes = {"bandar"},
holonyms = {
{ placetype = "state", display_placename = "Kansas", unlinked_placename = "Kansas" },
{ placetype = "negara", unlinked_placename = "United States" },
{ display_placename = "and", unlinked_placename = "and" },
{ placetype = "state", display_placename = "Missouri", unlinked_placename = "Missouri" },
{ placetype = "negara", unlinked_placename = "United States" },
},
holonyms_by_placetype = {
state = {"Kansas", "Missouri"},
country = {"United States"}
},
}
```
===Overall place specs===
The overall place spec parsed by `parse_overall_place_spec` has the following fields:
* `lang`: The language object (from {{para|1}}).
* `args`: The parsed arguments from the {{tl|place}} call.
* `directives`: List of form-of directives (starting with `@`) parsed from the numeric args beginning with {{para|2}}.
Each directive contains fields `directive` (the directive as specified by the user, e.g. `"former name of"`);
`terms` (list of term objects for the terms specified by the user); `conj` (conjunction specified by the user using
inline modifier `<conj:...>`, or {nil}); `spec` (the corresponding directive spec from `all_form_of_directives`);
`pretext` (the text to display directly before the directive); `posttext` (the text to display directly after the
directive; {nil} except for the last directive).
* `descs`: List of one or more place description objects parsed from the numeric args beginning with {{para|2}}, as
described above.
* `extra_info`: List of extra-info objects for extra info specified using arguments such as {{para|capital}},
{{para|modern}}, etc. Objects are in the order they should be displayed, and each object contains fields `spec` (the
spec for the type of extra info, taken from `export.extra_info_args`), `terms` (list of term objects for the terms
specified by the user); and `conj` (conjunction specified by the user using inline modifier `<conj:...>`, or {nil}).
===Category determination===
The algorithm to find the categories to which a given place belongs works off of a place description (which specifies
the entry placetype(s) and holonym(s); see above). If there are multiple place descriptions, each is processed
independently to generate categories. Likewise, if there are multiple entry placetypes in a given place description,
each is processed independently with all the holonyms of the description to generate categories. Furthermore, before
the category-generation algorithm runs, earlier steps have modified the holonyms of the place description (inserting
containing polities whenever possible; see the description above of `handle_category_implications()` and
`augment_holonyms_with_container()`).
Given a single entry placetype and a place description, the algorithm to generate categories processes holonyms from
left to right until it finds one that "matches" in that it produces one or more categories. At that point it attempts
to generate categories for all other holonyms in the place description of the same placetype. Normally, it then stops
processing holonyms, but if a holonym is marked using the `:also` modifier, the category generation process starts over
starting with that holonym (or the leftmost such remaining holonym, if there is more than one marked with `:also`).
This makes it possible, for example, to specify the description of a river that passes through two different types of
political divisions (e.g. Alberta and the Northwest Territories), or categorize a geographic region at both the
continent and country level, such as this:
<pre>
{{place|en|historical region|r/Eastern Europe|located in southeastern|c:also/Poland|*and western|c/Ukraine}}
</pre>
Here, `r/Eastern Europe` has a category implication that adds `cont/Europe` as a holonym directly after it, which
causes the page to be categorized into [[:Category:en:Geographic and cultural areas of Europe]]. The category generation
process would normally stop at this point, but the presence of `:also` causes it to restart with `c/Poland` and
generate the category [[:Category:en:Geographic and cultural areas of Poland]]. After doing this, it looks for other
holonyms of the same placetype as `c/Poland` (i.e. other countries), which causes it to process `c/Ukraine` and generate
the category [[:Category:en:Geographic and cultural areas of Ukraine]].
The category generation process works off of the `placetype_data` table, which specifies various properties for
placetypes, such as how to display a holonym of that placetype as well as how to categorize certain pages where the
{{tl|place}} call contains the specified placetype as an entry placetype. For example, the entry for `city-state` in
[[Module:place/placetypes]] might look like
```
["city-state"] = {
link = true,
category_link = "[[sovereign]] [[microstate]]s consisting of a single [[city]] and [[w:dependent territory|dependent territories]]",
has_neighborhoods = true,
class = "settlement",
["continent/*"] = {"City-states", "Cities", "Countries", "Countries in +++", "National capitals"},
default = {"City-states", "Cities", "Countries", "National capitals"},
},
```
Here, the keys specify, respectively:
# If `city-state` occurs as an entry placetype, link it to the corresponding Wiktionary entry (that is what `true` means
in `link = true`).
# Use the specified `category_link` text for categories such as [[:Category:City-states]].
# City-states are "city-like", i.e. they have neighborhoods; this controls the handling of entry placetypes such as
`neighborhood`, `district`, `area`, etc.
# City-states should be treated as settlements for determining how to handle the placetype `former city-state` and for
categorizing the bare category [[:Category:City-states]] and language-specific equivalents such as
[[:Category:en:City-states]].
# When the entry placetype `city-state` occurs along with a continent holonym, categorize into the specified categories
under `continent/*`. Here, `+++` stands for the holonym in question.
# When the entry placetype `city-state` occurs in any other context, categorize into the specified categories under
`default`.
It's important to realize that the only categorization keys under a given placetype entry that are specified
explicitly in [[Module:place/placetypes]] are certain wildcard keys such as `continent/*` above (i.e. containing a slash
followed by `*`) and under the key `default`. All the remaining categorization happens through category handlers, based
on the information on known locations in [[Module:place/locations]]. For example, [[Module:place/locations]] has an
"England group" specified similarly to the following:
```
export.england_group = {
default_container = {key = "England", placetype = "constituent country"},
default_placetype = "county",
default_divs = {
"districts",
{type = "local government districts", cat_as = "districts"},
{
type = "local government districts with borough status",
cat_as = {"districts", "boroughs"},
},
{type = "boroughs", cat_as = {"districts", "boroughs"}},
"civil parishes",
},
default_british_spelling = true,
data = export.england_counties,
}
```
The `default_divs` key here specifies the divisions that exist for each of the counties listed under the `data` key
(unless the key overrides them). Here, the entry `{type = "boroughs", cat_as = {"districts", "boroughs"}}` directs the
category handler `political_division_cat_handler` in [[Module:place/placetypes]] (which is one of two category handlers
that run for all entry placetypes, along with `generic_place_cat_handler`) to categorize boroughs specified under any of
the counties listed under `data` as both districts and boroughs.
Now, the categorization process proceeds as follows, given an entry placetype and place description, which specifies a
set of holonyms (the code to do this is in `get_placetype_cats()`):
# First, look up the entry placetype and any equivalent placetypes in `placetype_data`, which is defined in
[[Module:place/placetypes]]. Note that the entry in `placetype_data` that specifies the placetype information that is
used to determine the category or categories may not directly correspond to the entry placetype as specified in the
place description. For example, if the entry placetype is `small town`, the placetype whose data is fetched will be
`town` since `small` is a recognized qualifier and there is no entry in `placetype_data` for `small town`. As another
example, if the entry placetype is `administrative capital`, the code will first look up `administrative capital` and
then look up `capital city`, which is where the category handler is found, because `administrative capital` specifies
`capital city` as its fallback.
# Then, iterate over holonyms from left to right, as described above. For each holonym, we proceed as follows:
## First, call `political_division_cat_handler` to check if the entry placetype and holonym match a division in the
`locations` data in [[Module:place/locations]], as in the example above. Note that when doing this, holonyms are
canonicalized so that e.g. `co/Bedfordshire` gets mapped to `county/Bedfordshire` (because there is an entry in
`placetype_aliases` in [[Module:place/placetypes]] that maps `co` to `county`) and `c/USA` gets mapped to
`country/United States` (because there is an entry in the location data for the list of countries that maps
`country/USA` to `country/United States` for both display and categorization purposes). This category handler, as
with all such handlers, is passed the entry placetype and holonym being processed, but is also passed the entire
place description, so it can look at other specified holonyms (particularly those that follow). It either returns
{nil} or a list of category specs (which are the actual categories minus the preceding language code).
## If `political_division_cat_handler` doesn't generate any categories, check if there is a category handler defined
using the `cat_handler` key for the entry placetype. If so, call it to generate the categories (if any).
## If the category handler returns {nil}, or there is no category handler, look for a ''wildcard key'' of the format
e.g. `country/*`, which matches any holonym of placetype `country`. If found, the value is a list of category specs,
which are processed as above.
## If we get this far without generating any categories, move to the next holonym.
## If we do generate any categories, process all other holonyms of the same placetype. For example, if the user says
{{tl|place|en|city|s/Kansas|and|s/Missouri}}, when we get to the holonym `s/Kansas`, we generate the category
[[:Category:en:Cities in Kansas, USA]]. This causes us to look for other holonyms of the same placetype `state`,
and process them accordingly, generating a category [[:Category:en:Cities in Missouri, USA]] as well. The same thing
happens in an invocation like {{tl|place|pl|river|c/Poland,Ukraine,Belarus}}.
# Once we generate categories for a holonym and any other holonyms of the same placetype, we normally stop processing
holonyms. But if a holonym has the `:also` modifier, we restart the left-to-right loop at that holonym. For example,
in the invocation {{tl|place|en|river|flowing through|p/Alberta|p/British Columbia|and the|terr/Northwest Territories}},
we will generate a category [[:Category:en:Rivers in Alberta, Canada]] as well as
[[:Category:en:Rivers in British Columbia, Canada]] (because British Columbia is of the same placetype as Alberta);
but no category will be generated for the Northwest Territories, which is of a different placetype. To fix this, write
{{tl|place|en|river|flowing through|p/Alberta|p/British Columbia|and the|terr:also/Northwest Territories}}. The use
of `:also` will cause holonym processing to resume at `Northwest Territories` after `Alberta` is processed, leading to
an additional category [[:Category:en:Rivers in the Northwest Territories, Canada]]. (The presence of `the` in this
last category is because `Northwest Territories` is a known location with a spec indicating that it should be preceded
by `the`; it has nothing to do with the raw text `and the` in the invocation.)
# Finally, if we process all holonyms and don't end up producing any categories, we check the entry placetype's data for
a `default` key. If found, it lists category specs, which are processed to generate categories. This is used, for
example, in the placetype `city-state`, as described above.
# It should be noted that the above process runs independently for each combination of entry placetype and place
description. Thus, for example, an invocation {{tl|place|en|city/and/county|s/Kansas,Missouri|c/USA}} will generate
categories for both cities and counties in both Kansas and Missouri.
# Two additional sources of categories are ''bare location'' categories and ''generic place'' categories. These
categories are added by appropriate calls in the outer function `get_cats`, which iterates over placetypes and place
descriptions, calling `get_placetype_cats` on each combination.
## Bare location categories are categories like [[:Category:Arizona, USA]] that are related-to categories containing
terms related to the specified location. The bare location code, for example, adds the term [[Arizona]], and its
equivalents in other languages, to [[:Category:Arizona, USA]]. When looking for terms to consider, it checks the
pagename, the glosses specified using {{para|t}}, and the terms specified using {{para|modern}}, {{para|short}} and
{{para|full}}. It looks to see if any of these parameters match any known locations, but only adds them to a bare
location category if (a) the specified entry placetype matches, so that for example Russian `[[Джорджия]]` goes into
[[:Category:Georgia, USA]] while `[[Грузия]]` goes into [[:Category:Georgia]] (the country), even though both have a
gloss `Georgia`; and (b) there are no conflicting holonyms, so that for example the Old English term [[Munucceaster]]
if defined similarly to {{tl|place|ang|city|in modern|cc/England|t=Newcastle}} won't get added to
[[:Category:Newcastle, New South Wales]] (even though it is also a city) because the latter city is known to be in
Australia, which conflicts with the country `United Kingdom` (added internally to the Old English place description
through the holonym augmentation process, based on the holonym `cc/England`).
## Generic place categories are categories like [[:Category:Places in Kansas, USA]] and [[:Category:Places in England]]
that contain places of arbitrary placetype. These are added through a special category handler that operates like
other category handlers but is run for all placetypes, rather than only for the specified one(s).
]==]
--[=[
TODO/FIXME:
1. [DONE] Neighborhoods should categorize at the city level. Categories like [[:Category:Places in Los Angeles]] exist
but not [[:Category:Neighborhoods in Los Angeles]]; we can refactor the code in generic_cat_handler() to support this
use case.
2. Display handlers should be smarter. For example, 'co/Travis' as a holonym should display as 'Travis County' in the
United States, but (I think) display handlers don't currently have the full context of holonyms passed in to allow
this to happen.
3. Connected to this, we have various display handlers that add the name of the holonym after or (sometimes) before the
placename if it's not already there. An example is the county_display_handler() in [[Module:place/placetypes]], which
adds "County" before Ireland and Northern Ireland counties and after Taiwan and Romania counties. This should be
integrated into the polity group for these respective polities through a setting rather than requiring a separate
handler that has special casing for various polities.
4. Placetypes for toponyms should also have display handlers rather than just fixed text. This should allow us to
dispense with the need for special types for "fpref" = "French prefecture" (which displays as "prefecture" but links
to the appropriate Wikipedia article on Frenc prefectures, which are completely different from the more general
concept of prefecture). Similarly for "Polish colony" and "Welsh community". ("Israeli settlement" should probably
stay as-is because it displays as "Israeli settlement" not just "settlement".)
5. [DONE] Currently, categories for e.g. states and territories of Australia go into
[[:Category:States and territories of Australia]] but terms for states and territories of Australia go into
(respectively) [[:Category:States of Australia]] and [[:Category:Territories of Australia]]. We should fix this;
maybe this is as easy as setting cat_as in the respective divs definitions.
6. Probably cat_as should support raw categories as well as category types; raw categories would be indicated by being
prefixed with "Category:".
7. [MOSTLY DONE] Update documentation.
8. [DONE] Rename remaining political division categories to include name of country in them.
9. [DONE] Add Pakistan provinces and territories.
10. [DONE] Add a polity group for continents and continent-level regions instead of special-casing. This should make it
possible e.g. to have Jerusalem as a city under "Asia".
11. [DONE] Add better handling of cities that are their own states, like Mexico City.
12. [DONE] Breadcrumb for e.g. [[Category:Aguascalientes, Mexico]] is "Aguascalientes, Mexico" instead of just
"Aguascalientes".
13. [DONE] Unify aliasing system; cities have a completely different mechanism (alias_of) vs. polities/subpolities
(which use`placename_cat_aliases` and `placename_display_aliases` in [[Module:place/placetypes]]).
14. [DONE] More generally, cities should be unified into the polity grouping system to the extent possible; this would
allow for divs of cities (see #17 below).
15. [DONE] We have `no_containing_polity_cat` set for Lebanon, Malta and Saudi Arabia to prevent country-level
implications from being added due to generically-named divisions like "North Governorate", "Central Region" and
"Eastern Province" but (a) this setting seems to do multiple things and should be split, (b) it should be possible
to set this at the division level instead of the country level.
16. Split out the data from the handlers so we can use loadData() on the data because it's becoming very big.
17. [DONE] Cities like Tokyo have special wards; "prefecture-level cities" like Wuhan (which aren't really cities but we
treat them as such) have districts, subdistricts, etc. We need to support divs for cities and even named divisions
of cities (such as we already have for boroughs of New York City).
18. [DONE] It should be allowed to set 'true' to any qualifier (which links it) and have it work correctly; qualifier lookup
in [[Module:place]] needs to remove links first.
19. [DONE] Categories 'Historical polities' and 'Historical political subdivisions' should be renamed 'Former ...' since
"historic(al)" is ambiguous (cf. "historic counties" in England which are not former, but still have a legal
definition).
20. [PARTLY DONE; SUPPORT IS THERE BUT FORMER PROVINCES NOT YET CATEGORIZED] It should be possible to categorize former
subpolities of certain polities; cf. [[:Category:ja:Provinces of Japan]], which contains former provinces.
21. [DONE] In subpolity_keydesc(), we need to generate the correct indefinite article and have a huge hack to check
specifically for "union territory", which is the only placetype that shows up in this function where the default
indefinite article generating function fails. To fix this properly, we need to separate out the non-category
placetype data from `cat_data` in [[Module:place/placetypes]] and move it to [[Module:place/locations]], because we
don't have access to the data in [[Module:place/placetypes]], and that data indicates the correct article for
placetypes like "union territory".
22. [DONE] Simplify the specs in `cat_data`, eliminating the distinction between "inner" and "outer" matching. There
should not be two levels, just one. For example, in "district", instead of
["country/Portugal"] = {
["itself"] = {"Districts and autonomous regions of +++"},
}
we should just have
["country/Portugal"] = {"Districts and autonomous regions of +++"},
And in "dependent territory", instead of
["default"] = {
["itself"] = {true},
["negara"] = {true},
},
we should just have
["itself"] = {true},
["country/*"] = {true},
It appears the only remaining spec that can't be easily converted in this fashion is for "subdistrict":
["country/Indonesia"] = {
["municipality"] = {true},
},
This seems to be specifically for Jakarta and doesn't seem to work anyway, as the two entries in
[[:Category:en:Subdistricts of Jakarta]] and the one entry in [[:Category:id:Subdistricts of Jakarta]] are manually
categorized.
23. [DONE] Consolidate the remaining stuff in [[Module:category tree/topic cat/data/Earth]] into
[[Module:category tree/topic cat/data/Places]].
24. [DONE] The `generic_cat_handler` that categorizes into `Places in FOO` is smart enough not to categorize cities that
are in different polities from the specified containing polity/polities of the city, but doesn't do the same for
larger-level divisions. Likewise for the `city_type_cat_handler`. There are some sufficiently generically-named
divisions that this issue can occur; for example, [[Koforidua]], the capital city of Eastern Region, Ghana, is
incorrectly categorized under [[:Category:en:Cities in Eastern Region, Malta]] and
[[:Category:en:Places in Eastern Region, Malta]]. Note that the function `augment_holonyms_with_container`
''DOES'' do such checks, so we should be able to refactor the code out of that function and use it elsewhere.
25. [DONE] The `generic_cat_handler` that categorizes into `Places in FOO` is smart enough not to categorize cities that
are in different polities from the specified containing polity/polities of the city; but how smart is it? It will
successfully avoid categorizing a neighborhood in e.g. [[Columbus]], [[Georgia]] that doesn't explicitly mention the
US (only `s/Georgia`) into [[:Category:en:Places in Columbus]], which is for Columbus, Ohio, but will it do the same
for a hypothetical neighborhood of Columbus in say Merseyside, England? This should be investigated. It will
probably work for a hypothetical Columbus in [[Canada]] because `augment_holonyms_with_container` would
auto-add Canada as an additional holonym once say `p/Ontario` is mentioned, but I think there's a setting preventing
this augmentation from happening for the UK. (This relates to FIXME #15. `no_containing_polity_cat` is set on
England, Scotland, etc. to prevent the toponyms from being added to [[:Category:en:Places in the United Kingdom]],
but this same setting is used to prevent augmentation, which it should not be; there should be different settings.)
26. [DONE] The `generic_cat_handler` (or more specifically `find_holonym_keys_for_categorization`) checks for city
holonyms by looking specifically for holonym type `city`. But some cities (particularly those in China) can be
specified using different holonym types, e.g. `prefecture-level city`, `subprovincial city`, etc. We should allow
these when appropriate (which means the cities in China need to have a `placetype` set that indicates their
regional-level status as well as just `city`). I'm not sure if cities support specifying a custom `placetype` at the
moment; this relates to FIXME #14 above concerning unifying cities and political divisions internally.
27. [DONE] The bare category handler (`get_bare_categories` in [[Module:place/placetypes]]) is not smart enough to avoid
overcategorizing cities or other divisions that are of the right placetype but in the wrong containing polity. For
example, Asturian [[Llión]] "León (city in Spain)" gets put in [[:Category:ast:León]] even though the latter is
supposed to refer to a city in Mexico. We can borrow the check-containing-polity code from `generic_cat_handler`.
28. [DONE] Redo handling of singular and plural to respect overrides specified in placetype_data. Check more carefully
for things that may not singularize correctly, e.g. 'passes' -> 'passe'? Definitely 'headquarters' and variants.
29. [DONE] Combine placetype_equivs and other placetype data into `placetype_data`. Figure out if we need the
distinction between `placetype_equivs` and `fallback`.
30. `has_neighborhoods` may need to be a function that can look at the containing holonyms to determine whether the
entity in question is city-like.
31. [DONE] Bare placenames as they appear in holonyms (e.g. `Riau Islands`) instead of category keys (e.g.
`the Riau Islands, Indonesia`) should appear in the polity data tables. As a first pass, the word "the" should not
appear but should instead be a property of the polity.
32. [DONE] `capital_city_cat_handler` should use `get_holonyms_to_check()`.
33. [PARTLY DONE] The code to generate and parse the correct preposition ("di" or "of") is very convoluted, and the
actual preposition used is specified in various locations with various defaults, sometimes hardcoded. This should be
simplified. It is made more difficult by the fact that the in/of distinction occurs in several places:
(a) when generating the {{place}} text in old-style descriptions where the preposition isn't explicitly given, which
uses the `preposition` setting in placetype_data, defaulting to "di";
(b) when generating categories based on explicit category specs in placetype_data (which are gradually being
deprecated), which likewise uses the `preposition` setting in placetype_data, defaulting to "di";
(c) when generating categories based on political_division_cat_handler, originating in the `divs` placetypes for
specific known locations in [[Module:place/locations]], which uses the `prep` setting embedded in the `divs`
specifications, defaulting to "of";
(d) when generating categories based on category handlers specified using the `cat_handler` property of entries in
placetype_data, which tend to hardcode "di" or "of" depending on the specific category handler;
(e) when generating category descriptions in [[Module:category tree/topic/Places]] for `divs` categories generated
in (c), which (correctly) uses the same `prep` setting embedded in the `divs` settings that is used when
generating the categories themselves;
(f) when generating category descriptions for categories generated in (b) and (d) above, which relies on the
`generic_before_non_cities` and `generic_before_cities` settings in placetype_data, which need to match the
corresponding prepositions hardcoded in the category generation handlers. Instead of the hardcoding, the
category generation handler should respect the `generic_before_*` settings.
34. [[Krakow]] defined as {{place|en|A <<city>> on the [[Vistula]] River, the <<capital>> of the <<voi/Lesser Poland Voivodeship>> in southern <<c/Poland>>}}
categorizes under [[:Category:Voivodeship capitals]] when it should probably instead be under
[[:Category:Voivodeship capitals of Poland]]. Possibly this is because the various voivodeships haven't yet been
entered as known locations, but this should happen regardless of that.
35. {{tcl}} bugs:
a. [DONE] Lowercase initial letter in new-style {{place}} descriptions in {{tcl}}. Maybe we can have a setting
tcl_nolc=1 to prevent this from happening.
b. [DONE] tcl= and probably new-style {{place}} descriptions in general should recognize ;; to separate distinct {{place}}
descriptions, and similarly ;;and as the equivalent of regular `;and`, etc.
c. [DONE] The value supplied in `modern=` should be displayed in {{tcl}} descriptions regardless of the setting that
normally disables this, so that e.g. the foreign-language equivalent of [[British Honduras]] doesn't just say
it's a former British colony in Central America but specifically identifies it as modern Belize. If the user
gives, place_modern= in {{tcl}}, that should override the modern= value and still display.
d. [DONE] The page supplied to {{tcl}} should be used for generating bare categories even if t= is supplied and
overrides the English term displayed. [DONE]
e. [DONE] If text follows {{place}} and begins with a semicolon, the semicolon isn't copied into {{tcl}}.
36. County boroughs used as holonyms currently display 'borough county borough' because there's an affix setting for
'county borough' and a fallback display handler for 'borough'. We need to rethink this; maybe merge the affix
setting and display handlers.
37. Implement known-location groups and specs in a more standardly object-oriented way using metatables.
38. Implement caching of known location lookup in the holonym. This may have to be keyed by placetype, but we can have a
special field for when the lookup placetype is the same as the user-specified placetype of the holonym. Use this
known location in place of looking up known locations and store the appropriate known location there in
`augment_holonyms_with_container()` instead of calling `key_to_placename`.
39. Bug fixes with 'the':
(a) [DONE] [[Kazaň]] defined as {{place|cs|caplc|rep:Pref/Tatarstan|c/Russia|t1=Kazan}} displays as
"Republic of the Tatarstan".
(b) [[Valday]] defined as {{place|en|town/administrative center|dist:Suf/Valdaysky|obl/Novgorod|c/Russia}}
displays as "a town, the administrative center of the Valdaysky District". Changing to `dist:suf/Valdaysky`
displays as "... of Valdaysky district".
40. [DONE] Bug fix with 'the': [[Verkhoyansk]] defined as {{place|en|town|rep/Sakha|c/Russia}} displays as "a town in
the Sakha".
41. [DONE] [[Category:Cities in Asia]] has [[Category:Cities in Eurasia]] as a parent, which in turn has
[[Category:Cities in the Earth]] as a parent. Continents should not have the second parent like this.
42. [DONE] When checking `british_spelling`, it should check all containers as well; otherwise it's too hard to keep
this in sync across cities, administrative divisions and countries.
43. [DONE] `skip_polity_parent_type` should be renamed to container_parent_type or similar.
44. There should be a flag to allow e.g. departments of France that are currently categorized as departments of their
region to also be categorized as departments of France.
45. [DONE] Aliases are causing iterate_matching_holonym_location() to fail, e.g. if [[براق]] "Prague" is specified as
{{place|acw|capital city|c/Czechia|t1=Prague}}, this fails add a bare category [[Category:acw:Prague]] because
the code in iterate_matching_holonym_location() isn't resolving aliases when comparing the known container
'Czech Republic'. Probably we want to build an alias table to speed up these sorts of lookups.
46. [DONE; DUE TO TYPO IN HANDLER] The district cat handler is failing to work right, e.g. in [[Saint-Gaudérique]]
defined as {{place|fr|district|city/Perpignan|in|dept/Pyrénées-Orientales|r/Occitania|c/France|t=Saint-Gaudérique}},
only the 'Places in ...' categories are getting triggered.
47. Suburbs of a given city aren't generally in the city and may not even be in the same country or country division,
so they should not categorize as "Places in ..." based on the city and specified country and division. Same goes
for "enclave" (within somewhere) and "exclave".
48. When converting display aliases, we should automatically convert full placenames to full placenames and elliptical
placenames to elliptical placenames instead of always either doing elliptical or full placenames depending on the
value of `display_as_full`.
49. `@obsolete form of` and `@archaic form of` should automatically trigger nocat=1.
50. The handler that adds bare categories should pick up values in <eq:...>.
]=]
--[==[ var:
List specifying the allowed form-of directives, used for former names, official names, abbreviations, etc. of places.
The key is the form-of directive and the value is an object with the following properties:
* `text`: The actual text displayed before the terms. If the value is `+`, the key is used as the text. If the value is
a function, it is passed a single argument, the overall place spec (see comment at top of file) and should return
the text to be displayed.
* `type_prefix`: The prefix used to generate the placetype for looking up the appropriate category or categories in the
placetype data structure. Can be omitted if there are no categories associated with the directive.
* `conjunction`: The conjunction used to join multiple terms, defaulting to `and`.
* `cat`: Additional category or categories to add the term to, whenever this particular directive is used. Normally the
value is a topic-style category minus the langcode prefix, but if prefixed with `cln:`, it is a langname-style
category. For example, the value `"Abbreviations"` would correspond to a category [[:Category:en:Abbreviations]]
(assuming the language of the {{tl|place}} call is English), while the value `"cln:abbreviations"` corresponds to a
category [[:Category:English abbreviations]]. Use a list of such specs for multiple categories.
* `default_foreign`: If specified, the default language of terms given along with this directive is the language in
{{para|1}}; otherwise it is English.
]==]
export.all_form_of_directives = {
["former name of"] = {text = "nama lama bagi", type_prefix = "FORMER_NAME_OF"},
["fmr of"] = {alias_of = "former name of"},
["ancient name of"] = {text = "nama purba bagi", type_prefix = "FORMER_NAME_OF"},
["official name of"] = {text = "nama rasmi bagi", type_prefix = "OFFICIAL_NAME_OF"},
["former official name of"] = {text = "nama rasmi lama bagi", type_prefix = "FORMER_OFFICIAL_NAME_OF"},
["long form of"] = {text = "bentuk panjang bagi", type_prefix = "LONG_FORM_OF"},
["former long form of"] = {text = "bentuk panjang lama bagi", type_prefix = "FORMER_LONG_FORM_OF"},
["nickname for"] = {text = "nama panggilan bagi", type_prefix = "NICKNAME_FOR"},
["official nickname for"] = {text = "nama panggilan rasmi bagi", type_prefix = "OFFICIAL_NICKNAME_FOR"},
["former nickname for"] = {text = "nama panggilan lama bagi", type_prefix = "FORMER_NICKNAME_FOR"},
["derogatory name for"] = {text = "nama menghina bagi", type_prefix = "DEROGATORY_NAME_FOR"},
["synonym of"] = {text = "sinonim bagi"},
["syn of"] = {alias_of = "synonym of"},
["abbreviation of"] = {text = "singkatan bagi", type_prefix = "ABBREVIATION_OF", cat = "cln:abbreviations",
default_foreign = true},
["abbr of"] = {alias_of = "abbreviation of"},
["abbrev of"] = {alias_of = "abbreviation of"},
["initialism of"] = {text = "inisial bagi", type_prefix = "ABBREVIATION_OF", cat = "cln:initialisms",
default_foreign = true},
["init of"] = {alias_of = "initialism of"},
["acronym of"] = {text = "akronim bagi", type_prefix = "ABBREVIATION_OF", cat = "cln:acronyms",
default_foreign = true},
["syllabic abbreviation of"] = {text = "singkatan suku kata bagi", type_prefix = "ABBREVIATION_OF", cat = "cln:syllabic abbreviations",
default_foreign = true},
["sylabbr of"] = {alias_of = "syllabic abbreviation of"},
["sylabbrev of"] = {alias_of = "syllabic abbreviation of"},
["ellipsis of"] = {text = "elipsis bagi", type_prefix = "ELLIPSIS_OF", cat = "cln:ellipses",
default_foreign = true},
["ellip of"] = {alias_of = "ellipsis of"},
["clipping of"] = {text = "pemendekan bagi", type_prefix = "CLIPPING_OF", cat = "cln:clippings",
default_foreign = true},
["clip of"] = {alias_of = "clipping of"},
["alternative form of"] = {text = "bentuk alternatif bagi", default_foreign = true},
["alt form"] = {alias_of = "alternative form of"},
["alternative spelling of"] = {text = "ejaan alternatif bagi", default_foreign = true},
["alt spell"] = {alias_of = "alternative spelling of"},
["alt sp"] = {alias_of = "alternative spelling of"},
["dated form of"] = {text = "bentuk lama bagi", type_prefix = "DATED_FORM_OF", cat = "cln:dated forms",
default_foreign = true},
["dated form"] = {alias_of = "dated form of"},
["dated spelling of"] = {text = "ejaan lama bagi", type_prefix = "DATED_FORM_OF", cat = "cln:dated forms",
default_foreign = true},
["dated spell"] = {alias_of = "dated spelling of"},
["dated sp"] = {alias_of = "dated spelling of"},
["archaic form of"] = {text = "bentuk arkaik bagi", type_prefix = "ARCHAIC_FORM_OF", cat = "cln:archaic forms",
default_foreign = true},
["arch form"] = {alias_of = "archaic form of"},
["archaic spelling of"] = {text = "ejaan arkaik bagi", type_prefix = "ARCHAIC_FORM_OF", cat = "cln:archaic forms",
default_foreign = true},
["arch spell"] = {alias_of = "archaic spelling of"},
["arch sp"] = {alias_of = "archaic spelling of"},
["obsolete form of"] = {text = "bentuk usang bagi", type_prefix = "OBSOLETE_FORM_OF", cat = "cln:obsolete forms",
default_foreign = true},
["obs form"] = {alias_of = "obsolete form of"},
["obsolete spelling of"] = {text = "ejaan usang bagi", type_prefix = "OBSOLETE_FORM_OF", cat = "cln:obsolete forms",
default_foreign = true},
["obs spell"] = {alias_of = "obsolete spelling of"},
["obs sp"] = {alias_of = "obsolete spelling of"},
}
local function get_seat_text(overall_place_spec)
local placetype = overall_place_spec.descs[1].placetypes[1]
if placetype == "kaunti" or placetype == "county" or placetype == "counties" then
return "pusat pentadbiran kaunti"
elseif placetype == "parish" or placetype == "parishes" then
return "pusat pentadbiran paroki"
elseif placetype == "borough" or placetype == "boroughs" then
return "pusat pentadbiran borough"
else
return "pusat pentadbiran"
end
end
--[==[ var:
List specifying the allowed arguments containing extra information that is sometimes added to a definition, such as the
capital, largest city, modern name, official name, etc., along with associated properties; displayed in the order given.
Each element is an object with the following properties:
* `arg`: The argument name.
* `text`: The actual text displayed before the terms. If the value is `+`, the argument name is used as the text. If the
value is a function, it is passed a single argument, the overall place spec (see the comment at the top of the file)
and should return the text to be displayed.
* `conjunction`: The conjunction used to join multiple terms, defaulting to `and`.
* `display_even_when_dropped`: Display this piece of extra info even when it would normally be dropped (e.g. in
{{tl|tcl}} when the language is other than English).
* `match_sentence_style`: If true, the text will be capitalized and preceded by a period when ''sentence style'' is
in effect (essentially, when the language is English and there is no translation specified using {{para|t}} or
similar parameter); otherwise, the text will be displayed as-is and preceded by a semicolon. If false, the semicolon
style will always be used.
* `auto_plural`: If true, pluralize the text when there is more than one term.
* `with_colon`: If true, follow the text with a colon. (This colon cannot easily be included in the text itself because
if pluralized, the pluralized text goes before the colon.)
]==]
export.extra_info_args = {
{arg = "modern", text = "nama moden", conjunction = "atau", display_even_when_dropped = true},
{arg = "now", text = "kini", conjunction = "atau", display_even_when_dropped = true},
{arg = "full", text = "nama penuh", conjunction = "atau", display_even_when_dropped = true},
{arg = "short", text = "nama pendek", conjunction = "atau"},
{arg = "abbr", text = "singkatan", conjunction = "atau"},
{arg = "former", text = "dahulunya"},
{arg = "official", text = "nama rasmi", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "capital", text = "ibu kota", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "largest city", text = "bandar terbesar", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "caplc", text = "ibu negara dan bandar terbesar", match_sentence_style = true, auto_plural = false,
with_colon = true},
{arg = "seat", text = get_seat_text, match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "shire town", text = "pekan shire", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "headquarters", text = "ibu pejabat", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "center", text = "pusat pentadbiran", match_sentence_style = true, auto_plural = false, with_colon = true},
{arg = "centre", text = "pusat pentadbiran", match_sentence_style = true, auto_plural = false, with_colon = true},
}
export.extra_info_arg_map = {}
for _, spec in ipairs(export.extra_info_args) do
export.extra_info_arg_map[spec.arg] = spec
end
----------- Wikicode utility functions
-- Return a wikilink link {{l|language|text}}
local function link(text, langcode, id)
if not langcode then
return text
end
return m_links.full_link(
{term = text, lang = require(languages_module).getByCode(langcode, true, "allow etym"), id = id},
nil, "allow self link"
)
end
---------- Basic utility functions
-- Add the page to a tracking "category". To see the pages in the "category",
-- go to [[Wiktionary:Tracking/place/PAGE]] and click on "What links here".
local function track(page)
require(debug_track_module)("place/" .. page)
return true
end
local function ucfirst_all(text)
if text:find(" ") then
local parts = split(text, " ", true)
for i, part in ipairs(parts) do
parts[i] = m_strutils.ucfirst(part)
end
return concat(parts, " ")
else
return m_strutils.ucfirst(text)
end
end
local function lc(text)
return mw.getContentLanguage():lc(text)
end
---------- Argument parsing functions and utilities
-- Split an argument on comma, but not comma followed by whitespace.
local function split_on_comma(val)
if val:find(",") then
return require(parse_interface_module).split_on_comma(val)
else
return {val}
end
end
-- Split an argument on slash, but not slash occurring inside of HTML tags like </span> or <br />.
local function split_on_slash(arg)
if arg:find("<") then
local m_parse_utilities = require(parse_utilities_module)
-- We implement this by parsing balanced segment runs involving <...>, and splitting on slash in the remainder.
-- The result is a list of lists, so we have to rejoin the inner lists by concatenating.
local segments = m_parse_utilities.parse_balanced_segment_run(arg, "<", ">")
local slash_separated_groups = m_parse_utilities.split_alternating_runs(segments, "/")
for i, group in ipairs(slash_separated_groups) do
slash_separated_groups[i] = concat(group)
end
return slash_separated_groups
else
return split(arg, "/", true)
end
end
-- Implement "implications", i.e. where the presence of a given holonym causes additional holonym(s) to be added.
-- Implications apply only to categorization. There used to be support for "general implications" that applied to both
-- display and categorization, but there ended up not being any such implications, so we've removed the support. It is
-- a bad idea in any case to have such implications; the user might purposely leave out a higher-level polity to avoid
-- redundancy in several successive definitions, and we wouldn't want to override that. Note that in practice the
-- mechanism implemented by this function is used specifically for non-administrative geographic regions such as
-- Eastern Europe and the West Bank; there is a similar mechanism for administrative regions handled by
-- `augment_holonyms_with_containing_polity` in [[Module:place/placetypes]].
--
-- `place_descriptions` is a list of place descriptions (see top of file, collectively describing the data passed to
-- {{place}}). `implication_data` is the data used to implement the implications, i.e. a table indexed by holonym
-- placetype, each value of which is a table indexed by holonym placename, each value of which is a list of
-- "PLACETYPE/PLACENAME" holonyms to be added to the end of the list of holonyms.
local function handle_category_implications(place_descriptions, implication_data)
for i, desc in ipairs(place_descriptions) do
if desc.holonyms then
local new_holonyms = {}
for _, holonym in ipairs(desc.holonyms) do
insert(new_holonyms, holonym)
local imp_data = m_placetypes.get_equiv_placetype_prop(holonym.placetype, function(pt)
local implication = implication_data[pt] and implication_data[pt][holonym.unlinked_placename]
if implication then
return implication
end
end)
if imp_data then
for _, holonym_to_add in ipairs(imp_data) do
local split_holonym = split_on_slash(holonym_to_add)
if #split_holonym ~= 2 then
internal_error("Invalid holonym in implications: %s", holonym_to_add)
end
local holonym_placetype, holonym_placename = unpack(split_holonym, 1, 2)
local new_holonym = {
-- By the time we run, the display has already been generated so we don't need to set
-- display_placename.
placetype = holonym_placetype, unlinked_placename = holonym_placename
}
insert(new_holonyms, new_holonym)
m_placetypes.key_holonym_into_place_desc(desc, new_holonym)
end
end
end
desc.holonyms = new_holonyms
end
end
end
-- Split a holonym (e.g. "continent/Europe" or "country/en:Italy" or "in southern" or "r:suf/O'Higgins" or
-- "c/Austria,Germany,Czech Republic") into its components. Return a list of holonym objects (see top of file). Note
-- that if there isn't a slash in the holonym (e.g. "in southern"), the `placetype` field of the holonym will be nil.
-- Placetype aliases (e.g. "r" for "region") and placename aliases (e.g. "US" or "USA" for "United States") will be
-- expanded.
local function split_holonym(raw)
local no_display, combined_holonym = raw:match("^(!)(.*)$")
no_display = not not no_display
combined_holonym = combined_holonym or raw
local suppress_comma, combined_holonym_without_comma = combined_holonym:match("^(%*)(.*)$")
suppress_comma = not not suppress_comma
combined_holonym = combined_holonym_without_comma or combined_holonym
local holonym_parts = split_on_slash(combined_holonym)
if #holonym_parts == 1 then
-- `unlinked_placename` should not be used.
return {{display_placename = combined_holonym, no_display = no_display, suppress_comma = suppress_comma}}
end
-- Rejoin further slashes in case of slash in holonym placename, e.g. Admaston/Bromley.
local placetype = holonym_parts[1]
local placename = concat(holonym_parts, "/", 2)
-- Check for modifiers after the holonym placetype.
local split_holonym_placetype = split(placetype, ":", true)
placetype = split_holonym_placetype[1]
local affix_type
local saw_also
local saw_the
for i = 2, #split_holonym_placetype do
local modifier = split_holonym_placetype[i]
if modifier == "also" then
if saw_also then
error(("Modifier ':also' occurs twice in holonym '%s'"):format(combined_holonym))
end
saw_also = true
elseif modifier == "the" then
if saw_the then
error(("Modifier ':the' occurs twice in holonym '%s'"):format(combined_holonym))
end
saw_the = true
elseif modifier == "pref" or modifier == "Pref" or modifier == "suf" or modifier == "Suf" or
modifier == "noaff" then
if affix_type then
error(("Affix-type modifier ':%s' occurs twice in holonym '%s'"):format(modifier, combined_holonym))
end
affix_type = modifier
else
error(("Unrecognized holonym placetype modifier '%s', should be one of " ..
"'pref', 'Pref', 'suf', 'Suf', 'noaff', 'also' or 'the'"):format(modifier))
end
end
placetype = m_placetypes.resolve_placetype_aliases(placetype)
local holonyms = split_on_comma(placename)
local pluralize_affix = #holonyms > 1
local affix_holonym_index = (affix_type == "pref" or affix_type == "Pref") and 1 or affix_type == "noaff" and 0 or
#holonyms
for i, placename in ipairs(holonyms) do
-- Check for langcode before the holonym placename, but don't get tripped up by Wikipedia links, which begin
-- "[[w:...]]" or "[[wikipedia:]]".
local langcode, placename_without_langcode = rmatch(placename, "^([^%[%]]-):(.*)$")
if langcode then
placename = placename_without_langcode
end
placename = m_placetypes.resolve_placename_display_aliases(placetype, placename)
holonyms[i] = {
placetype = placetype,
display_placename = placename,
unlinked_placename = m_placetypes.remove_links_and_html(placename),
langcode = langcode,
affix_type = i == affix_holonym_index and affix_type or nil,
pluralize_affix = i == affix_holonym_index and pluralize_affix,
suppress_affix = i ~= affix_holonym_index,
no_display = no_display,
suppress_comma = suppress_comma,
continue_cat_loop = saw_also,
force_the = i == 1 and saw_the,
}
end
return holonyms
end
local get_param_mods = memoize(function()
local m_param_utils = require(parameter_utilities_module)
return m_param_utils.construct_param_mods {
{group = {"link", "q", "l", "ref"}},
{param = "eq"},
-- FIXME: Finish [[Module:format utilities]].
--{param = "conj", set = require(format_utilities_module).allowed_conjs_for_join_segments, overall = true},
{param = "conj", set = {["and"] = true, ["or"] = true, ["and/or"] = true}, overall = true},
}
end)
local function parse_term_with_inline_modifiers(term, paramname, default_lang)
-- FIXME: Finish changes to [[Module:parameter utilities]] and [[Module:parse utilities]] that support continuations
-- and new-format generate_obj().
--local function generate_obj(data)
-- local m_param_utils = require(parameter_utilities_module)
-- data.parse_lang_prefix = true
-- data.special_continuations = m_param_utils.default_special_continuations
-- data.default_lang = default_lang
-- local obj = m_param_utils.generate_obj_maybe_parsing_lang_prefix(data)
-- obj.show_decorations = true
-- return obj
--end
local function generate_obj(raw_term, parse_err)
local obj = require(parse_utilities_module).generate_obj_maybe_parsing_lang_prefix {
term = raw_term,
parse_err = parse_err,
parse_lang_prefix = true,
}
obj.lang = obj.lang or default_lang
obj.show_decorations = true
return obj
end
return require(parse_interface_module).parse_inline_modifiers(term, {
paramname = paramname,
param_mods = get_param_mods(),
generate_obj = generate_obj,
-- FIXME: See above.
--generate_obj_new_format = true,
splitchar = ",",
outer_container = {},
})
end
local function parse_form_of_directive(arg, lang, form_of_overridden_args)
local form_of_directive, raw_terms = arg:match("^@([a-z -]+):(.*)$")
if not form_of_directive then
error("Misformatted @-directive: " .. dump(arg))
end
if not export.all_form_of_directives[form_of_directive] then
local known_directives = {}
for k, _ in pairs(export.all_form_of_directives) do
insert(known_directives, '"' .. k .. '"')
end
table.sort(known_directives)
error(("Unrecognized form-of directive %s in @-directive %s; recognized directives are %s"):format(
dump(form_of_directive), dump(arg), concat(known_directives, ", ")))
end
local spec = export.all_form_of_directives[form_of_directive]
local canonical_directive = form_of_directive
if spec.alias_of then
canonical_directive = spec.alias_of
spec = export.all_form_of_directives[canonical_directive]
if not spec then
internal_error("Form-of directive alias %s points to %s, which is not a directive",
"@" .. form_of_directive, canonical_directive)
elseif spec.alias_of then
internal_error("Form-of directive alias %s points to %s, which is also an alias",
"@" .. form_of_directive, canonical_directive)
end
end
local default_foreign = spec.default_foreign
local directive_param = "@" .. form_of_directive
if form_of_overridden_args and form_of_overridden_args[canonical_directive] then
raw_terms = form_of_overridden_args[canonical_directive].new_value
local new_directive = form_of_overridden_args[canonical_directive].new_directive
local new_spec = export.all_form_of_directives[new_directive]
if not new_spec then
error(("Internal error: [[Module:transclude]] passed in unrecognized replacement directive '@%s'"):
format(new_directive))
end
if new_spec.alias_of then
error(("Internal error: [[Module:transclude]] passed in replacement directive alias '@%s', " ..
"should be canonical"):format(new_directive))
end
if new_directive ~= canonical_directive then
directive_param = directive_param .. (" (replaced with @%s)"):format(new_directive)
canonical_directive = new_directive
spec = new_spec
end
default_foreign = true
end
local terms = parse_term_with_inline_modifiers(raw_terms, directive_param,
default_foreign and lang or enlang)
return {
directive = canonical_directive,
terms = terms.terms,
conj = terms.conj,
spec = spec,
}
end
-- Parse an argument containing extra information that is sometimes added to a definition, such as the capital, largest
-- city, modern name, official name, etc. `args` is the value from the parsed argument structure and can be either nil,
-- a string or a list (depending on whether it was declared as a single parameter or a list). `spec` is the extra info
-- spec corresponding to the type of extra info. Each value in `args` can be a comma-separated list of terms with inline
-- modifiers attached. [FIXME: we should switch to always using the comma-separated format and disallow list parameters
-- such as |capital=, |capital2=, etc.] The return value is a structure containing fields `terms` (a list of term
-- objects, each of which is in the format expected by full_link() in [[Module:links]]), `conj` (an explicit
-- conjunction to join multiple terms, or nil if no explicit conjunction was given) and `spec` (the passed-in spec).
local function parse_extra_info_arg(args, spec, default_lang)
if not args then
return nil
end
if type(args) ~= "table" then
args = {args}
end
if not args[1] then
return nil
end
local terms = nil
local conj
for i, arg in ipairs(args) do
local this_terms = parse_term_with_inline_modifiers(arg, spec.arg .. (i == 1 and "" or i), default_lang)
local thisconj = this_terms.conj
if not conj then
conj = thisconj
elseif thisconj and conj ~= thisconj then
error(("Two different conjunctions '%s' and '%s' specified for |%s=; you only need to specify the " ..
"conjunction once"):format(conj, thisconj))
end
if not terms then
terms = this_terms.terms
else
m_table.extend(terms, this_terms.terms)
end
end
return {
spec = spec,
terms = terms,
conj = conj,
}
end
--[==[
Parse a "new-style" place description, with placetypes and holonyms surrounded by `<<...>>` amid otherwise raw text.
Return value is a place description object as documented at the top of the file. Exported for use by
[[Module:demonyms]].
]==]
function export.parse_new_style_place_desc(text, lang, form_of_directives, form_of_overridden_args)
local placetypes = {}
local segments = split(text, "<<(.-)>>")
local retval = {holonyms = {}, order = {}}
local form_of_directives_already_present = form_of_directives and not not form_of_directives[1]
for i, segment in ipairs(segments) do
if i % 2 == 1 then
insert(retval.order, {type = "raw", value = segment})
elseif segment:find("@") then
if not form_of_directives then
error(("Form-of directive '%s' not allowed in this context"):format(segment))
elseif form_of_directives_already_present then
error(("Saw form-of directive '%s' in new-style place desc followed by direct (separate-parameter) form-of directives; not allowed"):format(
segment))
elseif placetypes[1] or retval.holonyms[1] then
error(("Form-of directive '%s' must come first, before placetypes and holonyms"):format(segment))
else
local form_of_directive = parse_form_of_directive(segment, lang, form_of_overridden_args)
if not retval.order[1] or retval.order[1].type ~= "raw" or retval.order[2] then
internal_error("`retval.order` should have a single raw element: %s", retval.order)
end
form_of_directive.pretext = retval.order[1].value
retval.order[1] = nil
insert(form_of_directives, form_of_directive)
end
elseif segment:find("/") then
local holonyms = split_holonym(segment)
for j, holonym in ipairs(holonyms) do
if j > 1 then
if not holonym.no_display then
if j == #holonyms then
insert(retval.order, {type = "raw", value = " and "})
else
insert(retval.order, {type = "raw", value = ", "})
end
end
-- All but the first in a multi-holonym need an article. For the first one, the article is
-- specified in the raw text if needed. (Currently, needs_article is only used when displaying the
-- holonym, so it wouldn't matter when no_display is set, but we set it anyway in case we need it
-- for something else.)
holonym.needs_article = true
end
insert(retval.holonyms, holonym)
if not holonym.no_display then
insert(retval.order, {type = "holonym", value = #retval.holonyms})
end
m_placetypes.key_holonym_into_place_desc(retval, holonym)
end
else
local treat_as, display = segment:match("^(..-):(.+)$")
if treat_as then
segment = treat_as
else
display = segment
end
-- see if the placetype segment is just qualifiers
local only_qualifiers = true
local split_segments = split(segment, " ", true)
for _, split_segment in ipairs(split_segments) do
if m_placetypes.placetype_qualifiers[split_segment] == nil then
only_qualifiers = false
break
end
end
insert(placetypes, {placetype = segment, only_qualifiers = only_qualifiers})
if only_qualifiers then
insert(retval.order, {type = "qualifier", value = display})
else
insert(retval.order, {type = "placetype", value = display})
end
end
end
if not form_of_directives_already_present and form_of_directives and form_of_directives[1] then
form_of_directives[#form_of_directives].posttext = ""
end
local final_placetypes = {}
for i, placetype in ipairs(placetypes) do
if i > 1 and placetypes[i - 1].only_qualifiers then
final_placetypes[#final_placetypes] = final_placetypes[#final_placetypes] .. " " .. placetypes[i].placetype
else
insert(final_placetypes, placetypes[i].placetype)
end
end
retval.placetypes = final_placetypes
return retval
end
--[==[
Parse one or more "new-style" place descriptions, with placetypes and holonyms surrounded by `<<...>>` amid otherwise
raw text. Multiple descriptions are separated by two semicolons in a row. Return value is a list of place description
objects as documented at the top of the file.
]==]
local function parse_conjoined_new_style_place_desc(text, lang, form_of_directives, form_of_overridden_args)
local separate_specs = split(text, ";(;[^ ]*)")
local descs = {}
for i = 1, #separate_specs do
if i % 2 == 1 then
insert(descs, export.parse_new_style_place_desc(separate_specs[i], lang, form_of_directives,
form_of_overridden_args))
form_of_directives = nil
else
descs[#descs].separator = separate_specs[i]
end
end
return descs
end
--[=[
Process numeric and "extra info" arguments into an overall place spec, as described at the top of the file. `data` is an
object with the following fields:
* `args`: The parsed arguments of {{tl|place}}.
* `from_tcl`: True if we're being invoked from {{tl|tcl}}.
* `extra_info_overridden_set`, `form_of_overridden_args`: Same as the corresponding fields in the `data` object passed
to `export.format`.
]=]
local function parse_overall_place_spec(data)
local args, from_tcl, extra_info_overridden_set, form_of_overridden_args =
data.args, data.from_tcl, data.extra_info_overridden_set, data.form_of_overridden_args
local descs = {}
local this_desc
-- Index of separate (semicolon-separated) place descriptions within `descs`.
local desc_index = 1
-- Index of separate holonyms within a place description. 0 means we've seen no holonyms and have yet to process
-- the placetypes that precede the holonyms. 1 means we've seen no holonyms but have already processed the
-- placetypes.
local holonym_index = 0
local in_place_desc = false
local form_of_directives = {}
local function set_desc_joiner(desc, separator)
if separator == ";" then
this_desc.joiner = "; "
this_desc.include_following_article = true
elseif separator == ";;" then
this_desc.joiner = " "
else
local joiner = separator:sub(2)
if rfind(joiner, "^%a") then
this_desc.joiner = " " .. joiner .. " "
else
this_desc.joiner = joiner .. " "
end
end
end
for _, arg in ipairs(args[2]) do
if arg:find("^@") then
if not (desc_index == 1 and holonym_index == 0) then
error("@-directives cannot follow place descriptions")
end
local form_of_directive = parse_form_of_directive(arg, args[1], form_of_overridden_args)
if form_of_directives[1] then
form_of_directive.pretext = ", "
else
form_of_directive.pretext = ""
end
insert(form_of_directives, form_of_directive)
elseif arg == ";" or arg:find("^;[^ ]") then
if not this_desc then
error("Saw semicolon joiner without preceding place description")
end
set_desc_joiner(this_desc, arg)
desc_index = desc_index + 1
holonym_index = 0
in_place_desc = false
else
if arg:find("<<") then
if in_place_desc then
error("New-style place description must come first or following a separator (semicolon or similar), not directly following another description")
end
in_place_desc = true
local this_descs = parse_conjoined_new_style_place_desc(arg, args[1], form_of_directives,
form_of_overridden_args)
for j, desc in ipairs(this_descs) do
this_desc = desc
if holonym_index > 0 then
desc_index = desc_index + 1
holonym_index = 0
end
if j < #this_descs then
set_desc_joiner(this_desc, this_desc.separator)
end
descs[desc_index] = this_desc
last_was_new_style = true
holonym_index = #this_desc.holonyms + 1
end
else
-- Old-style arguments can directly follow a new-style argument; they become additional holonyms
-- tacked onto the end of the holonym list, and are displayed old-style except that there is no
-- prefix before the first one following the new-style argument.
in_place_desc = true
if holonym_index == 0 then
local entry_placetypes = split_on_slash(arg)
this_desc = {placetypes = entry_placetypes, holonyms = {}}
descs[desc_index] = this_desc
holonym_index = holonym_index + 1
else
local holonyms = split_holonym(arg)
for j, holonym in ipairs(holonyms) do
if j > 1 then
-- All but the first in a multi-holonym need an article. Not for the first one because e.g.
-- {{place|en|city|s/Arizona|c/United States}} should not display as "a city in Arizona, the
-- United States". The overall first holonym in the place description gets an article if
-- needed regardless of our setting here.
holonym.needs_article = true
-- Insert "and" before the last holonym.
if j == #holonyms then
this_desc.holonyms[holonym_index] = {
-- Use the no_display value from the first holonym; it should be the same for all
-- holonyms. `unlinked_placename` should not be used.
display_placename = "and", no_display = holonyms[1].no_display
}
holonym_index = holonym_index + 1
end
end
this_desc.holonyms[holonym_index] = holonym
m_placetypes.key_holonym_into_place_desc(this_desc, this_desc.holonyms[holonym_index])
holonym_index = holonym_index + 1
end
end
end
end
end
if form_of_directives[1] and not form_of_directives[#form_of_directives].posttext then
form_of_directives[#form_of_directives].posttext =
(args.def and args.def ~= "-" or not args.def and descs[1]) and ": " or ""
end
-- Tracking code. This does nothing but add tracking for seen placetypes and qualifiers. The place will be linked to
-- [[Wiktionary:Tracking/place/entry-placetype/PLACETYPE]] for all entry placetypes seen; in addition, if PLACETYPE
-- has qualifiers (e.g. 'small city'), there will be links for the bare placetype minus qualifiers and separately
-- for the qualifiers themselves:
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/BARE_PLACETYPE]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/QUALIFIER]]
-- Note that if there are multiple qualifiers, there will be links for each possible split. For example, for
-- 'small maritime city'), there will be the following links:
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/small maritime city]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/maritime city]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/city]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/small]]
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/maritime]]
-- Finally, there are also links for holonym placetypes, e.g. if the holonym 'c/Italy' occurs, there will be the
-- following link:
-- [[Special:WhatLinksHere/Wiktionary:Tracking/place/holonym-placetype/country]]
for _, desc in ipairs(descs) do
for _, entry_placetype in ipairs(desc.placetypes) do
local splits = m_placetypes.split_qualifiers_from_placetype(entry_placetype, "no canon qualifiers")
for _, split in ipairs(splits) do
local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3)
track("entry-placetype/" .. bare_placetype)
if this_qualifier then
track("entry-qualifier/" .. this_qualifier)
end
end
end
for _, holonym in ipairs(desc.holonyms) do
if holonym.placetype then
track("holonym-placetype/" .. holonym.placetype)
end
end
end
local extra_info = {}
for _, extra_info_spec in ipairs(export.extra_info_args) do
local extra_info_terms = parse_extra_info_arg(args[extra_info_spec.arg], extra_info_spec,
-- If called from {{tcl}} and extra info argument was set by {{tcl}}, interpret the argument
-- according to the language in 1=; otherwise interpret as English. To override this, prefix
-- with the appropriate language.
from_tcl and extra_info_overridden_set and extra_info_overridden_set[extra_info_spec.arg] and args[1] or
enlang)
if extra_info_terms then
insert(extra_info, extra_info_terms)
end
end
return {
lang = args[1],
args = args,
directives = form_of_directives,
descs = descs,
extra_info = extra_info,
}
end
-------- Definition-generating functions
-- Return a string with the wikilinks to the English translations of the word.
local function get_translations(transl, ids)
local ret = {}
for i, t in ipairs(transl) do
local arg_transls = split_on_comma(t)
local arg_ids = ids[i]
if arg_ids then
arg_ids = split_on_comma(arg_ids)
if #arg_transls ~= #arg_ids then
error(("Saw %s translation%s in t%s=%s but %s ID%s in tid%s=%s"):format(
#arg_transls, #arg_transls > 1 and "s" or "", i == 1 and "" or i, t, #arg_ids,
#arg_ids > 1 and "'s" or "", i == 1 and "" or i, ids[i]))
end
end
for j, arg_transl in ipairs(arg_transls) do
insert(ret, link(arg_transl, "en", arg_ids and arg_ids[j] or nil))
end
end
return concat(ret, ", ")
end
-- Return the article (currently always `"the"`) to be prepended to the given placename, or nil. `decorated_placename`
-- is the placename as specified by the user along with any affix added to it. `placename` is the raw unlinked
-- placename, defaulting to the unlinked version of `decorated_placename` if not given. `placetypes` is a placetype or
-- list of placetypes for the placename. `suppress_holonym_use_the_check` suppresses checking the placetypes for
-- `holonym_use_the`.
local function get_placename_article(decorated_placename, placetypes, placename, suppress_holonym_use_the_check)
local unlinked_decorated_placename = m_placetypes.remove_links_and_html(decorated_placename)
if unlinked_decorated_placename:find("^the ") then
return nil
end
placename = placename or unlinked_decorated_placename
if type(placetypes) == "string" then
placetypes = {placetypes}
end
for _, placetype in ipairs(placetypes) do
local art = m_placetypes.get_equiv_placetype_prop(placetype, function(pt)
local art = m_placetypes.placename_article[pt] and m_placetypes.placename_article[pt][placename]
if art then
return art
end
end)
if art then
return art
end
end
-- Get equivalent placetypes of the specified placetype so that e.g.
-- {{place|en|@official name of:Bahamas|island country|r/Caribbean}} put 'the' before Bahamas ("Bahamas" is just
-- specified as a country but "island country" falls back to "negara").
local all_equiv_placetypes = {}
for _, placetype in ipairs(placetypes) do
local this_equiv_placetypes = m_placetypes.get_placetype_equivs(placetype)
for _, this_equiv_placetype in ipairs(this_equiv_placetypes) do
insert(all_equiv_placetypes, this_equiv_placetype.placetype)
end
end
-- Look for a known location. We should be using find_matching_holonym_location() but that function doesn't
-- currently work without alias resolution. Instead we check if any matching location has `the = true` set.
-- In practice there aren't any cases where a given placename matches two locations, only one of which has
-- `the = true` set.
for group, key, spec in m_placetypes.iterate_matching_location {
placetypes = all_equiv_placetypes,
placename = placename,
alias_resolution = "none",
} do
-- `iterate_holonym_location` doesn't initialize the spec if alias resolution is turned off, so check both
-- the spec and group. Be careful in case `the = false` is explicitly given by the spec.
if spec.the ~= nil then
if spec.the then
return "the"
end
elseif group.default_the then
return "the"
end
end
if not suppress_holonym_use_the_check then
-- See if the placetype requests an article to be placed before the placename. This occurs e.g. with 'sea'. But
-- if the user specifies e.g. "sea:pref/Cortez", we'll wrongly get "the sea of the Cortez", so in that case we
-- need to ignore the holonym article specified along with the placetype.
for _, placetype in ipairs(placetypes) do
local holonym_use_the = m_placetypes.get_equiv_placetype_prop(placetype,
function(pt) return placetype_data[pt] and placetype_data[pt].holonym_use_the end)
if holonym_use_the then
return "the"
end
end
end
local universal_res = m_placetypes.placename_the_re["*"]
for _, re in ipairs(universal_res) do
if unlinked_decorated_placename:find(re) then
return "the"
end
end
for _, placetype in ipairs(placetypes) do
local matched = m_placetypes.get_equiv_placetype_prop(placetype, function(pt)
local res = m_placetypes.placename_the_re[pt]
if not res then
return nil
end
for _, re in ipairs(res) do
if unlinked_decorated_placename:find(re) then
return true
end
end
return nil
end)
if matched then
return "the"
end
end
return nil
end
-- Prepend the appropriate article if needed to `decorated_placename` (the user-specified placename with any affix
-- added), where the underlying holonym object that generated `linked_placename` can be found at `holonym_index` in the
-- holonyms in `place_desc`.
local function get_holonym_article(decorated_placename, place_desc, holonym_index)
local holonym = place_desc.holonyms[holonym_index]
local holonym_placetype = holonym.placetype
if not holonym_placetype then
return nil
end
return get_placename_article(decorated_placename, holonym_placetype, holonym.unlinked_placename,
not not holonym.affix_type)
end
-- Convert a holonym into display format. This adds wikilinks to holonyms and passes them through any display handlers,
-- which may (e.g.) add the placetype to the holonym. If `needs_article` is true, prepend the article `"the"` if the
-- holonym requires it (e.g. if the holonym is `United States`). `needs_article` is set to true we are processing the
-- first specified holonym in an old-style place description (i.e. the holonym directly following the entry placetype,
-- with no raw-text holonym in between).
--
-- Examples:
-- ({placetype = "negara", display_placename = "United States", unlinked_placename = "United States"}, true) returns
-- the template-expanded equivalent of "the {{l|en|United States}}".
-- ({placetype = "region", display_placename = "O'Higgins", unlinked_placename = "O'Higgins", affix_type = "suf"}, false)
-- returns the template-expanded equivalent of "{{l|en|O'Higgins}} region".
-- ({display_placename = "in the southern"}, false) returns "in the southern" (without wikilinking because .placetype
-- and .langcode are both nil).
local function format_holonym(place_desc, holonym_index, needs_article)
local holonym = place_desc.holonyms[holonym_index]
if holonym.no_display then
return ""
end
local orig_needs_article = needs_article
needs_article = needs_article or holonym.needs_article or holonym.force_the
local output = holonym.display_placename
local placetype = holonym.placetype
local affix_type_pt_data, affix_type, affix_is_prefix, affix, prefix, suffix, no_affix_strings
local pt_equiv_for_affix_type, already_seen_affix, need_affix
-- Implement display handlers.
local display_handler = m_placetypes.get_equiv_placetype_prop(placetype,
function(pt) return placetype_data[pt] and placetype_data[pt].display_handler end)
if display_handler then
output = display_handler(placetype, output)
end
if not holonym.suppress_affix then
-- Implement adding an affix (prefix or suffix) based on the holonym's placetype. The affix will be
-- added either if the placetype's placetype_data spec says so (by setting 'affix_type'), or if the
-- user explicitly called for this (e.g. by using 'r:suf/O'Higgins'). Before adding the affix,
-- however, we check to see if the affix is already present (e.g. the placetype is "district"
-- and the placename is "Mission District"). The placetype can override the affix to add (by setting
-- `prefix`, `suffix` or `affix`) and/or override the strings used for checking if the affix is already
-- present (by setting 'no_affix_strings', which defaults to the affix explicitly given through `prefix`,
-- `suffix` or `affix` if any are given). `prefix` and `suffix` take precedence over `affix` if both are
-- set, but only when the appropriate type of affix is requested.
-- Search through equivalent placetypes for a setting of `affix_type`, `affix`, `prefix` or `suffix`. If we
-- find any, use them. If `affix_type` is given, it is overridden by the user's explicitly specified affix
-- type. If either an `affix_type` is found or the user explicitly specified an affix type, the affix is
-- displayed according to the following:
-- 1. If `prefix`, `suffix` or `affix` is given by the placetype or equivalent placetypes, use it (e.g.
-- placetype `administrative region` requests suffix "region" but doesn't set affix type; if the user
-- explicitly specifies `administrative region` as the placetype for a holonym and specifies a suffixal
-- affix type, use "region"). In this search, we stop looking if we find an explicit `affix_type`
-- setting; if this is found without an associated affix setting, the assumption is the associated
-- placetype was intended as the affix, not some explicit affix setting associated with a fallback
-- placetype.
-- 2. Otherwise, if the user explicitly requested an affix type, use the actual placetype (principle of
-- least surprise).
-- 3. Finally, fall back to the placetype associated with an explicit `affix_type` setting (which will
-- always exist if we get this far).
affix_type_pt_data, pt_equiv_for_affix_type = m_placetypes.get_equiv_placetype_prop(placetype,
function(pt)
local cdpt = placetype_data[pt]
return cdpt and cdpt.affix_type and cdpt or nil
end
)
affix_pt_data, pt_equiv_for_affix = m_placetypes.get_equiv_placetype_prop(placetype,
function(pt)
local cdpt = placetype_data[pt]
return cdpt and (cdpt.affix_type or cdpt.affix or cdpt.prefix or cdpt.suffix) and cdpt or nil
end
)
if affix_type_pt_data then
affix_type = affix_type_pt_data.affix_type
need_affix = true
end
if affix_pt_data then
prefix = affix_pt_data.prefix or affix_pt_data.affix
suffix = affix_pt_data.suffix or affix_pt_data.affix
need_affix = true
end
no_affix_strings = affix_pt_data and affix_pt_data.no_affix_strings or
affix_type_pt_data and affix_type_pt_data.no_affix_strings
if holonym.affix_type and placetype then
affix_type = holonym.affix_type
prefix = prefix or placetype
suffix = suffix or placetype
need_affix = true
end
if need_affix then
-- At this point the affix_type has been determined and can't change any more, so we can figure out
-- whether we need the calculated prefix or suffix.
affix_is_prefix = affix_type == "pref" or affix_type == "Pref"
if affix_is_prefix then
affix = prefix
else
affix = suffix
end
if not affix then
if not pt_equiv_for_affix_type then
internal_error("Something wrong, `pt_equiv_for_affix_type` not set processing holonym: %s",
holonym)
end
affix = pt_equiv_for_affix_type.placetype
if not affix then
internal_error("Something wrong, no affix could be located in `pt_equiv_for_affix_type` for " ..
"holonym %s: %s", holonym, pt_equiv_for_affix_type)
end
end
no_affix_strings = no_affix_strings or lc(affix)
if holonym.pluralize_affix then
affix = m_placetypes.pluralize_placetype(affix)
end
already_seen_affix = m_placetypes.check_already_seen_string(output, no_affix_strings)
end
end
output = link(output, holonym.langcode or placetype and "en" or nil)
if need_affix and not affix_is_prefix and not already_seen_affix then
output = output .. " " .. (affix_type == "Suf" and ucfirst_all(affix) or affix)
end
if needs_article then
local article = holonym.force_the and "the" or get_holonym_article(output, place_desc, holonym_index)
if article then
output = article .. " " .. output
end
end
if affix_is_prefix and not already_seen_affix then
output = (affix_type == "Pref" and ucfirst_all(affix) or affix) .. " bagi " .. output
if orig_needs_article then
-- Put the article before the added affix if we're the first holonym in the place description. This is
-- distinct from the article added above for the holonym itself; cf. "c:pref/United States,Canada" ->
-- "the countries of the United States and Canada". We need to use the value of `needs_article` passed
-- in from the function, which indicates whether we're processing the first holonym.
output = "the " .. output
end
end
return output
end
-- Format a holonym for display, taking into account the entry's placetype (specifically, the last placetype if there
-- are more than one, excluding conjunctions and parenthetical items); the holonym's index among the holonyms in the
-- template (which specifies what the previous holonym is and whether it is the first holonym); and the full place
-- description (which helps resolve ambiguities in holonyms when looking up known locations). This may involve putting a
-- preposition ("di" or "of") before the formatted holonym, particularly if it is the first one, and may involve
-- prepending a comma. If `holonym_no_prefix` is specified, nothing except a space is put before the holonym; used
-- when formatting mixed new/old-style descriptions.
local function format_holonym_in_context(entry_placetype, place_desc, holonym_index, holonym_no_prefix)
local desc = ""
-- If holonym.placetype is nil, the holonym is just raw text, e.g. 'in southern'.
if holonym_no_prefix then
desc = " "
else
local holonym = place_desc.holonyms[holonym_index]
if not holonym.no_display then
-- First compute the initial delimiter.
if holonym_index == 1 then
if holonym.placetype then
desc = desc .. " " .. m_placetypes.get_placetype_entry_preposition(entry_placetype) .. " "
elseif not holonym.display_placename:find("^,") then
desc = desc .. " "
end
else
local prev_holonym = place_desc.holonyms[holonym_index - 1]
if prev_holonym.placetype and not holonym.suppress_comma then
local dname = holonym.display_placename
if dname ~= "and" and dname ~= "di" and dname ~= "and the" and dname ~= "di" then
desc = desc .. ","
end
end
if holonym.placetype or not holonym.display_placename:find("^,") then
desc = desc .. " "
end
end
end
end
return desc .. format_holonym(place_desc, holonym_index, not holonym_no_prefix and holonym_index == 1)
end
-- Return the linked description of a placetype. This splits off any qualifiers and displays them separately.
local function get_placetype_description(placetype)
local splits = m_placetypes.split_qualifiers_from_placetype(placetype)
local prefix = ""
for _, split in ipairs(splits) do
local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3)
if this_qualifier then
prefix = (prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier) .. " "
else
prefix = ""
end
local display_form = m_placetypes.get_placetype_display_form(bare_placetype)
if display_form then
return prefix .. display_form
end
placetype = bare_placetype
end
return prefix .. placetype
end
-- Return the linked description of a qualifier (which may be multiple words).
local function get_qualifier_description(qualifier)
local splits = m_placetypes.split_qualifiers_from_placetype(qualifier .. " foo")
local split = splits[#splits]
local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3)
return prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier
end
-- Format a set of form-of directive terms.
local function format_form_of_directive(overall_place_spec, directive_terms, ucfirst, from_tcl)
local formatted_terms = {}
local placetypes
if not overall_place_spec.descs[2] then
placetypes = overall_place_spec.descs[1].placetypes
else
placetypes = {}
for _, desc in ipairs(overall_place_spec.descs) do
m_table.extend(placetypes, desc.placetypes)
end
end
for _, termobj in ipairs(directive_terms.terms) do
local placename_article
if not termobj.alt and termobj.term and not termobj.term:find("%[%[") then
placename_article = get_placename_article(termobj.term, placetypes)
end
local linked_term = m_links.full_link(termobj, "term")
linked_term = "<span class='form-of-definition-link'>" .. linked_term .. "</span>"
if termobj.eq then
linked_term = linked_term .. " (= " .. m_links.full_link {term = termobj.eq, lang = enlang} .. ")"
end
if placename_article then
linked_term = placename_article .. " " .. linked_term
end
insert(formatted_terms, linked_term)
end
local spec = directive_terms.spec
local text = spec.text
if type(text) == "function" then
text = text(overall_place_spec)
end
if text == "+" then
text = directive_terms.directive
end
if ucfirst then
text = m_strutils.ucfirst(text)
end
if not from_tcl then
local tracking_prefix = "form-of/" .. directive_terms.directive
track(tracking_prefix)
local langcode = overall_place_spec.lang:getCode()
local full_langcode = overall_place_spec.lang:getFullCode()
track(tracking_prefix .. "/" .. langcode)
if full_langcode ~= langcode then
track(tracking_prefix .. "/" .. full_langcode)
end
if full_langcode ~= "en" then
track(tracking_prefix .. "/non-english")
end
end
return (require(form_of_module).format_form_of {
text = text,
lemmas = m_table.serialCommaJoin(formatted_terms, {conj = directive_terms.conj or spec.conjunction or "dan"}),
lemma_classes = false,
-- text_classes = "place-text",
})
end
-- Format a set of extra-info terms for extra information that is sometimes added to a definition, such as the capital,
-- largest city, modern name, official name, etc. `overall_place_spec` is the overall parsed {{tl|place}} spec (see
-- comment at top of file); `extra_info_terms` is the terms spec for this type of extra-info (as returned by
-- `parse_extra_info_arg`); and `sentence_style` indicates whether we're generating a sentence-style definition (as
-- suitable for an English-language term without a translation specified using t=).
local function format_extra_info(overall_place_spec, extra_info_terms, sentence_style)
local formatted_terms = {}
for _, termobj in ipairs(extra_info_terms.terms) do
insert(formatted_terms, m_links.full_link(termobj))
end
local spec = extra_info_terms.spec
local text = spec.text
if type(text) == "function" then
text = text(overall_place_spec)
end
if text == "+" then
text = spec.arg
end
if spec.auto_plural and formatted_terms[2] then
text = pluralize(text)
end
if spec.with_colon then
text = text .. ":"
end
if sentence_style and spec.match_sentence_style then
text = ". " .. m_strutils.ucfirst(text)
else
text = "; " .. text
end
-- FIME: Use joinSegments when available.
-- return text .. " " ..
-- m_table.joinSegments(formatted_terms, {conj = extra_info_terms.conj or spec.conjunction or "dan"})
return text .. " " ..
m_table.serialCommaJoin(formatted_terms, {conj = extra_info_terms.conj or spec.conjunction or "dan"})
end
-- Format an old-style place description (with separate arguments for the placetype and each holonym) for display and
-- return the resulting string.
local function format_old_style_place_desc_for_display(args, place_desc, desc_index, with_article, ucfirst)
-- The placetype used to determine whether "di" or "of" follows is the last placetype if there are
-- multiple slash-separated placetypes, but ignoring "and", "or" and parenthesized notes
-- such as "(one of 254)".
local entry_placetype = nil
local placetypes = place_desc.placetypes
local function is_and_or(item)
return item == "and" or item == "or"
end
local parts = {}
local function ins(txt)
insert(parts, txt)
end
local function ins_space()
if #parts > 0 then
ins(" ")
end
end
local and_or_pos
for i, placetype in ipairs(placetypes) do
if is_and_or(placetype) then
and_or_pos = i
-- no break here; we want the last in case of more than one
end
end
local remaining_placetype_index
if and_or_pos then
track("multiple-placetypes-with-and")
if and_or_pos == #placetypes then
error("Conjunctions 'and' and 'or' cannot occur last in a set of slash-separated placetypes: " ..
concat(placetypes, "/"))
end
local items = {}
for i = 1, and_or_pos + 1 do
local pt = placetypes[i]
if is_and_or(pt) then
-- skip
elseif i > 1 and pt:find("^%(") then
-- append placetypes beginning with a paren to previous item
items[#items] = items[#items] .. " " .. pt
else
entry_placetype = pt
insert(items, get_placetype_description(pt))
end
end
ins(m_table.serialCommaJoin(items, {conj = placetypes[and_or_pos]}))
remaining_placetype_index = and_or_pos + 2
else
remaining_placetype_index = 1
end
for i = remaining_placetype_index, #placetypes do
local pt = placetypes[i]
-- Check for and, or and placetypes beginning with a paren (so that things like
-- "{{place|en|county/(one of 254)|s/Texas}}" work).
if m_placetypes.placetype_is_ignorable(pt) then
ins_space()
ins(pt)
else
entry_placetype = pt
-- Join multiple placetypes with comma unless placetypes are already
-- joined with "and". We allow "the" to precede the second placetype
-- if they're not joined with "and" (so we get "city and county seat of ..."
-- but "city, the county seat of ...").
if i > 1 then
ins(", ")
local article = m_placetypes.get_placetype_article(pt)
if article ~= "the" and i > remaining_placetype_index then
-- Track cases where we are comma-separating multiple placetypes without the second one starting
-- with "the", as they may be mistakes. The occurrence of "the" is usually intentional, e.g.
-- {{place|zh|municipality/state capital|s/Rio de Janeiro|c/Brazil|t1=Rio de Janeiro}}
-- for the city of [[Rio de Janeiro]], which displays as "a municipality, the state capital of ...".
track("multiple-placetypes-without-and-or-the")
end
if article then
ins(article)
ins(" ")
end
end
ins(get_placetype_description(pt))
end
end
if place_desc.holonyms then
for holonym_index, _ in ipairs(place_desc.holonyms) do
ins(format_holonym_in_context(entry_placetype, place_desc, holonym_index))
end
end
local gloss = concat(parts)
if with_article then
local article
if desc_index == 1 then
article = args.a
else
if not place_desc.holonyms then
-- there isn't a following holonym; the place type given might be raw text as well, so don't add
-- an article.
with_article = false
else
local saw_placetype_holonym = false
for _, holonym in ipairs(place_desc.holonyms) do
if holonym.placetype then
saw_placetype_holonym = true
break
end
end
if not saw_placetype_holonym then
-- following holonym(s)s is/are just raw text; the place type given might be raw text as well,
-- so don't add an article.
with_article = false
end
end
if with_article then
track("second-or-higher-description-with-added-article")
else
track("second-or-higher-description-suppressed-article")
end
end
if with_article then
article = article or m_placetypes.get_placetype_article(place_desc.placetypes[1], ucfirst)
if article then
gloss = article .. " " .. gloss
elseif ucfirst then
gloss = m_strutils.ucfirst(gloss)
end
end
end
return gloss
end
--[==[
Get the full gloss (English description) of a new-style place description. New-style place descriptions are
specified with a single string containing raw text interspersed with placetypes and holonyms surrounded by `<<...>>`.
Exported for use by [[Module:demonyms]].
]==]
function export.format_new_style_place_desc_for_display(args, place_desc, with_article)
local parts = {}
local function ins(txt)
insert(parts, txt)
end
if with_article and args.a then
ins(args.a .. " ")
end
local max_holonym = 0
for _, order in ipairs(place_desc.order) do
local segment_type, segment = order.type, order.value
if segment_type == "raw" then
ins(segment)
elseif segment_type == "placetype" then
ins(get_placetype_description(segment))
elseif segment_type == "qualifier" then
ins(get_qualifier_description(segment))
elseif segment_type == "holonym" then
ins(format_holonym(place_desc, segment, false))
if segment > max_holonym then
max_holonym = segment
end
else
internal_error("Unrecognized segment type %s", segment_type)
end
end
if place_desc.holonyms and max_holonym < #place_desc.holonyms then
local holonym_no_prefix = true
for holonym_index = max_holonym + 1, #place_desc.holonyms do
ins(format_holonym_in_context(nil, place_desc, holonym_index, holonym_no_prefix))
holonym_no_prefix = false
end
end
return concat(parts)
end
-- Return a string with the gloss (the description of the place itself, as opposed to translations). If `ucfirst` is
-- given, the gloss's first letter is made upper case. If `sentence_style` is given, the "extra info" (modern name,
-- capital, largest city, etc.) is displayed as separated sentences; otherwise, it is displayed separated from the main
-- definition by semicolons.
local function get_display_form(data)
local overall_place_spec, ucfirst, sentence_style, drop_extra_info, extra_info_overridden_set, from_tcl =
data.overall_place_spec, data.ucfirst, data.sentence_style, data.drop_extra_info,
data.extra_info_overridden_set, data.from_tcl
local args = overall_place_spec.args
local parts = {}
local function ins(txt)
table.insert(parts, txt)
end
if overall_place_spec.directives and overall_place_spec.directives[1] then
for i, directive_terms in ipairs(overall_place_spec.directives) do
ins(directive_terms.pretext)
if directive_terms.pretext ~= "" then
ucfirst = false
end
if not args.def or args.def == "-" then
ins(format_form_of_directive(overall_place_spec, directive_terms, ucfirst, from_tcl))
ucfirst = false
if i == #overall_place_spec.directives and directive_terms.posttext then
ins(directive_terms.posttext)
end
end
end
end
if args.def == "-" then
return concat(parts)
end
if args.def then
if args.def:find("<<") then
local def_desc = export.parse_new_style_place_desc(args.def, args[1])
ins(export.format_new_style_place_desc_for_display({}, def_desc, false))
else
ins(args.def)
end
else
local include_article = true
for n, desc in ipairs(overall_place_spec.descs) do
if desc.order then
ins(export.format_new_style_place_desc_for_display(args, desc, n == 1))
else
ins(format_old_style_place_desc_for_display(args, desc, n, include_article, ucfirst))
end
if desc.joiner then
ins(desc.joiner)
end
include_article = desc.include_following_article
ucfirst = false
end
end
local addl = args.addl
if addl then
posttext = posttext or ""
if addl:find("^[;:]") then
ins(addl)
elseif addl:find("^_") then
ins(" " .. addl:sub(2))
else
ins(", " .. addl)
end
end
for _, extra_info_terms in ipairs(overall_place_spec.extra_info) do
-- Include a given extra info term either when
-- (1) drop_extra_info not set (it's set by {{tcl}}), or
-- (2) the extra info term is marked as "display even when dropped" (e.g. modern= or full=, to help understand
-- the term's sense), or
-- (3) the term was overridden by a `place_*=` setting in {{tcl}}.
if not drop_extra_info or extra_info_terms.spec.display_even_when_dropped or
extra_info_overridden_set and extra_info_overridden_set[extra_info_terms.spec.arg] then
ins(format_extra_info(overall_place_spec, extra_info_terms, sentence_style))
end
end
return concat(parts)
end
-- Return the definition line.
local function get_def(data)
local overall_place_spec, from_tcl, drop_extra_info, extra_info_overridden_set, translation_follows =
data.overall_place_spec, data.from_tcl, data.drop_extra_info, data.extra_info_overridden_set,
data.translation_follows
local args = overall_place_spec.args
local sentence_style = overall_place_spec.lang:getCode() == "en"
local ucfirst = sentence_style and not args.nocap
if #args.t > 0 then
local gloss = get_display_form {
overall_place_spec = overall_place_spec,
ucfirst = false,
sentence_style = false,
drop_extra_info = drop_extra_info,
extra_info_overridden_set = extra_info_overridden_set,
from_tcl = from_tcl,
}
if from_tcl and not args.tcl_nolc then
gloss = m_strutils.lcfirst(gloss)
end
if translation_follows then
return (gloss == "" and "" or gloss .. ": ") .. get_translations(args.t, args.tid)
else
return get_translations(args.t, args.tid) .. (gloss == "" and "" or " (" .. gloss .. ")")
end
else
return get_display_form {
overall_place_spec = overall_place_spec,
ucfirst = ucfirst,
sentence_style = sentence_style,
drop_extra_info = drop_extra_info,
extra_info_overridden_set = extra_info_overridden_set,
from_tcl = from_tcl,
}
end
end
---------- Functions for the category wikicode
-- The code in this section finds the categories to which a given place belongs. See comment at top of file.
--[=[
Find the appropriate category specs for a given place description and placetype. For example, for the template
invocation {{tl|place|en|city/and/county|s/Pennsylvania|c/US}}, which results in the place description
```
{
placetypes = {"bandar", "and", "county"},
holonyms = {
{placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"},
{placetype = "negara", display_placename = "United States", unlinked_placename = "United States"},
},
holonyms_by_placetype = {
state = {"Pennsylvania"},
country = {"United States"},
},
}
```
the call
```
find_placetype_cat_specs {
entry_placetype = "bandar",
place_desc = {
placetypes = {"bandar", "and", "county"},
holonyms = {
{placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"},
{placetype = "negara", display_placename = "United States", unlinked_placename = "United States"},
},
holonyms_by_placetype = {
state = {"Pennsylvania"},
country = {"United States"},
},
},
}
```
might produce the return value
```
{
entry_placetype = "bandar",
cat_specs = {"Cities in Pennsylvania, USA"},
triggering_holonym = {placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"},
triggering_holonym_index = 1,
}
```
See the comment at the top of the section for a description of category specs and the overall algorithm.
On entry, `data` is an object with the following fields:
* `entry_placetype`: the entry placetype (or equivalent) used to look up the category data in placetype_data,
which must have already been resolved to a placetype with an entry in `placetype_data`;
* `place_desc`: the full place description as documented at the top of the file (used only for its holonyms);
* `first_holonym_index`: the index of the first holonym to consider when iterating through the holonyms (used to
implement the `:also` holonym placetype modifier);
* `overriding_holonym`: an optional overriding holonym to use, in place of iterating through the holonyms (used to
implement categorizing other holonyms of the same type as the triggering holonym, so that e.g.
{{tl|place|en|river|s/Kansas,Nebraska}}, or equivalently {{tl|place|en|river|s/Kansas|and|s/Nebraska}}, works);
* `from_demonym`: we are called from {{tl|demonym-noun}} or {{tl|demonym-adj}} instead of {{tl|place}}, and should
generate categories appropriate to those templates.
* `form_of_directive`: A form-of directive prefix such as `FORMER_NAME_OF`. If specified, use that type prefix to
generate categories appropriate to the form-of directive (in addition to the regular categories generated for the
{{tl|place}} invocation, which happens in a separate call).
The return value is {nil} if no category specs could be located, otherwise an object with the following fields:
* `entry_placetype`: the placetype that should be used to construct categories when `true` is one of the returned
category specs (normally the same as the `entry_placetype` passed in, but will be different when a "fallback" key
exists and is used);
* `cat_specs`: list of category specs as described above;
* `triggering_holonym`: the triggering holonym (see the comment at the top of the section), or nil if there was no
triggering holonym;
* `triggering_holonym_index`: the index of the triggering holonym in the list of holonyms in `place_desc`, or nil if
an overriding holonym was passed in or there was no triggering holonym.
]=]
local function find_placetype_cat_specs(data)
local entry_placetype, place_desc, first_holonym_index, overriding_holonym, from_demonym =
data.entry_placetype, data.place_desc, data.first_holonym_index, data.overriding_holonym, data.from_demonym
local form_of_directive = data.form_of_directive
local function fetch_cat_specs(holonym_to_match, index, no_fallback)
local holonym_placetype = holonym_to_match.placetype
if not holonym_placetype then
-- raw text in place of holonym
return nil
end
local holonym_placename = holonym_to_match.unlinked_placename
if not holonym_placename then
internal_error("Missing unlinked_placename in holonym (index %s): %s", index, holonym_to_match)
end
local cat_specs, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype,
function(equiv_entry_pt)
return m_placetypes.get_equiv_placetype_prop(holonym_placetype,
function(equiv_holonym_pt) return m_placetypes.political_division_cat_handler {
entry_placetype = equiv_entry_pt,
holonym_placetype = equiv_holonym_pt,
holonym_placename = holonym_placename,
holonym_index = index,
place_desc = place_desc,
from_demonym = from_demonym,
} end)
end,
{no_fallback = no_fallback, form_of_directive = form_of_directive}
)
if cat_specs and cat_specs[1] then
return cat_specs, equiv_entry_placetype_and_qualifier.placetype
end
local cat_handler, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype,
function(equiv_entry_pt)
local entry_placetype_data = m_placetypes.placetype_data[equiv_entry_pt]
if entry_placetype_data and entry_placetype_data.cat_handler then
return entry_placetype_data.cat_handler
end
end,
{no_fallback = no_fallback, form_of_directive = form_of_directive}
)
if cat_handler then
local cat_specs = m_placetypes.get_equiv_placetype_prop(holonym_placetype,
function(equiv_holonym_pt) return cat_handler {
entry_placetype = equiv_entry_placetype_and_qualifier.placetype,
holonym_placetype = equiv_holonym_pt,
holonym_placename = holonym_placename,
holonym_index = index,
place_desc = place_desc,
from_demonym = from_demonym,
} end)
if cat_specs and cat_specs[1] then
return cat_specs, equiv_entry_placetype_and_qualifier.placetype
end
end
if not no_fallback then
local cat_specs, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype,
function(equiv_entry_pt)
local entry_placetype_data = m_placetypes.placetype_data[equiv_entry_pt]
if entry_placetype_data then
return m_placetypes.get_equiv_placetype_prop(holonym_placetype,
function(equiv_holonym_pt)
return entry_placetype_data[equiv_holonym_pt .. "/*"]
end)
end
end,
{form_of_directive = form_of_directive}
)
if cat_specs and cat_specs[1] then
return cat_specs, equiv_entry_placetype_and_qualifier.placetype
end
end
return nil
end
if overriding_holonym then
-- FIXME, change the algorithm to eliminate overriding_holonym
local cat_specs, fetched_entry_placetype = fetch_cat_specs(overriding_holonym, nil)
if cat_specs and cat_specs[1] then
return {
entry_placetype = fetched_entry_placetype,
cat_specs = cat_specs,
triggering_holonym = overriding_holonym,
-- no triggering_holonym_index
}
end
else
-- We loop twice over holonyms, the first time setting `no_fallback` so that we process only category specs for
-- the specifically given entry placetype (possibly with preceding qualifiers). The reason for this is to
-- correctly handle cases like [[Poblacion IX]]:
-- {{place|en|barangay|mun/Roxas|p/Capiz|c/Philippines}}.
-- "barangay" falls back to "neighborhood", and without the `no_fallback` loop, the neighborhood cat handler run
-- on the mun/Roxas holonym will take precedence over the barangay-specific setting for p/Capiz because we
-- check, for each holonym in turn, first for a matching spec through political_division_cat_handler, then a cat
-- handler, then a wildcard spec like country/*. During the first no-fallback loop, we disable checking for
-- wildcard specs because it seems a fallback matching exactly or through a cat handler on an earlier holonym
-- would be better than a wildcard match for the exact entry placetype at a later holonym. (FIXME: But I don't
-- know for sure; maybe we should check wildcard holonyms on the exact entry placetype first, or contrariwise
-- maybe we should check only exact-match holonyms through political_division_cat_handler on the exact entry
-- placetype first, not even checking other cat handlers.)
for i, holonym in ipairs(place_desc.holonyms) do
if first_holonym_index and i < first_holonym_index then
-- continue
else
local cat_specs, fetched_entry_placetype = fetch_cat_specs(holonym, i, "no_fallback")
if cat_specs and cat_specs[1] then
return {
entry_placetype = fetched_entry_placetype,
cat_specs = cat_specs,
triggering_holonym = holonym,
triggering_holonym_index = i,
}
end
end
end
for i, holonym in ipairs(place_desc.holonyms) do
if first_holonym_index and i < first_holonym_index then
-- continue
else
local cat_specs, fetched_entry_placetype = fetch_cat_specs(holonym, i)
if cat_specs and cat_specs[1] then
return {
entry_placetype = fetched_entry_placetype,
cat_specs = cat_specs,
triggering_holonym = holonym,
triggering_holonym_index = i,
}
end
end
end
end
return nil
end
-- Turn a list of category specs (see comment at section top) into the corresponding categories (minus the language
-- code prefix). The function is given the following arguments:
-- (1) the category specs retrieved using find_placetype_cat_specs();
-- (2) the entry placetype used to fetch the entry in `placetype_data`
-- (3) the triggering holonym (a holonym object; see comment at top of file) used to fetch the category specs
-- (see top-of-section comment); or nil if no triggering holonym.
-- The return value is constructed as described in the top-of-section comment.
local function cat_specs_to_categories(place_desc, cat_data)
local all_cats = {}
local cat_specs, entry_placetype, triggering_holonym, triggering_holonym_index =
cat_data.cat_specs, cat_data.entry_placetype, cat_data.triggering_holonym, cat_data.triggering_holonym_index
if triggering_holonym then
for _, cat_spec in ipairs(cat_specs) do
local cat
if cat_spec == true then
cat = m_placetypes.pluralize_placetype(entry_placetype, "ucfirst") .. " " ..
m_placetypes.get_placetype_entry_preposition(entry_placetype) .. " +++"
else
cat = cat_spec
end
if cat:find("%+%+%+") then
local group, key, spec, container_trail = m_placetypes.find_matching_holonym_location {
holonym_placetype = triggering_holonym.placetype,
holonym_placename = triggering_holonym.unlinked_placename,
holonym_index = triggering_holonym_index,
place_desc = place_desc,
}
if group then
cat = cat:gsub("%+%+%+", m_strutils.replacement_escape(m_placetypes.get_prefixed_key(key, spec)))
insert(all_cats, cat)
else
mw.log(("Unable to insert category for cat spec '%s' because holonym '%s/%s' did not match a " ..
"known location"):format(cat, triggering_holonym.placetype, triggering_holonym.unlinked_placename))
track("cant-match-holonym-for-category-spec")
end
else
insert(all_cats, cat)
end
end
else
for _, cat_spec in ipairs(cat_specs) do
local cat
if cat_spec == true then
cat = m_placetypes.pluralize_placetype(entry_placetype, "ucfirst")
else
cat = cat_spec
if cat:find("%+%+%+") then
internal_error("Category %s contains +++ but there is no holonym to substitute", cat)
end
end
insert(all_cats, cat)
end
end
return all_cats
end
-- Return the categories (without initial lang code) that should be added to the entry, given the place description
-- (which specifies the entry placetype(s) and holonym(s); see top of file) and a particular entry placetype (e.g.
-- "bandar"). Note that only the holonyms from the place description are looked at, not the entry placetypes in the place
-- description.
local function get_placetype_cats(place_desc, entry_placetype, from_demonym, form_of_directive)
local cats = {}
local first_holonym_index = 1
while first_holonym_index <= #place_desc.holonyms do
-- Find the category specs (see top-of-file comment) corresponding to the holonym(s) in the place description.
local cat_data = find_placetype_cat_specs {
entry_placetype = entry_placetype,
place_desc = place_desc,
first_holonym_index = first_holonym_index,
from_demonym = from_demonym,
form_of_directive = form_of_directive,
}
-- Check if no category spec could be found.
if not cat_data then
break
end
local triggering_holonym = cat_data.triggering_holonym
if not triggering_holonym then
internal_error("find_placetype_cat_specs should have returned a triggering holonym: %s", cat_data)
end
-- Generate categories for the category specs found.
extend(cats, cat_specs_to_categories(place_desc, cat_data))
-- Also generate categories for other holonyms of the same placetype, so that e.g.
-- {{place|en|city|s/Kansas|and|s/Missouri|c/USA}} generates both [[:Category:en:Cities in Kansas, USA]] and
-- [[:Category:en:Cities in Missouri, USA]].
first_holonym_index = cat_data.triggering_holonym_index
-- Loop over non-fallback equivalent placetypes to the triggering holonym's placetype, in case it is
-- non-canonical (e.g. `cities/San Francisco`). This matches the loop over equivalent places in
-- key_holonym_into_place_desc().
local equiv_triggering_placetypes = m_placetypes.get_placetype_equivs(triggering_holonym.placetype,
{no_fallback = true})
for _, equiv in ipairs(equiv_triggering_placetypes) do
local other_holonyms_of_same_type = place_desc.holonyms_by_placetype[equiv.placetype]
if other_holonyms_of_same_type then
for _, other_placename_of_same_type in ipairs(other_holonyms_of_same_type) do
if other_placename_of_same_type ~= triggering_holonym.unlinked_placename then
local overriding_holonym = {
placetype = triggering_holonym.placetype,
unlinked_placename = other_placename_of_same_type,
}
local other_cat_data = find_placetype_cat_specs {
entry_placetype = entry_placetype,
place_desc = place_desc,
overriding_holonym = overriding_holonym,
from_demonym = from_demonym,
form_of_directive = form_of_directive,
}
if other_cat_data then
extend(cats, cat_specs_to_categories(place_desc, other_cat_data))
end
end
end
end
end
-- If there are any later-specified holonyms that had the modifier :also, try to produce categories for them
-- as well.
first_holonym_index = first_holonym_index + 1
while first_holonym_index <= #place_desc.holonyms do
if place_desc.holonyms[first_holonym_index].continue_cat_loop then
break
end
first_holonym_index = first_holonym_index + 1
end
end
if cats[1] then
return cats
end
local entry_pt_default, equiv_entry_placetype_and_qualifier =
m_placetypes.get_equiv_placetype_prop(entry_placetype, function(pt)
return m_placetypes.placetype_data[pt] and m_placetypes.placetype_data[pt].default
end,
{form_of_directive = form_of_directive})
if entry_pt_default then
return cat_specs_to_categories(place_desc, {
cat_specs = entry_pt_default,
entry_placetype = equiv_entry_placetype_and_qualifier.placetype,
-- no triggering holonym
})
end
return {}
end
--[==[
Iterate through each type of place and return a list of the categories that need to be added to the entry. The returned
categories need to be formatted using `format_cats`, as they can be either topic-style categories (by default) or
langname-style categories (if prefixed with `cln:`). The function is passed the overall place spec, which contains all
the parsed info on the {{tl|place}} call (see comment at top of file), the parsed arguments (needed for arguments
not parsed by `parse_overall_place_spec` and used primarily to add "bare categories" corresponding to toponyms for known
locations), and `from_demonym`, which is true if we're being called from {{tl|demonym-noun}} or {{tl|demonym-adj}} (in
this case, we only want certain categories added, specifically bare categories corresponding to the specified
holonym(s)).
]==]
function export.get_cats(args, overall_place_spec, from_demonym)
local cats = {}
local place_descriptions = overall_place_spec.descs
handle_category_implications(place_descriptions, m_placetypes.cat_implications)
m_placetypes.augment_holonyms_with_container(place_descriptions)
if overall_place_spec.directives then -- not necessarily when called from [[Module:demonym]]
for _, directive_terms in ipairs(overall_place_spec.directives) do
local spec_cats = directive_terms.spec.cat
if spec_cats then
if type(spec_cats) == "string" then
spec_cats = {spec_cats}
end
for _, spec_cat in ipairs(spec_cats) do
insert(cats, spec_cat)
end
end
if directive_terms.spec.type_prefix then
for _, place_desc in ipairs(place_descriptions) do
for _, placetype in ipairs(place_desc.placetypes) do
if not m_placetypes.placetype_is_ignorable(placetype) then
extend(cats, get_placetype_cats(place_desc, placetype, from_demonym,
directive_terms.spec.type_prefix))
end
end
end
end
end
end
if not from_demonym then
local bare_categories = m_placetypes.get_bare_categories(args, overall_place_spec)
extend(cats, bare_categories)
end
for _, place_desc in ipairs(place_descriptions) do
if not from_demonym then
for _, placetype in ipairs(place_desc.placetypes) do
if not m_placetypes.placetype_is_ignorable(placetype) then
extend(cats, get_placetype_cats(place_desc, placetype))
end
end
end
-- Also add generic place categories for the holonyms listed (e.g. a category like
-- [[Category:Places in Merseyside, England]]). This is handled through the special placetype "*".
extend(cats, get_placetype_cats(place_desc, "*", from_demonym))
end
if args.cat then -- not necessarily when called from [[Module:demonym]]
for _, cat in ipairs(args.cat) do
local split_cats = split_on_comma(cat)
extend(cats, split_cats)
end
end
return cats
end
-- Return the category link for a category, given the language code and the name of the category.
local function format_cats(lang, cats, sort_key)
local full_cats = {}
local langcode = lang:getFullCode()
for _, cat in ipairs(cats) do
-- 'cln' corresponds to {{cln}}, which generates lang-name categories like [[:Category:English abbreviations]]
-- (as opposed to topic categories like [[:Category:en:Abbreviations of states of the United States]]).
local cln_cat = cat:match("^cln:(.*)$")
if cln_cat then
insert(full_cats, lang:getFullName() .. " " .. cln_cat)
else
insert(full_cats, langcode .. ":" .. cat)
end
end
return require(utilities_module).format_categories(full_cats, lang, sort_key, nil,
force_cat or m_placetypes.get_force_cat())
end
----------- Main entry point
--[==[
Implementation of {{tl|place}}. Meant to be callable from another module (specifically, [[Module:transclude]]). The
single argument `data` is an object with the following fields:
* `template_args`: Raw arguments specified by {{tl|place}}, possibly modified by {{tl|tcl}}.
* `from_tcl`: True if we're being invoked from {{tl|tcl}}.
* `drop_extra_info`: True if we should drop most of the "extra info" specified using extra info arguments (capital,
largest city, etc.). Usually true when invoked from {{tl|tcl}}. Note that some extra info is still displayed even
when `drop_extra_info` is set in order to establish the context (e.g. {{para|full}} and {{para|modern}}), and any
extra info overridden at the {{tl|tcl}} level is displayed regardless.
* `extra_info_overridden_set`: Set of booleans specifying, for each extra info arg, whether it was overridden at the
{{tl|tcl}} level. This means, for example, that the values are interpreted according to the language in {{para|1}}
instead of always defaulting to English, as is the case when {{tl|place}} is called directly.
* `form_of_overridden_args`: Set of objects of the form `{new_directive = ``directive``, new_value = ``value``}` for
overriding a given form-of directive (the key) with new directive ``directive`` and new unparsed value ``value``.
Both the key and the replacing directive should be canonical. ``value`` will be parsed in the same way as a regular
form-of directive except that all specified terms are interpreted in the language specified in {{para|1}}, never in
English. This is present so that {{tl|tcl}} can be used on abbreviations like [[GDR]] and [[FYROM]], whose
equivalents in a foreign language have language-specific expansions but where the rest of the call should stay the
same.
* `translation_follows`: If true, any translation specified using t= should follow the definition, after a colon,
rather than preceding, with the definition in parens.
]==]
function export.format(data)
local template_args = data.template_args
local list_param = {list = true}
local boolean_param = {type = "boolean"}
local params = {
[1] = {required = true, type = "language", default = "und"},
[2] = {required = true, list = true},
["t"] = list_param,
["tid"] = {list = true, allow_holes = true},
["cat"] = list_param,
["nocat"] = boolean_param,
["nocap"] = boolean_param,
["sort"] = true,
["pagename"] = true, -- for testing or documentation purposes
["a"] = true,
["addl"] = true,
["def"] = true,
-- params that are only used when transcluding using {{tcl}}/{{transclude}}, to transmit information to {{tcl}}.
["tcl"] = true,
["tcl_t"] = list_param,
["tcl_tid"] = list_param,
["tcl_nolb"] = true,
["tcl_nolc"] = boolean_param,
["tcl_noextratext"] = boolean_param,
}
-- add "extra info" parameters
for _, extra_arg_spec in ipairs(export.extra_info_args) do
params[extra_arg_spec.arg] = list_param
end
-- FIXME, once we've flushed out any uses, delete the following clause. That will cause def= to be ignored.
if template_args.def == "" then
error("Cannot currently pass def= as an empty parameter; use def=- if you want to suppress the definition display")
end
local args = require("Module:parameters").process(template_args, params)
if args.a then
track("a")
if args.a:find("^[Aa]n?$") or args.a:find("^[Tt]he$") then
track("a/article")
else
error("a= can only be used to specify a definite or indefinite article (and preferably use |nocap=1 instead to get the initial letter lowercase); see especially the documentation on the [[Template:place#Mixed format|mixed format]], which can be used to add arbitrary text before the placetype")
end
end
data.args = args
local overall_place_spec = parse_overall_place_spec(data)
data.overall_place_spec = overall_place_spec
return get_def(data) .. (
args.nocat and "" or format_cats(args[1], export.get_cats(args, overall_place_spec), args.sort))
end
--[==[
Actual entry point of {{tl|place}}.
]==]
function export.show(frame)
return export.format {
template_args = frame:getParent().args,
}
end
return export
m05zigq3vsle4fh9g7rc6slab3vvdkk
Modul:place/placetypes
828
76179
375873
344225
2026-09-25T12:50:52Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/92092040|92092040]])
375873
Scribunto
text/plain
local export = {}
export.force_cat = false -- set to true for testing
local m_locations = require("Module:place/locations")
local m_links = require("Module:links")
local m_table = require("Module:table")
local m_strutils = require("Module:string utilities")
local debug_track_module = "Module:debug/track"
local en_utilities_module = "Module:en-utilities"
local dump = mw.dumpObject
local insert = table.insert
local concat = table.concat
local internal_error = m_locations.internal_error
export.internal_error = internal_error
local process_error = m_locations.process_error
export.process_error = process_error
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local ucfirst = m_strutils.ucfirst
local ulower = m_strutils.lower
local rmatch = m_strutils.match
local split = m_strutils.split
--[==[ intro:
This module contains placetype data used by [[Module:place]] and {{tl|place}}, along with a significant amount of code
to work with both placetypes and locations, as well as some placename-related info (FIXME: Consider moving it to
[[Module:place/locations]]). See also [[Module:place/locations]], which has definitions of all known locations. You must
currently load this module using {{cd|require()}}, not using {{cd|mw.loadData()}}.
In particular, it contains two fundamental and tricky functions:
# `get_placetype_equivs`, which finds the equivalent placetypes to look under in order to find a given property, and in
the process correctly handles placetypes with qualifiers (including qualifiers that act similar to "type-raising"
operators in that they do something non-trivial to the placetype to their right) as well as form-of directives and
fallbacks.
# `find_matching_holonym_location`, which looks up a holonym to find a matching known location, but in the process
checks holonyms to the right to make sure there isn't a clash between the user-specified containing holonyms and the
containers of the known location being considered. This is done to prevent overcategorizing when either there are two
known locations with the same name (e.g. Birmingham in England and Birmingham, Alabama in the US), or more generally
two locations with the same name, one of which is a known location but where the other is not (e.g. we're processing
non-known-location Mérida, Spain and don't want it categorized like known location Mérida, Yucatán, Mexico).
Both of these functions are invoked repeatedly, and probably are invoked several times on the same inputs and as a
result are candidates for memoization to speed up the operation of {{tl|place}}.
]==]
------------------------------------------------------------------------------------------
-- Basic utilities --
------------------------------------------------------------------------------------------
--[==[
Return true if `force_cat` is set either in this module or in [[Module:place/locations]].
]==]
function export.get_force_cat()
return export.force_cat or m_locations.force_cat
end
-- Add the page to a tracking "category". To see the pages in the "category",
-- go to [[Wiktionary:Tracking/place/PAGE]] and click on "What links here".
local function track(page)
require(debug_track_module)("place/" .. page)
return true
end
function export.remove_links_and_html(text)
text = m_links.remove_links(text)
return text:gsub("<.->", "")
end
--[==[
Return the singular version of a maybe-plural placetype, or nil if not plural. This correctly handles placetypes with
irregular plurals such as `kibbutzim` plural of `kibbutz` by looking up in a table constructed from the `plural` values
specified in `placetype_data`. If a special plural value is not found, the regular singularization algorithm in
[[Module:en-utilities]] is invoked, which reverses the y -> ies change after vowels and the 'es' addition after sh/ch/x,
and otherwise just subtracts a final 's' (which will incorrectly generate 'passe' for plural 'passes'; FIXME: consider
changing this for words ending in '-sses'). If the generated singular is the same as the passed-in value, nil is
returned.
]==]
function export.maybe_singularize_placetype(placetype)
if not placetype then
return nil
end
if export.plural_placetype_to_singular[placetype] then
return export.plural_placetype_to_singular[placetype]
end
local retval = require(en_utilities_module).singularize(placetype)
if retval == placetype then
return nil
end
return retval
end
-- Return the correct plural of a placetype, and (if `do_ucfirst` is given) make the first letter uppercase. We first
-- look up the plural in `placetype_data`, falling back to pluralize() in [[Module:en-utilities]], which is almost
-- always correct.
function export.pluralize_placetype(placetype, do_ucfirst)
local ptdata = export.placetype_data[placetype]
if ptdata and ptdata.plural then
placetype = ptdata.plural
else
placetype = require(en_utilities_module).pluralize(placetype)
end
if do_ucfirst then
return ucfirst(placetype)
else
return placetype
end
end
--[==[
Get the data associated with a placetype, which may be in its singular or plural form. If `from_category` is specified,
we also look for category-only placetypes (generally plural) followed by `!`. Return three values: (a) the placetype
under which the data can be looked up (i.e. in its singular form if the passed-in `placetype` is plural and did not
match a category-only placetype followed by `!`); (b) the placetype data structure; (c) the type of `placetype` match
that occurred, one of `"direct"` if the canonical placetype is the same as the passed-in `placetype` and also the same
as the key under which `ptdata` was looked up, or `"direct-category"` if the `ptdata` was looked up under a key formed
from the passed-in `placetype` by adding `!`, or `"plural"` if the `ptdata` was looked up under the singularized version
of the plural passed-in `placetype`.
]==]
function export.get_placetype_data(placetype, from_category)
local ptdata = export.placetype_data[placetype]
if ptdata then
return placetype, ptdata, "direct"
end
if from_category then
ptdata = export.placetype_data[placetype .. "!"]
if ptdata then
return placetype .. "!", ptdata, "direct-category"
end
end
local sg_placetype = export.maybe_singularize_placetype(placetype)
if sg_placetype then
ptdata = export.placetype_data[sg_placetype]
if ptdata then
return sg_placetype, ptdata, "plural"
end
end
return nil
end
--[==[
Check for special pseudo-placetypes that should be ignored for categorization purposes.
]==]
function export.placetype_is_ignorable(placetype)
return placetype == "and" or placetype == "or" or placetype:find("^%(")
end
function export.resolve_placetype_aliases(placetype)
return export.placetype_aliases[placetype] or placetype
end
--[==[
Return a property from `placetype_data` for a given placetype. If the placetype isn't found in `placetype_data`, or the
key isn't found in the placetype's entry in `placetype_data`, return nil.
]==]
function export.get_placetype_prop(placetype, key)
-- Usually we are called on equivalent placetypes returned from `get_placetype_equivs`, in which case placetype
-- aliases have been resolved, but sometimes not, e.g. when fetching the indefinite article in
-- get_placetype_article(). `resolve_placetype_aliases` is just a simple lookup and it doesn't hurt to do it twice.
placetype = export.resolve_placetype_aliases(placetype)
if export.placetype_data[placetype] then
return export.placetype_data[placetype][key]
else
return nil
end
end
--[==[
Given a placetype, split the placetype into one or more potential ''splits'', each consisting of a three-element list
{ {``prev_qualifiers``, ``this_qualifier``, ``reduced_placetype``}}, i.e.
# the concatenation of zero or more previously-recognized qualifiers on the left, normally canonicalized (if there are
zero such qualifiers, the value will be nil);
# a single recognized qualifier, normally canonicalized (if there is no qualifier, the value will be nil);
# the "reduced placetype" on the right.
Splitting between the qualifier in (2) and the reduced placetype in (3) happens at each space character, proceeding from
left to right, and stops if a qualifier isn't recognized. All placetypes are canonicalized by checking for aliases
in `placetype_aliases`, but no other checks are made as to whether the reduced placetype is recognized. Canonicalization
of qualifiers does not happen if `no_canon_qualifiers` is specified.
For example, given the placetype `"small beachside unincorporated community"`, the return value will be
{ {
{nil, nil, "small beachside unincorporated community"},
{nil, "small", "beachside unincorporated community"},
{"small", "[[beachfront]]", "unincorporated community"},
{"small [[beachfront]]", "[[unincorporated]]", "community"},
}}
Here, `"beachside"` is canonicalized to `"[[beachfront]]"` and `"unincorporated"` is canonicalized to
`"[[unincorporated]]"`, in both cases according to the entry in `placetype_qualifiers`.
On the other hand, if given `"small former haunted community"`, the return value will be
{ {
{nil, nil, "small former haunted community"},
{nil, "small", "former haunted community"},
{"small", "former", "haunted community"},
}}
because `"small"` and `"former"` but not `"haunted"` are recognized as qualifiers.
Finally, if given `"former adr"`, the return value will be
{ {
{nil, nil, "former adr"},
{nil, "former", "administrative region"},
}}
because `"adr"` is a recognized placetype alias for `"administrative region"`.
]==]
function export.split_qualifiers_from_placetype(placetype, no_canon_qualifiers)
local splits = {{nil, nil, export.resolve_placetype_aliases(placetype)}}
local prev_qualifier = nil
while true do
local qualifier, reduced_placetype = placetype:match("^(.-) (.*)$")
if qualifier then
local canon = export.placetype_qualifiers[qualifier]
if canon == nil then
break
end
local new_qualifier = qualifier
if type(canon) == "table" then
canon = canon.link
end
if not no_canon_qualifiers and canon ~= false then
if canon == true then
new_qualifier = "[[" .. qualifier .. "]]"
else
new_qualifier = canon
end
end
insert(splits, {prev_qualifier, new_qualifier, export.resolve_placetype_aliases(reduced_placetype)})
prev_qualifier = prev_qualifier and prev_qualifier .. " " .. new_qualifier or new_qualifier
placetype = reduced_placetype
else
break
end
end
return splits
end
--[==[
Given a `placetype` (which may be pluralized), return an ordered list of equivalent placetypes to look under to find the
placetype's properties (such as the category or categories to be inserted). The return value is actually an ordered list
of objects of the form `{qualifier=``qualifier``, placetype=``equiv_placetype``}` where ``equiv_placetype`` is a
placetype whose properties to look up, derived from the passed-in placetype or from a contiguous subsequence of the
words in the passed-in placetype (always including the rightmost word in the placetype, i.e. we successively chop off
qualifier words from the left and use the remainder to find equivalent placetypes). ``qualifier`` is the remaining words
not part of the subsequence used to find ``equiv_placetype``; or nil if all words in the passed-in placetype were used
to find ``equiv_placetype``. (FIXME: This qualifier is not currently used anywhere.) Only placetypes for which there is
an entry in `placetype_data` are included. The placetype passed in is always checked first, and will form the first
entry if it exists in `placetype_data`.
'''NOTE:''' This is a tricky function as it implements handling of (a) qualifiers, (b) fallback logic, (c)
"type-raising" qualifiers such as `former`/`ancient`/etc. as well as `fictional` and `mythological`, and (d) form-of
directives, which act somewhat similarly to `former`, and allows interaction between more than one of these
simultaneously (e.g. official names of former places, which have their own categorization).
If {{tl|place}} gets too slow, one potential speedup is to memoize the results of this function, as it appears to be
getting called more than once on the same inputs. Another similar potential speedup is to memoize the results of
`iterate_matching_holonym_location()`.
For example, given the placetype `left tributary`, the following placetype/qualifier combinations are checked in turn:
```
{qualifier = nil, placetype="left tributary"}
{qualifier = "left", placetype="tributary"}
{qualifier = "left", placetype="river"}
```
and the return value will be
{ {
{qualifier = "left", placetype="tributary"},
{qualifier = "left", placetype="river"},
}}
The algorithm first enters the placetype itself into the list, then checks for `left tributary` as a recognized
placetype in `placetype_data` and doesn't find it, so it doesn't enter it into the returned list (if it found it, it
would add it as well as any fallbacks directly after it). It then splits off the recognized qualifier `left` to form the
''reduced placetype'' `tributary`, which is entered into the list because it is found in `placetype_data`. Then, because
it has a fallback `river`, which exists in `placetype_data`, the fallback is entered next.
Another example is `small rural fraziones` (where a ''frazione'' is type of subdivision of a ''comune'' or municipality,
often specifically an outlying hamlet). the placetype/qualifier combinations checked are:
```
{qualifier = nil, placetype="small rural fraziones"}
{qualifier = nil, placetype="small rural frazione"}
{qualifier = "small", placetype="rural fraziones"}
{qualifier = "small", placetype="rural frazione"}
{qualifier = "small [[rural]]", placetype="fraziones"}
{qualifier = "small [[rural]]", placetype="frazione"}
{qualifier = "small [[rural]]", placetype="hamlet"}
{qualifier = "small [[rural]]", placetype="village"}
```
The return value ends up as
{qualifier = "small [[rural]]", placetype="frazione"},
{qualifier = "small [[rural]]", placetype="hamlet"},
{qualifier = "small [[rural]]", placetype="village"},
}}
Here, because the result of singularizing `fraziones` returns a different value from the placetype itself, that
singularized value is checked after the original plural value. Also, in the process of splitting off qualifiers,
they are canonicalized if the entry in `placetype_qualifiers` says to do so; in this case, links are placed around
`rural`. Finally, `frazione` has `hamlet` as its fallback, which in turn has `village` as its fallback, so both
fallbacks end up being returned.
`no_fallback`, if set, disables returning equivalent placetypes based on the `fallback` setting for a placetype. This is
used in the first of two loops in find_placetype_cat_specs() in [[Module:place]] to prefer exact matches for placetypes
such as barangays with later holonyms to matches based on a fallback such as `neighborhood` with an earlier holonym.
See the comment in that function in [[Module:place]] for a more detailed explanation of why this is needed. Only the
placetype itself, and any reduced placetypes created by chopping off recognized qualifiers at the beginning, are
returned; but we do not return reduced placetypes if a containing placetype exists in `placetype_data`. (For example,
`"overseas territory"` has a fallback `"dependent territory"`, and `"overseas"` is also a recognized qualifier. When
`no_fallback` is in place, without the above proviso, we would return `"overseas territory"` followed by `"wilayah"`
with the incorrect effect of classifying an `"overseas territory"` of the United Kingdom such as `"Gibraltar"` under
[[:Category:Territories of the United Kingdom]] instead of [[:Category:Dependent territories of the United Kingdom]].)
As an exception, if `historical`, `ancient`, `former` or the like are found, they proceed ignoring `no_fallback`,
because it seems tricky to handle them correctly in the presence of `no_fallback`, and historical/former placetypes
rarely occur with exact match category specs anyway.
`no_split_qualifiers` prevents splitting off recognized qualifiers and returning the remainder of the placetype as an
equivalent placetype. Only the passed-in placetype, and any fallbacks, will be returned. This is used in
[[Module:category tree/topic cat/data/Places]] when looking up placetypes found in categories. Such placetypes won't
have qualifiers and so it doesn't make sense to try and look for them.
`from_category`, if set, causes category-only placetypes (those ending in `!`) to also be checked.
`form_of_directive`, if set, causes the specified form-of directive (e.g. `FORMER_NAME_OF`) to be prepended to checked
placetypes, their directive-specific type (e.g. `FORMER_NAME_OF_type`), and their classes (`class`) to get the
appropriate placetypes to check for form-of-directive categories. It falls back to the prepended generic `place` as a
placetype, e.g. `FORMER_NAME_OF place`, if nothing else matches.
`no_check_for_inherently_former` is used internally to prevent an infinite loop when checking for `inherently_former`.
`register_former_as_non_former` is a major hack used in `get_bare_categories` to deal with the mismatch between e.g.
known location `Yugoslavia` declaring itself a `country` but definitions of it declaring it a `former country`. It
causes the non-former version of the specified placetype to be included in the returned equivalents along with the
former placetypes. [FIXME: This should apply only to the entries in `former_countries` but it's tricky to do that now;
fix this in the known-location refactor. -- The known-location refactor is already done but we haven't yet fixed this.]
]==]
function export.get_placetype_equivs(placetype, props)
local no_fallback, no_split_qualifiers, no_check_for_inherently_former, from_category, register_former_as_non_former
local form_of_directive
if props then
no_fallback, no_split_qualifiers, no_check_for_inherently_former, from_category, register_former_as_non_former =
props.no_fallback, props.no_split_qualifiers, props.no_check_for_inherently_former, props.from_category,
props.register_former_as_non_former
form_of_directive = props.form_of_directive
end
local equivs = {}
-- Insert `placetype` into `equivs`, along with any fallback placetypes listed in `placetype_data`. `qualifier` is
-- the preceding qualifier to insert into `equivs` along with the placetype (see comment at top of function). If
-- `from_category` is given, we also check for a category-specific entry consisting of the placetype followed by
-- `!`, and in all cases we also check to see if `placetype` is plural, and if so, insert the singularized version
-- along with its fallbacks (if any) in `placetype_data`. `form_of_prefix` is a form-of prefix such as
-- `OFFICIAL_NAME_OF`. If specified, we check the fallbacks of `placetype` without the prefix but then insert into
-- `equivs` the prefixed placetype. This way, if the user says e.g. {{tl|place|pt|@official name of:Cuba|island country|r/Caribbean}},
-- we will correctly categorize into [[:Category:Official names of countries]], rather than only trying to look up
-- `OFFICIAL_NAME_OF island country` and failing, falling back ultimately to [[:Category:Official names of places]].
local function insert_placetype_and_fallbacks(qualifier, placetype, form_of_prefix)
local function insert_equiv(pt)
if form_of_prefix then
-- Let's say the user says {{tl|place|pt|@official name of:Cuba|island country|r/Caribbean}} and we have
-- no entry for `OFFICIAL_NAME_OF island country` but we do for `OFFICIAL_NAME_OF country` (which we end
-- up processing because `island country` falls back to `country`), and that entry in turn is defined
-- using a fallback. We have to insert that fallback-of-fallback, and the easiest/cleanest way of
-- handling this is by calling ourselves recursively.
insert_placetype_and_fallbacks(qualifier, form_of_prefix .. " " .. pt)
else
insert(equivs, {qualifier=qualifier, placetype=pt})
end
end
-- Insert the placetype, along with any fallbacks.
local canon_placetype, ptdata, ptmatch = export.get_placetype_data(placetype, from_category)
if ptdata then
insert_equiv(canon_placetype)
if no_fallback then
return
end
local first_placetype = #equivs + 1
local prev_placetype = nil
while true do
local pt_value = export.placetype_data[canon_placetype]
if not pt_value then
internal_error("Fallback value %s specified for placetype %s but is not in `placetype_data`",
canon_placetype, prev_placetype)
end
if pt_value.fallback then
insert_equiv(pt_value.fallback)
local last_placetype = #equivs
if last_placetype - first_placetype >= 10 then
local fallback_loop = {}
for i = first_placetype, last_placetype do
insert(fallback_loop, equivs[i].placetype)
end
internal_error("Apparent loop in fallback chain: %s", table.concat(fallback_loop, " -> "))
end
prev_placetype = canon_placetype
canon_placetype = pt_value.fallback
else
break
end
end
end
end
-- Insert `placetype` into `equivs`, along with any fallback placetypes listed in `placetype_data`. This is a
-- wrapper around the more basic `insert_placetype_and_fallbacks()` which handles form-of directives. If there is no
-- form-of directive, this function directly calls `insert_placetype_and_fallbacks()`. We do things this way so that
-- form-of directives correctly combine with `former`-type qualifiers. Note that we also have special backups for
-- form-of directives that check `DIRECTIVE place` (and before that, `DIRECTIVE FORMER/ANCIENT place` is there's a
-- `former`-type directive); these backups live outside this function because we want them done once, late, rather
-- than in each invocation of `process_and_insert_placetype()`.
local function process_and_insert_placetype(qualifier, reduced_placetype)
if form_of_directive then
-- First check for e.g. `OFFICIAL_NAME_OF island country` and its fallbacks; then we look for fallbacks of
-- `island country` and check e.g. `OFFICIAL_NAME_OF country` and its fallbacks. All of this is handled by
-- `insert_placetype_and_fallbacks()` with appropriate parameters. After that, check the general class of
-- the directive, e.g. `subpolity` if something like `district` is given. (Eventually, we check for
-- `OFFICIAL_NAME_OF place` as a backup, but this happens at the end outside the loop over qualifiers.)
insert_placetype_and_fallbacks(qualifier, reduced_placetype, form_of_directive)
if not no_fallback then
local reduced_placetype_equivs = export.get_placetype_equivs(reduced_placetype)
local directive_type = export.get_equiv_placetype_prop_from_equivs(reduced_placetype_equivs,
function(pt) return export.get_placetype_prop(pt, form_of_directive .. "_type") or
export.get_placetype_prop(pt, "class") end
)
if not directive_type then
local pt_data = export.get_equiv_placetype_prop_from_equivs(reduced_placetype_equivs,
function(pt) return export.placetype_data[pt] end
)
if pt_data then
internal_error("For placetype %s in conjunction with form-of directive %s, placetype data " ..
'located but directive-specific type property %s missing, and so is "class"; ' ..
"placetypes searched are %s", reduced_placetype, form_of_directive,
form_of_directive .. "_type", reduced_placetype_equivs)
else
-- This should be allowed, as we allow unrecognized placetypes in general.
end
elseif directive_type ~= "!" then
insert_placetype_and_fallbacks(qualifier, directive_type, form_of_directive)
end
end
else
insert_placetype_and_fallbacks(qualifier, reduced_placetype)
end
end
-- Successively split off recognized qualifiers and loop over successively greater sets of qualifiers from the left
-- (unless `no_split_qualifiers` is specified, in which case we don't check for qualifiers).
local splits
if no_split_qualifiers then
splits = {{nil, nil, export.resolve_placetype_aliases(placetype)}}
else
splits = export.split_qualifiers_from_placetype(placetype)
end
for _, split in ipairs(splits) do
local prev_qualifier, this_qualifier, reduced_placetype = unpack(split, 1, 3)
-- If a special "former" qualifier like `former` or `historical` isn't present, and
-- `no_check_for_inherently_former` is not given (this flag is used to avoid infinite loops), check for
-- "inherently former" placetypes like `satrapy` and `treaty port` that always refer to no-longer-existing
-- placetypes, and handle accordingly.
local unlinked_this_qualifier
if this_qualifier and this_qualifier:find("%[") then
unlinked_this_qualifier = export.remove_links_and_html(this_qualifier)
else
unlinked_this_qualifier = this_qualifier
end
local former_qualifiers = this_qualifier and export.former_qualifiers[unlinked_this_qualifier] or nil
if not former_qualifiers and not no_check_for_inherently_former then
former_qualifiers = export.get_equiv_placetype_prop(reduced_placetype,
function(pt) return export.get_placetype_prop(pt, "inherently_former") end,
{no_check_for_inherently_former = true})
end
-- If a special "former" qualifier like `former` or `historical` is present, map it to the appropriate internal
-- qualifiers (`ANCIENT` and/or `FORMER`, which are written in all-caps to distinguish them from user-specified
-- qualifiers), fetch the `former_type` property, and treat the placetype as if a concatenation of the mapped
-- qualifier(s) and the value of `former_type`. For example, if `medieval village` is given, we map `medieval`
-- to `ANCIENT` and `FORMER`, and `village` to its `former_type` of `settlement`, and enter the placetypes
-- `ANCIENT settlement` and `FORMER settlement` (in that order) into `equivs`. If the placetype following the
-- "former" qualifier is recognized in `placetype_data` but has no `former_type` and no fallback with a
-- `former_type` specified, it is an internal error; but if the placetype isn't recognized (e.g. something like
-- `former greenhouse` is specified and we don't have an entry for `greenhouse`), just track the occurrence and
-- don't enter anything into `equivs`.
if former_qualifiers then
-- FIXME: Should we respect `no_fallback` here? My instinct says no.
local reduced_placetype_equivs = export.get_placetype_equivs(reduced_placetype, {
no_check_for_inherently_former = true
})
local former_type = export.get_equiv_placetype_prop_from_equivs(reduced_placetype_equivs,
function(pt) return export.get_placetype_prop(pt, "former_type") or
export.get_placetype_prop(pt, "class") end
)
if not former_type then
local pt_data = export.get_equiv_placetype_prop_from_equivs(reduced_placetype_equivs,
function(pt) return export.placetype_data[pt] end
)
if pt_data then
internal_error("For placetype %s, placetype data located but `former_type` missing; " ..
"placetypes searched are %s", reduced_placetype, reduced_placetype_equivs)
else
-- Enable error when we've verified there aren't any examples.
track("bad-former-placetype")
track("bad-former-placetype/" .. reduced_placetype)
--process_error("For placetype '%s', unrecognized placetype following 'former'-type " ..
-- "qualifier; searched placetype(s) %s", reduced_placetype, dump(reduced_placetype_equivs))
end
elseif former_type ~= "!" then
-- First check directly for `ANCIENT/FORMER` + the original following placetype. This makes it possible
-- for (e.g.) former provinces of the Roman empire to be categorized specially.
for _, former_qualifier in ipairs(former_qualifiers) do
process_and_insert_placetype(prev_qualifier, former_qualifier .. " " .. reduced_placetype)
end
for _, former_qualifier in ipairs(former_qualifiers) do
process_and_insert_placetype(prev_qualifier, former_qualifier .. " " .. former_type)
end
-- HACK! See explanation above for `register_former_as_non_former`.
if register_former_as_non_former then
process_and_insert_placetype(prev_qualifier, reduced_placetype)
end
-- If we're processing a form-of directive, after doing everything else we do
-- `DIRECTIVE ANCIENT/FORMER place` e.g. `OFFICIAL_NAME_OF FORMER place` as a backup.
if form_of_directive and not no_fallback then
for _, former_qualifier in ipairs(former_qualifiers) do
insert_placetype_and_fallbacks(prev_qualifier, form_of_directive .. " " .. former_qualifier ..
" place")
end
end
-- Don't continue processing equivs. The reason is probably the same as the `break` below for
-- qualifier_to_placetype_equivs[]; categories for `former BLAH` are set using `default`, and
-- non-former equivs will otherwise take precedence.
break
end
end
-- Then see if the rightmost split-off qualifier is in qualifier_to_placetype_equivs
-- (e.g. 'fictional *' -> 'fictional location'). If so, add the mapping.
if this_qualifier and export.qualifier_to_placetype_equivs[unlinked_this_qualifier] then
insert(equivs, {
qualifier=prev_qualifier,
placetype=export.qualifier_to_placetype_equivs[unlinked_this_qualifier]
})
-- Don't continue processing equivs; otherwise, if we specify 'mythological city', even though the
-- equivalent entry for 'mythological location' gets inserted ahead of the entry for 'city', the
-- latter ends up generating the category because the category for 'mythological location' is set as
-- the default value, which is used only when no non-default category can be found.
break
end
-- Finally, join the rightmost split-off qualifier to the previously split-off qualifiers to form a combined
-- qualifier, and add it along with reduced_placetype and any mapping in placetype_data for reduced_placetype.
-- NOTE: The first time through this loop, both `prev_qualifier` and `this_qualifier` are nil, and this inserts
-- the full placetype into `equivs`.
local qualifier = prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier
process_and_insert_placetype(qualifier, reduced_placetype)
-- If `no_fallback` and there's an entry in `placetype_data` for this placetype, don't include any reduced
-- placetypes to avoid the "overseas territory treated as a territory" issue describe above.
if no_fallback then
local canon_placetype, ptdata, ptmatch = export.get_placetype_data(reduced_placetype, from_category)
if canon_placetype then
break
end
end
end
-- If we're processing a form-of directive, after doing everything else we do `DIRECTIVE place` e.g.
-- `OFFICIAL_NAME_OF place` as a backup; but only if either the placetype as a whole is recognized or the placetype
-- begins with a recognized qualifier. This latter check is to avoid categorizing into e.g.
-- [[Category:en:Former names of places]] in an invocation like
-- {{place|en|@former name of:Democratic Republic of the Congo|country|r/Central Africa|;|used from 1971–1997}};
-- the `used from 1971–1997` gets treated as a placetype and we're called on it.
if form_of_directive and not no_fallback and (splits[2] or export.get_placetype_data(placetype, from_category)) then
insert_placetype_and_fallbacks(nil, form_of_directive .. " place")
end
return equivs
end
function export.get_equiv_placetype_prop_from_equivs(equivs, fun, continue_on_nil_only)
for _, equiv in ipairs(equivs) do
local retval = fun(equiv.placetype)
if continue_on_nil_only and retval ~= nil or not continue_on_nil_only and retval then
return retval, equiv
end
end
return nil, nil
end
--[==[
Given a placetype `placetype` and a function `fun` of one argument, iteratively call the function on equivalent
placetypes fetched from `get_placetype_equivs` until the function returns a non-falsy value (i.e. not {nil} or {false});
but if `continue_on_nil_only` is specified, the iterations continue until the function returns non non-{nil} value.
FIXME: We should make `continue_on_nil_only` the default; but this requires changing some callers.) When `fun` returns a
non-falsy or non-{nil} value, `get_equiv_placetype_prop` returns two values: the value returned by `fun` and the
equivalent placetype that triggered the non-falsy (or non-{nil}) return value. If `fun` never returns a non-falsy (or
non-{nil}) value, `get_equiv_placetype_prop` returns {nil} for both return values. If `placetype` is passed in as {nil},
the return value is the result of calling `fun` on {nil} (whatever it is) with {nil} for the second return value.
]==]
function export.get_equiv_placetype_prop(placetype, fun, props)
if not placetype then
return fun(nil), nil
end
return export.get_equiv_placetype_prop_from_equivs(export.get_placetype_equivs(placetype, props), fun,
props and props.continue_on_nil_only)
end
--[==[
Return the article that is used with an entry placetype. We proceed as follows:
# See if there is a recognized qualifier at the beginning that specifies an article (including `false` for no article).
This takes precedence over anything else, so that e.g. `various capitals` gets no article rather than "`the"`.
# Then check the placetype or any equivalent placetype for the `entry_placetype_use_the` property, indicating that
`"the"` should be used.
# Otherwise we look to see if the placetype itself (not any equivalents, even those involving deleting a qualifier from
the beginning) has an entry in `placetype_data` that specifies the indefinite article using `entry_placetype_use_the`
(principally for use with placetypes like `union territory`).
# Otherwise, we use [[Module:en-utilities]] to apply the standard algorithm to generate `"an"` for words beginning with
a vowel and `"a"` otherwise.
If `ucfirst` is true, the first letter of the article is made upper-case.
]==]
function export.get_placetype_article(placetype, ucfirst)
local art
local qualifier, reduced_placetype = placetype:match("^(.-) (.*)$")
if qualifier then
local canon = export.placetype_qualifiers[qualifier]
if type(canon) == "table" then
art = canon.article
end
end
if art == false then
return art
end
if art == nil then
local placetype_use_the = export.get_equiv_placetype_prop(placetype,
function(pt) return export.get_placetype_prop(pt, "entry_placetype_use_the") end)
if placetype_use_the then
art = "the"
else
art = export.get_placetype_prop(placetype, "entry_placetype_indefinite_article")
if not art then
art = require(en_utilities_module).get_indefinite_article(placetype)
end
end
end
if ucfirst then
art = m_strutils.ucfirst(art)
end
return art
end
--[==[
Return the preposition that should be used after `placetype` when occurring as an entry placetype or in categories
(e.g. `city >in< France` but `country >of< South America`). The preposition defaults to `"di"` if not specified.
]==]
function export.get_placetype_entry_preposition(placetype)
local pt_prep = export.get_equiv_placetype_prop(placetype,
function(pt) return export.get_placetype_prop(pt, "preposition") end
)
return pt_prep or "di"
end
--[==[
Given a place desc (see top of file) and a holonym object (see top of file), add a key/value into the place desc's
`holonyms_by_placetype` field corresponding to the placetype and placename of the holonym. For example, corresponding
to the holonym "c/Italy", a key "negara" with the list value {"Italy"} will be added to the place desc's
`holonyms_by_placetype` field. If there is already a key with that place type, the new placename will be added to the
end of the value's list.
]==]
function export.key_holonym_into_place_desc(place_desc, holonym)
if not holonym.placetype then
return
end
-- Key in equivalent placetypes, so that e.g. `cities/San Francisco` gets keyed under `city`; but don't do
-- fallbacks, as it doesn't seem correct for the "do other holonyms of the same placetype" algorithm to do holonyms
-- of different types just because they have the same fallback.
local equiv_placetypes = export.get_placetype_equivs(holonym.placetype, {no_fallback = true})
local unlinked_placename = holonym.unlinked_placename
for _, equiv in ipairs(equiv_placetypes) do
local placetype = equiv.placetype
if not place_desc.holonyms_by_placetype then
place_desc.holonyms_by_placetype = {}
end
if not place_desc.holonyms_by_placetype[placetype] then
place_desc.holonyms_by_placetype[placetype] = {unlinked_placename}
else
insert(place_desc.holonyms_by_placetype[placetype], unlinked_placename)
end
end
end
--[=[
Construct a formatted link from the raw link spec `link` given the canonical singular placetype `sg_placetype`. If the
placetype was originally plural, `orig_placetype` should contain this plural value; otherwise it should be nil. This
will construct the appropriate type of link that displays as `orig_placetype` (or otherwise `sg_placetype`) but links to
whatever the `link` spec specifies (which may be `sg_placetype`, a Wikipedia article, etc.). `ptdata` is the placetype
data structure for the placetype, and `from_category` indicates that we are generating the description of a category
(otherwise we are generating the display form of an entry placetype).
]=]
local function make_placetype_link(link, sg_placetype, orig_placetype, ptdata, from_category, noerror)
if not from_category and ptdata.disallow_in_entries then
if noerror then
return "[not meant to be specified directly, with warning: " .. ptdata.disallow_in_entries .. "]"
else
process_error("Placetype %s is not meant to be specified directly: " .. ptdata.disallow_in_entries, sg_placetype)
end
end
if link == nil then
internal_error("Placetype data present for placetype %s but no link= setting given", sg_placetype)
elseif link == true then
if orig_placetype then
return ("[[%s|%s]]"):format(sg_placetype, orig_placetype)
else
return ("[[%s]]"):format(sg_placetype)
end
elseif link == false then
process_error("Placetype %s is not meant to be specified directly, but is only for internal use", sg_placetype)
elseif link == "w" then
return ("[[w:%s|%s]]"):format(sg_placetype, orig_placetype or sg_placetype)
elseif link == "separately" then
if orig_placetype then
local sg_words = split(sg_placetype, " ")
local orig_words = split(orig_placetype, " ")
if #sg_words ~= #orig_words then
internal_error("Can't construct 'separately' link for plural placetype %s as original placetype %s " ..
"has different number of words", orig_placetype, sg_placetype)
else
for i = 1, #sg_words do
if sg_words[i] == orig_words[i] then
sg_words[i] = ("[[%s]]"):format(sg_words[i])
else
sg_words[i] = ("[[%s|%s]]"):format(sg_words[i], orig_words[i])
end
end
return concat(sg_words, " ")
end
else
return (sg_placetype:gsub("([^ ]+)", "[[%1]]"))
end
elseif link:find("^%+") then
link = link:sub(2) -- discard initial +
return ("[[%s|%s]]"):format(link, orig_placetype or sg_placetype)
elseif not orig_placetype then
return link
else
return require(en_utilities_module).pluralize(link)
end
end
--[==[
Get the display form of a placetype by looking it up in `placetype_data`. If the placetype is recognized, or is the
plural of a recognized placetype, the corresponding linked display form is returned (with plural placetypes displaying
as plural but linked to the singular form of the placetype). Otherwise, return nil. If we're generating the description
of a category, `category_type` should be set to one of `"top-level"` (for top-level categories like
[[:Category:Neighborhoods]]), `"noncity"` (for non-city categories like [[:Category:Neighborhoods in Illinois, USA]]) or
`"bandar"` (for city categories like [[:Category:Neighborhoods of Chicago]]). Otherwise, we're generating the description
for use in formatting a {{tl|place}} call, and category-only placetypes ending in `!` will be ignored, along with
special `category_link*` settings. `return_full` is used along with `category_type` and will preferably return the
"full" variant of category link settings, i.e. `full_category_link*`; if they don't exist, the `category_link*` value is
prepended with `"names of"`. `noerror` says to not throw an error when encountering entry placetypes that would be
disallowed.
]==]
function export.get_placetype_display_form(placetype, category_type, return_full, noerror)
local from_category = not not category_type
local canon_placetype, ptdata, ptmatch = export.get_placetype_data(placetype, from_category)
if canon_placetype then
local raw_link
local function is_linked_string(str)
return type(str) == "string" and str:find("%[%[")
end
if category_type then
local fetched_full
local function fetch_maybe_full(prop)
local retval = ptdata["full_" .. prop]
if retval ~= nil then
if return_full then
return retval, true
else
internal_error("Saw full_" .. prop .. "=%s but `return_full` not set, can't handle", retval)
end
end
return ptdata[prop], false
end
local function maybe_prefix(str)
if return_full and not fetched_full then
return "names of " .. str
else
return str
end
end
-- Careful with `false` as possible value.
if category_type == "top-level" then
raw_link, fetched_full = fetch_maybe_full("category_link_top_level")
elseif category_type == "noncity" then
raw_link, fetched_full = fetch_maybe_full("category_link_before_noncity")
elseif category_type == "bandar" then
raw_link, fetched_full = fetch_maybe_full("category_link_before_city")
else
internal_error('Unrecognized value for `category_type` %s, should be "top-level", "noncity" or "bandar"',
category_type)
end
if type(raw_link) == "string" then
return maybe_prefix(raw_link), ptdata
elseif raw_link ~= nil then
return raw_link, ptdata
end
raw_link, fetched_full = fetch_maybe_full("category_link")
if raw_link == false then
return raw_link, ptdata
end
if is_linked_string(raw_link) then
return maybe_prefix(raw_link), ptdata
end
if ptmatch == "plural" then
raw_link, fetched_full = fetch_maybe_full("plural_link")
if raw_link == false then
return raw_link, ptdata
end
if is_linked_string(raw_link) then
return maybe_prefix(raw_link), ptdata
end
end
if raw_link == nil then
raw_link, fetched_full = fetch_maybe_full("link")
end
if raw_link == false then
return raw_link, ptdata
end
return maybe_prefix(make_placetype_link(raw_link, canon_placetype,
placetype ~= canon_placetype and placetype or nil, ptdata, from_category, noerror)), ptdata
else
if ptmatch == "plural" then
raw_link = ptdata.plural_link
if raw_link == false then
process_error("Placetype %s cannot appear plural", placetype)
end
if is_linked_string(raw_link) then
return raw_link, ptdata
end
end
if raw_link == nil then
raw_link = ptdata.link
end
return make_placetype_link(raw_link, canon_placetype,
placetype ~= canon_placetype and placetype or nil, ptdata, from_category, noerror), ptdata
end
end
return nil
end
local function resolve_unlinked_placename_display_aliases(placetype, placename)
local equiv_placetypes = export.get_placetype_equivs(placetype)
for i, equiv in ipairs(equiv_placetypes) do
equiv_placetypes[i] = equiv.placetype
end
local all_display_aliases_found = {}
local all_others_found = {}
for group, key, spec in m_locations.iterate_matching_location {
placetypes = equiv_placetypes,
placename = placename,
alias_resolution = "display",
} do
if spec.alias_of and spec.display then
insert(all_display_aliases_found, {group, key, spec, spec.display_as_full})
else
insert(all_others_found, {group, key, spec})
end
end
if not all_display_aliases_found[1] then
return placename
elseif all_display_aliases_found[2] then
internal_error("Found multiple matching display aliases for placename %s, placetype %s: " ..
"all_display_aliases_found=%s, all_others_found=%s", placename, placetype, all_display_aliases_found,
all_others_found)
elseif all_others_found[1] then
internal_error("Found a display alias along with other possible meanings for placename %s, placetype %s: " ..
"all_display_aliases_found=%s, all_others_found=%s", placename, placetype, all_display_aliases_found,
all_others_found)
else
local group, key, spec, as_full = unpack(all_display_aliases_found[1])
local full, elliptical = m_locations.key_to_placename(group, key)
return as_full and full or elliptical
end
end
--[==[
If `placename` of type `placetype` is a display alias, convert it to its canonical form; otherwise, return unchanged.
Display aliases transform certain placenames into canonical displayed forms. For example, if any of `country/US`,
`country/USA` or `country/United States of America` (or `c/US`, etc.) are given, the result will be displayed as
`United States`.
'''NOTE''': Display aliases change what is displayed from what the editor wrote in the Wikitext. As a result, they
should (a) be non-political in nature, and (b) not involve a change where the word `the` needs to be added or removed.
For example, normalizing `US` and `USA` to `United States` for display purposes is OK but normalizing `Burma` to
`Myanmar` is not (instead a cat alias should be used) because the terms `Burma` and `Myanmar` have clear political
connotations. Similarly, we have a display alias that maps the old name of `Macedonia` as a country (but not a region!)
to `North Macedonia`, but `Republic of Macedonia` is mapped to `North Macedonia` only as a cat alias because the two
terms differ in their use of `the`. (For example, if we had a display alias mapping `Republic of Macedonia` to
`North Macedonia`, the call {{tl|place|en|the <<capital city>> of the <<c/Republic of Macedonia>>}} would wrongly
display as `the [[capital city]] of the [[North Macedonia]]`.) Generally, display normalizations tend to involve
alternative forms (e.g. abbreviations, ellipses, foreign spellings) where the normalization improves clarity and
consistency.
]==]
function export.resolve_placename_display_aliases(placetype, placename)
-- If the placename is a link, apply the alias inside the link.
-- This pattern matches both piped and unpiped links. If the link is not piped, the second capture (linktext) will
-- be empty.
local link, linktext = rmatch(placename, "^%[%[([^|%[%]]+)|?([^|%[%]]-)%]%]$")
if link then
if linktext ~= "" then
local alias = resolve_unlinked_placename_display_aliases(placetype, linktext)
return "[[" .. link .. "|" .. alias .. "]]"
else
local alias = resolve_unlinked_placename_display_aliases(placetype, link)
return "[[" .. alias .. "]]"
end
else
return resolve_unlinked_placename_display_aliases(placetype, placename)
end
end
--[==[
Generate the "prefixed" version of a bare key, i.e. prefix it with `the` if correct for this key.
]==]
function export.get_prefixed_key(key, spec)
if spec.the then
return "the " .. key
else
return key
end
end
-- Necessary for use by [[Module:place]]. FIXME: Reorganize the modules so this isn't necessary.
export.iterate_matching_location = m_locations.iterate_matching_location
--[=[
Iterator that iterates over holonyms in `place_desc`. If `first_holonym_index` is given, start iterating at the
specified holonym and stop either when there are no more holonyms or a holonym with modifier `:also` is found. If
`first_holonym_index` is nil or omitted, iterate over all holonyms regardless. If `include_raw_text_holonyms` is
specified, raw text holonyms (those not of the form `placetype/placename`) are returned as well; they can be identified
by the fact that the `placetype` field in the holonym structure is nil. Two values are returned at each iteration, the
holonym index and holonym structure, similar to `ipairs()`.
]=]
function export.get_holonyms_to_check(place_desc, first_holonym_index, include_raw_text_holonyms)
local stop_at_also = not not first_holonym_index
return function(place_desc, index)
while true do
index = index + 1
local this_holonym = place_desc.holonyms[index]
-- If we were passed in a starting holonym index, go up to but not including a holonym marked with `:also`
-- (continue_cat_loop); the categorization code will then restart the loop at that holonym. That holonym
-- will have `:also` marked on it, so make sure not to stop immediately if the first holonym is marked with
-- `:also`.
if not this_holonym or stop_at_also and index > first_holonym_index and this_holonym.continue_cat_loop then
return nil
end
-- If not placetype, we're processing raw text, which we normally want to skip.
if include_raw_text_holonyms or this_holonym.placetype then
return index, this_holonym
end
end
end, place_desc, first_holonym_index and first_holonym_index - 1 or 0
end
--[==[
If the holonym in `data` (in the format as passed to a category handler) refers to a known location, iterate over all
such known locations, returning for each location the corresponding key, spec and group as well as the trail of
ancestral containers. Unlike `iterate_matching_location()`, this specifically checks that there is no mismatch between
the location's containers at any level and any of the following holonyms in the {{tl|place}} spec. The fields in `data`
are:
* `holonym_placetype`: The placetype of the holonym. It can actually be a list of possible placetypes, as with
`iterate_matching_location()`.
* `holonym_placename`: The placename of the holonym.
* `holonym_index`: The index of the holonym among the holonyms in `place_desc`, or nil if the holonym is not among the
holonyms in `place_desc`. (If a holonym index is given, we check for container mismatches among the holonyms
following the specified index, stopping either when encountering a holonym marked with modifier `:also` or, if none
exist, when we run out of holonyms. If no holonym index is given, we check all holonyms for container mismatches.)
* `place_desc`: Description of the place; used for the holonyms, to check for container mismatches.
Returns four values: the location group, the canonical key by which the location is known, the spec object describing
the location and the trail of ancestral containers for the location. The first three values are the same as for
`iterate_matching_location`.
]==]
function export.iterate_matching_holonym_location(data)
local holonym_placetype, holonym_placename, holonym_index, place_desc =
data.holonym_placetype, data.holonym_placename, data.holonym_index, data.place_desc
local matching_location_iterator = m_locations.iterate_matching_location {
placetypes = holonym_placetype,
placename = holonym_placename,
}
return function()
while true do
local group, key, spec = matching_location_iterator()
if not group then
return nil
end
local container_trail = {}
-- For each level of container, check that there are no mismatches (i.e. other location of the same
-- placetype) mentioned. We allow a mismatch at a given level if there's also a match with the container
-- at that level. For example, in the case of Kansas City, defined in [[Module:place/locations]] as a city
-- in Missouri, if we define it as {{tl|place|city|s/Missouri,Kansas}}, we ignore the mismatching state of
-- Kansas because the correct state of Missouri was also mentioned. But imagine we are defining Newark,
-- Delaware as {{tl|place|city|s/Delaware|c/US}} and (as is the case) we have an entry for Newark, New
-- Jersey in [[Module:place/locations]]. Just because the containing location `US` matches isn't enough,
-- because Newark, NJ also has New Jersey as a containing location and there's a mismatch at that level. If
-- there are no mismatches at any level we assume we're dealing with the right known location.
--
-- If at a given level there are multiple containing locations, we count a match if any holonym matches any
-- containing location, and a mismatch only if a holonym exists of the same placetype that doesn't match any
-- containing location.
local containers_mismatch = false
for containers in m_locations.iterate_containers(group, key, spec) do
insert(container_trail, containers)
local match_at_level = false
local mismatch_at_level = false
for other_holonym_index, other_holonym in export.get_holonyms_to_check(place_desc,
holonym_index and holonym_index + 1 or nil) do
local other_source_holonym = other_holonym.augmented_from_holonym
if other_source_holonym and other_source_holonym.placetype == holonym_placetype and
other_source_holonym.unlinked_placename ~= holonym_placename then
-- Ignore holonyms added during the augmentation process for other holonyms of the same
-- placetype as the placetype of the holonym we're considering. See comment in
-- augment_holonyms_with_container() for why we do this.
-- continue; grrr, no 'continue' in Lua
else
local holonym_matches_at_level = false
local holonym_exists_with_same_placetype = false
for _, container in ipairs(containers) do
if not container.spec.no_check_holonym_mismatch then
local full_container_placename, elliptical_container_placename =
m_locations.key_to_placename(container.group, container.key)
local placetypes = container.spec.placetype
if type(placetypes) ~= "table" then
placetypes = {placetypes}
end
local placetype_equivs = {}
for _, pt in ipairs(placetypes) do
m_table.extend(placetype_equivs, export.get_placetype_equivs(pt))
end
local this_holonym_matches = export.get_equiv_placetype_prop_from_equivs(
placetype_equivs, function(placetype)
return other_holonym.placetype == placetype and
(other_holonym.unlinked_placename == full_container_placename or
other_holonym.unlinked_placename == elliptical_container_placename)
end
)
if this_holonym_matches then
holonym_matches_at_level = true
break
end
local this_holonym_exists_with_same_placetype = export.get_equiv_placetype_prop_from_equivs(
placetype_equivs, function(placetype)
return other_holonym.placetype == placetype
end
)
if this_holonym_exists_with_same_placetype then
-- We seem to have a mismatch at this level. But before we decide conclusively that this
-- is the case, check to see whether the putative mismatch is an alias and matches when
-- we resolve the alias.
for oh_group, oh_key, oh_spec, oh_container_trail in
export.iterate_matching_holonym_location {
holonym_placetype = other_holonym.placetype,
holonym_placename = other_holonym.unlinked_placename,
holonym_index = other_holonym_index,
place_desc = place_desc,
} do
local oh_full_placename, oh_elliptical_placename =
m_locations.key_to_placename(oh_group, oh_key)
if oh_full_placename == full_container_placename or
oh_elliptical_placename == elliptical_container_placename then
-- Alias matched when resolved.
this_holonym_matches = true
break
end
end
if this_holonym_matches then
-- Alias matched above when resolved.
holonym_matches_at_level = true
break
else
-- Not an alias, or doesn't match when resolved. We have a true mismatch.
holonym_exists_with_same_placetype = true
end
end
end
end
if holonym_matches_at_level then
match_at_level = true
break
end
if holonym_exists_with_same_placetype then
mismatch_at_level = true
end
end
end
if not match_at_level and mismatch_at_level then
containers_mismatch = true
break
end
end
if not containers_mismatch then
return group, key, spec, container_trail
end
end
end
end
--[==[
If the holonym in `data` (in the format as passed to a category handler) refers to a known location, find and return the
corresponding key, spec and group as well as the trail of ancestral containers. This is like
`iterate_matching_holonym_location()` but throws an error if more than one location matches. (An example where this
would happen is {{tl|place|en|neighborhood|city/Newcastle}}, because there are two known locations named Newcastle. To
fix this, specify additional following disambiguating holonyms, e.g.
{{tl|place|en|neighborhood|city/Newcastle|s/New South Wales}}.
]==]
function export.find_matching_holonym_location(data)
local all_found = {}
for group, key, spec, container_trail in export.iterate_matching_holonym_location(data) do
insert(all_found, {group, key, spec, container_trail})
end
if not all_found[1] then
return nil
elseif all_found[2] then
local holonym_placetype = data.holonym_placetype
if type(holonym_placetype) == "table" then
holonym_placetype = concat(holonym_placetype, ",")
end
local found_keys = {}
for _, found in ipairs(all_found) do
local _, key, _, _ = unpack(found)
insert(found_keys, key)
end
error(("Found multiple matching locations for holonym '%s/%s'; specify disambiguating context in the " ..
"containing holonyms: %s"):format(holonym_placetype, data.holonym_placename, dump(found_keys)))
else
return unpack(all_found[1])
end
end
------------------------------------------------------------------------------------------
-- Placename and placetype data --
------------------------------------------------------------------------------------------
--[==[ var:
This is a map from aliases to their canonical forms. Any placetypes appearing as keys here will be mapped to their
canonical forms in all respects, including the display form. Contrast entries in 'placetype_data' with a fallback, which
applies to categorization and other processes but not to display.
The most important aliases are for holonym placetypes, particularly those that occur often such as "negara", "negeri",
"province" and the like. Particularly long placetypes that mostly occur as entry placetypes (e.g.
"census-designated place") can be given abbreviations, but it is generally preferred to spell out the entry placetype.
Note also that we purposely avoid certain abbreviations that would be ambiguous (e.g. "d", which could variously be
interpreted as "department", "daerah" or "division").
]==]
export.placetype_aliases = {
["acomm"] = "autonomous community",
["adr"] = "administrative region",
["adterr"] = "administrative territory", -- Pakistan
["aobl"] = "autonomous oblast",
["aokr"] = "autonomous okrug",
["ap"] = "autonomous province",
["apref"] = "autonomous prefecture",
["aprov"] = "autonomous province",
["ar"] = "autonomous region",
["arch"] = "archipelago",
["arep"] = "autonomous republic",
["aterr"] = "autonomous territory",
["atu"] = "autonomous territorial unit",
["bor"] = "borough",
["c"] = "negara",
["can"] = "canton",
["carea"] = "council area",
["cc"] = "negara bahagian",
["cdblock"] = "community development block",
["cdep"] = "Crown dependency",
["CDP"] = "census-designated place",
["cdp"] = "census-designated place",
["clcity"] = "county-level city",
["co"] = "kaunti",
["cobor"] = "county borough",
["colcity"] = "county-level city",
["coll"] = "collectivity",
["comm"] = "community",
["cont"] = "benua",
["contr"] = "kawasan benua",
["contregion"] = "kawasan benua",
["cpar"] = "civil parish",
["damun"] = "direct-administered municipality",
["dep"] = "dependency",
["department capital"] = "departmental capital",
["dept"] = "department",
["depterr"] = "dependent territory",
["dist"] = "daerah",
["distmun"] = "district municipality",
["div"] = "division",
["emp"] = "empayar",
["fpref"] = "French prefecture",
["gov"] = "kegabenoran",
["govnat"] = "kegabenoran",
["home-rule city"] = "home rule city",
["home-rule municipality"] = "home rule municipality",
["inner-city area"] = "inner city area",
["ires"] = "Indian reservation",
["isl"] = "pulau",
["lbor"] = "London borough",
["lga"] = "local government area",
["lgarea"] = "local government area",
["lgd"] = "local government district",
["lgdist"] = "local government district",
["metbor"] = "metropolitan borough",
["metcity"] = "metropolitan city",
["metmun"] = "metropolitan municipality",
["mtn"] = "gunung",
["mun"] = "municipality",
["mundist"] = "municipal district",
["nonmetropolitan county"] = "non-metropolitan county",
["obl"] = "oblast",
["okr"] = "okrug",
["p"] = "province",
["par"] = "parish",
["parmun"] = "parish municipality",
["pen"] = "semenanjung",
["plcity"] = "prefecture-level city",
["plcolony"] = "Polish colony",
["pref"] = "prefecture",
["prefcity"] = "prefecture-level city",
["preflcity"] = "prefecture-level city",
["prov"] = "province",
["r"] = "wilayah",
["range"] = "mountain range",
["rcm"] = "regional county municipality",
["rcomun"] = "regional county municipality",
["rdist"] = "regional district",
["rep"] = "republic",
["rhrom"] = "rural hromada",
["riv"] = "river",
["rmun"] = "regional municipality",
["robor"] = "royal borough",
["romp"] = "Roman province",
["runit"] = "regional unit",
["rurmun"] = "rural municipality",
["s"] = "negeri",
["sar"] = "special administrative region",
["shrom"] = "settlement hromada",
["spref"] = "subprefecture",
["sprefcity"] = "sub-prefectural city",
["sprovcity"] = "subprovincial city",
["submet city"] = "sub-metropolitan city",
["submetropolitan city"] = "sub-metropolitan city",
["sub-prefecture-level city"] = "sub-prefectural city",
["sub-provincial city"] = "subprovincial city",
["sub-provincial district"] = "subprovincial district",
["terr"] = "territory",
["terrauth"] = "territorial authority",
["twp"] = "township",
["twpmun"] = "township municipality",
["uauth"] = "unitary authority",
["ucomm"] = "unincorporated community",
["udist"] = "unitary district",
["uhrom"] = "urban hromada",
["uterr"] = "union territory",
["utwpmun"] = "united township municipality",
["val"] = "valley",
["vdc"] = "village development committee",
["vil"] = "kampung",
["voi"] = "voivodeship",
["wcomm"] = "Welsh community",
-- Full English placetype aliases retained for compatibility with upstream data and older calls.
["capital city"] = "ibu kota",
["city"] = "bandar",
["city-state"] = "negara kota",
["confederation"] = "persekutuan",
["constituent country"] = "negara bahagian",
["continent"] = "benua",
["continental region"] = "kawasan benua",
["country"] = "negara",
["county"] = "kaunti",
["desert"] = "gurun",
["district"] = "daerah",
["district capital"] = "ibu daerah",
["empire"] = "empayar",
["federal territory"] = "wilayah persekutuan",
["forest"] = "hutan",
["geographic and cultural area"] = "kawasan geografi dan budaya",
["geographic region"] = "kawasan geografi",
["governorate"] = "kegabenoran",
["hemisphere"] = "hemisfera",
["highway"] = "lebuh raya",
["hill"] = "bukit",
["island"] = "pulau",
["lake"] = "tasik",
["mountain"] = "gunung",
["national capital"] = "ibu negara",
["ocean"] = "lautan",
["peninsula"] = "semenanjung",
["polity"] = "tatanegara",
["region"] = "wilayah",
["sea"] = "laut",
["settlement"] = "petempatan",
["star"] = "bintang",
["state"] = "negeri",
["state capital"] = "ibu negeri",
["strait"] = "selat",
["subdistrict"] = "subdaerah",
["subdivision"] = "subbahagian",
["supercontinent"] = "superbenua",
["town"] = "pekan",
["village"] = "kampung",
}
local no_link_def_article = {link = false, article = "the"}
local no_link_no_article = {link = false, article = false}
--[==[ var:
These qualifiers can be prepended onto any placetype and will be handled correctly. For example, the placetype
`large city` will be displayed as `large <nowiki>[[city]]</nowiki>` and categorized as if `city` were specified. If the
value in the following table is a string, the qualifier will display according to the string. If the value is `true`,
the qualifier will be linked to its corresponding Wiktionary entry. If the value is `false`, the qualifier will not be
linked but will appear as-is. Note that these qualifiers do not override placetypes with entries elsewhere that contain
those same qualifiers. For example, the entry for `inland sea` in `placetype_data` will apply in preference to treating
`inland sea` as equivalent to `sea`.
]==]
export.placetype_qualifiers = {
-- generic qualifiers
["huge"] = false,
["tiny"] = false,
["large"] = false,
["big"] = false,
["mid-size"] = false,
["mid-sized"] = false,
["small"] = false,
["sizable"] = false,
["important"] = false,
["long"] = false,
["short"] = false,
["major"] = false,
["minor"] = false,
["high"] = false,
["tall"] = false,
["low"] = false,
["left"] = false, -- left tributary
["right"] = false, -- right tributary
["modern"] = false, -- for use in opposition to "ancient" in another definition
-- "former" qualifiers
["abandoned"] = true,
["ancient"] = true,
["deserted"] = true,
["extinct"] = true,
["former"] = false,
["historic"] = "historical",
["historical"] = true,
["medieval"] = true,
["mediaeval"] = true,
["ruined"] = true,
["traditional"] = true,
-- sea qualifiers
["coastal"] = true,
["inland"] = true, -- note, we also have an entry in placetype_data for 'inland sea' to get a link to [[inland sea]]
["maritime"] = true,
["overseas"] = true,
["seaside"] = true,
["beachfront"] = true,
["beachside"] = true,
["riverside"] = true,
-- lake qualifiers
["freshwater"] = true,
["saltwater"] = true,
["endorheic"] = true,
["oxbow"] = true,
["ox-bow"] = "[[oxbow]]", -- [[ox-bow]] is a red link
["tidal"] = true,
-- land qualifiers
["hilltop"] = true,
["hilly"] = true,
["insular"] = true,
["peninsular"] = true,
["chalk"] = true,
["karst"] = true,
["limestone"] = true,
["mountainous"] = true,
["mountaintop"] = true,
["alpine"] = true,
["volcanic"] = true, -- for an island
-- political status qualifiers
["autonomous"] = true,
["incorporated"] = true,
["special"] = true,
["unincorporated"] = true,
["coterminous"] = true,
-- monetary status/etc. qualifiers
["fashionable"] = true,
["wealthy"] = true,
["affluent"] = true,
["declining"] = true,
-- city vs. rural qualifiers
["urban"] = true,
["suburban"] = true,
["exurban"] = true,
["outlying"] = true,
["remote"] = true,
["rural"] = true,
["outback"] = true,
["inner"] = false,
["inner-city"] = true,
["central"] = false,
["outer"] = false,
-- land use qualifiers
["residential"] = true,
["agricultural"] = true,
["business"] = true,
["commercial"] = true,
["industrial"] = true,
-- business use qualifiers
["railroad"] = true,
["railway"] = true,
["farming"] = true,
["fishing"] = true,
["mining"] = true,
["logging"] = true,
["cattle"] = true,
-- tourism use qualifiers
["resort"] = true, -- note, we also have 'resort city' and 'resort town', that take precedecne
["spa"] = true, -- note, we also have 'spa city' and 'spa town', that take precedecne
["ski"] = true, -- note, we also have 'ski resort city' and 'ski resort town', that take precedecne
-- religious qualifiers
["holy"] = true,
["sacred"] = true,
["religious"] = true,
["secular"] = true,
-- qualifiers for nonexistent places
["claimed"] = false,
["fictional"] = true,
["legendary"] = true,
["mythical"] = true,
["mythological"] = true,
-- directional qualifiers
["northern"] = false,
["southern"] = false,
["eastern"] = false,
["western"] = false,
["north"] = false,
["south"] = false,
["east"] = false,
["west"] = false,
["northeastern"] = false,
["southeastern"] = false,
["northwestern"] = false,
["southwestern"] = false,
["northeast"] = false,
["southeast"] = false,
["northwest"] = false,
["southwest"] = false,
-- seasonal qualifiers
["summer"] = true, -- e.g. for 'summer capital'
["winter"] = true,
-- legal status qualifiers
-- FIXME: Two-word qualifiers don't work yet. But you can enter "de-facto" and it's canonicalized to [[de facto]].
["official"] = true,
["unofficial"] = true,
["de facto"] = true, -- 'de facto capital'
["de-facto"] = "[[de facto]]", -- [[de-facto]] is a red link
["de jure"] = true, -- 'de jure capital'
["de-jure"] = "[[de jure]]", -- [[de-jure]] is a red link
-- NOTE: 'unrecognized/unrecognised' are handled as placetypes 'unrecognized country', 'unrecognized state'
-- misc. qualifiers
["planned"] = true,
["chartered"] = true,
["landlocked"] = true,
["uninhabited"] = true,
-- superlative qualifiers
["first"] = no_link_def_article,
["second"] = no_link_def_article, -- for "second largest" etc.
["third"] = no_link_def_article,
["fourth"] = no_link_def_article,
["last"] = no_link_def_article,
["only"] = no_link_def_article,
["sole"] = no_link_def_article,
["main"] = no_link_def_article,
["largest"] = no_link_def_article,
["biggest"] = no_link_def_article,
["smallest"] = no_link_def_article,
["shortest"] = no_link_def_article,
["longest"] = no_link_def_article,
["tallest"] = no_link_def_article,
["highest"] = no_link_def_article,
["lowest"] = no_link_def_article,
["leftmost"] = no_link_def_article,
["rightmost"] = no_link_def_article,
["innermost"] = no_link_def_article,
["outermost"] = no_link_def_article,
["northernmost"] = no_link_def_article,
["southernmost"] = no_link_def_article,
["westernmost"] = no_link_def_article,
["easternmost"] = no_link_def_article,
["northwesternmost"] = no_link_def_article,
["southwesternmost"] = no_link_def_article,
["northeasternmost"] = no_link_def_article,
["southeasternmost"] = no_link_def_article,
-- several/various
["several"] = no_link_no_article,
["various"] = no_link_no_article,
["numerous"] = no_link_no_article,
["multiple"] = no_link_no_article,
["many"] = no_link_no_article,
["other"] = no_link_no_article,
}
--[==[ var:
In this table, the key qualifiers should be treated the same as the value qualifiers for categorization purposes. This
is overridden by `placetype_data` and `qualifier_to_placetype_equivs`.
]==]
export.former_qualifiers = {
["abandoned"] = {"FORMER"},
["ancient"] = {"ANCIENT", "FORMER"},
["former"] = {"FORMER"},
["extinct"] = {"FORMER"},
["historic"] = {"FORMER"},
["historical"] = {"FORMER"},
["medieval"] = {"ANCIENT", "FORMER"},
["mediaeval"] = {"ANCIENT", "FORMER"},
["ruined"] = {"ANCIENT", "FORMER"},
["traditional"] = {"FORMER"},
}
--[==[ var:
In this table, any placetypes containing these qualifiers that do not occur in `placetype_data` should be mapped to the
specified placetypes for categorization purposes. Entries here are overridden by `placetype_data`.
]==]
export.qualifier_to_placetype_equivs = {
["fictional"] = "fictional location",
["legendary"] = "mythological location",
["mythical"] = "mythological location",
["mythological"] = "mythological location",
-- For e.g. Taiwan as a "claimed province" of China; parts of Belize as claimed by Guatemala; various islands
-- claimed by various parties in East Asia. FIXME: We should conditionalize on what is being claimed since there are
-- also claimed capitals, e.g. Israel and Palestine claim Jerusalem as their capital.
["claimed"] = "claimed political division",
}
--[==[ var:
Mapping from placetypes to the corresponding plural category-only placetype for a capital of that placetype. The reverse
mapping also exists.
]==]
export.placetype_to_capital_cat = {
["autonomous community"] = "autonomous community capitals",
["canton"] = "cantonal capitals",
["comarca"] = "comarca capitals",
["negara"] = "ibu negara",
-- The following are not obviously different from 'county seats' but the latte terminology is used in the US.
["kaunti"] = "county capitals",
["department"] = "departmental capitals",
["daerah"] = "ibu daerah",
["division"] = "division capitals",
["emirate"] = "emirate capitals",
["kegabenoran"] = "governorate capitals",
["hromada"] = "hromada capitals",
["krai"] = "krai capitals",
["metropolitan city"] = "metropolitan city capitals",
["municipality"] = "municipal capitals",
["oblast"] = "oblast capitals",
["okrug"] = "okrug capitals",
["prefecture"] = "prefectural capitals",
["province"] = "provincial capitals",
["raion"] = "raion capitals",
["regency"] = "regency capitals",
["wilayah"] = "regional capitals",
["regional unit"] = "regional unit capitals",
["republic"] = "republic capitals",
["negeri"] = "ibu negeri",
["territory"] = "territorial capitals",
["voivodeship"] = "voivodeship capitals",
}
--[==[ var:
This contains placenames that should be preceded by an article (almost always "the"). '''NOTE''': There are multiple
ways that placenames can come to be preceded by "the":
# Listed here.
# Given in [[Module:place/locations]] with an initial "the". All such placenames are added to this map by the code
just below the map.
# The placetype of the placename has `holonym_use_the = true` in its placetype_data.
# A regex in placename_the_re matches the placename.
Note that "the" is added only before the first holonym in a place description.
]==]
export.placename_article = {
-- This should only contain info that can't be inferred from [[Module:place/locations]].
["archipelago"] = {
["Cyclades"] = "the",
["Dodecanese"] = "the",
},
["negara"] = {
["Holy Roman Empire"] = "the",
},
["empayar"] = {
["Holy Roman Empire"] = "the",
},
["pulau"] = {
["North Island"] = "the",
["South Island"] = "the",
},
["wilayah"] = {
["Balkans"] = "the",
["Russian Far East"] = "the",
["Caribbean"] = "the",
["Caucasus"] = "the",
["Middle East"] = "the",
["New Territories"] = "the",
["North Caucasus"] = "the",
["South Caucasus"] = "the",
["West Bank"] = "the",
["Gaza Strip"] = "the",
},
["valley"] = {
["San Fernando Valley"] = "the",
},
}
--[==[ var:
Regular expressions to apply to determine whether we need to put 'the' before a holonym. The key "*" applies to all
holonyms, otherwise only the regexes for the holonym's placetype apply.
]==]
export.placename_the_re = {
-- We don't need entries for peninsulas, seas, oceans, gulfs or rivers
-- because they have holonym_use_the = true.
["*"] = {"^Isle of ", " Islands$", " Mountains$", " Empire$", " Country$", " Region$", " District$", "^City of "},
["bay"] = {"^Bay of "},
["tasik"] = {"^Lake of "},
["negara"] = {"^Republic of ", " Republic$"},
["republic"] = {"^Republic of ", " Republic$"},
["wilayah"] = {" [Rr]egion$"},
["river"] = {" River$"},
["local government area"] = {"^Shire of "},
["kaunti"] = {"^Shire of "},
["Indian reservation"] = {" Reservation", " Nation"},
["tribal jurisdictional area"] = {" Reservation", " Nation"},
}
--[==[ var:
If any of the following holonyms are present, the associated holonyms are automatically added to the end of the list of
holonyms for categorization (but not display) purposes.
]==]
export.cat_implications = {
["wilayah"] = {
["Eastern Europe"] = {"benua/Europe"},
["Central Europe"] = {"benua/Europe"},
["Western Europe"] = {"benua/Europe"},
["South Europe"] = {"benua/Europe"},
["Southern Europe"] = {"benua/Europe"},
["Northern Europe"] = {"benua/Europe"},
["Northeast Europe"] = {"benua/Europe"},
["Northeastern Europe"] = {"benua/Europe"},
["Southeast Europe"] = {"benua/Europe"},
["Southeastern Europe"] = {"benua/Europe"},
["North Caucasus"] = {"benua/Europe"},
["South Caucasus"] = {"benua/Asia"},
["South Asia"] = {"benua/Asia"},
["Southern Asia"] = {"benua/Asia"},
["East Asia"] = {"benua/Asia"},
["Eastern Asia"] = {"benua/Asia"},
["Central Asia"] = {"benua/Asia"},
["West Asia"] = {"benua/Asia"},
["Western Asia"] = {"benua/Asia"},
["Southeast Asia"] = {"benua/Asia"},
["North Asia"] = {"benua/Asia"},
["Northern Asia"] = {"benua/Asia"},
["Anatolia"] = {"benua/Asia"},
["Asia Minor"] = {"benua/Asia"},
["Mesopotamia"] = {"benua/Asia"},
["North Africa"] = {"benua/Africa"},
["Central Africa"] = {"benua/Africa"},
["West Africa"] = {"benua/Africa"},
["East Africa"] = {"benua/Africa"},
["Southern Africa"] = {"benua/Africa"},
["Central America"] = {"benua/Central America"},
["Caribbean"] = {"benua/North America"},
["Polynesia"] = {"benua/Oceania"},
["Micronesia"] = {"benua/Oceania"},
["Melanesia"] = {"benua/Oceania"},
["Siberia"] = {"country/Russia", "benua/Asia"},
["Russian Far East"] = {"country/Russia", "benua/Asia"},
["South Wales"] = {"negara bahagian/Wales", "benua/Europe"},
["Balkans"] = {"benua/Europe"},
["West Bank"] = {"country/Palestine", "benua/Asia"},
["Gaza"] = {"country/Palestine", "benua/Asia"},
["Gaza Strip"] = {"country/Palestine", "benua/Asia"},
}
}
------------------------------------------------------------------------------------------
-- Category and display handlers --
------------------------------------------------------------------------------------------
local function city_type_cat_handler(data)
local entry_placetype = data.entry_placetype
local generic_before_non_cities = export.get_placetype_prop(entry_placetype, "generic_before_non_cities")
if not generic_before_non_cities then
internal_error("city_type_cat_handler called on placetype %s that doesn't have a `generic_before_non_cities`" ..
" setting", entry_placetype)
end
local plural_entry_placetype = export.pluralize_placetype(entry_placetype)
local group, key, spec, container_trail = export.find_matching_holonym_location(data)
if group and not spec.is_former_place and not spec.is_city then
-- Categorize both in key, and in the larger polity that the key is part of, e.g. [[Hirakata]] goes in both
-- "Cities in Osaka Prefecture" and "Cities in Japan". (But don't do the latter if no_container_cat is set.)
local cap_plural_entry_placetype = ucfirst(plural_entry_placetype)
local retcats = {("%s %s %s"):format(cap_plural_entry_placetype, generic_before_non_cities,
export.get_prefixed_key(key, spec))}
if container_trail[1] and not spec.no_container_cat then
for _, container in ipairs(container_trail[1]) do
insert(retcats, ("%s %s %s"):format(cap_plural_entry_placetype, generic_before_non_cities,
export.get_prefixed_key(container.key, container.spec)))
end
end
return retcats
end
end
local function capital_city_cat_handler(data, non_city)
local holonym_placetype, holonym_placename, holonym_index, place_desc =
data.holonym_placetype, data.holonym_placename, data.holonym_index, data.place_desc
-- The first time we're called we want to return something; otherwise we will be called for later-mentioned
-- holonyms, which can result in wrongly classifying into e.g. `National capitals`. Simulate the loop in
-- find_placetype_cat_specs() over holonyms so we get the proper `Cities in ...` categories as well as the capital
-- category/categories we add below.
local retcats
if not non_city and place_desc.holonyms then
for h_index, holonym in export.get_holonyms_to_check(place_desc, holonym_index) do
local h_placetype, h_placename = holonym.placetype, holonym.unlinked_placename
retcats = city_type_cat_handler {
entry_placetype = "bandar",
holonym_placetype = h_placetype,
holonym_placename = h_placename,
holonym_index = h_index,
place_desc = place_desc,
}
if retcats then
break
end
end
end
if not retcats then
retcats = {}
end
-- Now find the appropriate capital-type category for the placetype of the holonym, e.g. 'State capitals'. If we
-- recognize the holonym among the known holonyms in [[Module:place/locations]], also add a category like 'State
-- capitals of the United States'. Truncate e.g. 'autonomous region' to 'region', 'union territory' to 'territory'
-- when looking up the type of capital category, if we can't find an entry for the holonym placetype itself (there's
-- an entry for 'autonomous community').
local capital_cat = export.placetype_to_capital_cat[holonym_placetype]
if not capital_cat then
capital_cat = export.placetype_to_capital_cat[holonym_placetype:gsub("^.* ", "")]
end
if capital_cat then
capital_cat = ucfirst(capital_cat)
local inserted_specific_variant_cat = false
if holonym_index then
-- Now find the first recognized holonym location. We don't stop when :also is seen because of the common pattern
-- where we use :also to specify that a given city is the capital at multiple surrounding levels.
local matching_group, matching_key, matching_spec, matching_container_trail, matching_holonym_index
for h_index = holonym_index, #place_desc.holonyms do
if place_desc.holonyms[h_index].placetype then
matching_group, matching_key, matching_spec, matching_container_trail = export.find_matching_holonym_location {
holonym_placetype = place_desc.holonyms[h_index].placetype,
holonym_placename = place_desc.holonyms[h_index].unlinked_placename,
holonym_index = h_index,
place_desc = place_desc,
}
if matching_group then
matching_holonym_index = h_index
break
end
end
end
if matching_holonym_index == holonym_index then
if matching_container_trail[1] and not matching_spec.no_container_cat then
for _, container in ipairs(matching_container_trail[1]) do
insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(container.key,
container.spec)))
inserted_specific_variant_cat = true
end
end
elseif matching_holonym_index then
-- Check to make sure that the holonym placetype we were called on is listed among the
-- divtypes of the location we found.
local function insert_specific_variant_if_possible(key, spec)
return export.get_equiv_placetype_prop(holonym_placetype, function(pt)
local plural_holonym_placetype = export.pluralize_placetype(pt)
local saw_matching_div
if spec.divs then
local divs = spec.divs
if type(divs) ~= "table" then
divs = {divs}
end
for _, div in ipairs(divs) do
if type(div) ~= "table" then
div = {type = div}
end
if plural_holonym_placetype == div.type then
saw_matching_div = true
break
end
end
end
if saw_matching_div then
insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(key, spec)))
return true
end
return false
end)
end
if insert_specific_variant_if_possible(matching_key, matching_spec) then
inserted_specific_variant_cat = true
elseif not matching_spec.no_container_cat then
for _, containers in ipairs(matching_container_trail) do
local saw_no_container_cat = false
for _, container in ipairs(containers) do
if insert_specific_variant_if_possible(container.key, container.spec) then
inserted_specific_variant_cat = true
break
end
saw_no_container_cat = saw_no_container_cat or container.spec.no_container_cat
end
if inserted_specific_variant_cat or saw_no_container_cat then
break
end
end
end
end
else
-- This happens when in an invocation like {{place|en|capital city|s/Haryana,Punjab}} for
-- [[Chandigarh]]. We fall back to older code that doesn't depend on the holonym index existing.
-- FIXME: This may not be necessary. In the example just given, when processing Haryana we add to
-- [[:Category:en:State capitals of India]], and nothing extra gets added when processing Punjab.
-- Possibly we can just skip this case entirely.
local group, key, spec, container_trail = export.find_matching_holonym_location(data)
if group and container_trail[1] and not spec.no_container_cat then
for _, container in ipairs(container_trail[1]) do
insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(container.key,
container.spec)))
inserted_specific_variant_cat = true
end
end
end
if not inserted_specific_variant_cat then
insert(retcats, capital_cat)
end
else
-- We didn't recognize the holonym placetype; just put in 'Capital cities'.
insert(retcats, "Ibu kota")
end
return retcats
end
--[=[
This is invoked specially for all placetypes (see the `*` placetype key at the bottom of `placetype_data`). This is used
in two ways:
# To add pages to generic holonym categories like [[:Category:en:Places in Merseyside, England]] (and
[[:Category:en:Places in England]]) for any pages that have `co/Merseyside` as their holonym.
# To categorize demonyms in bare placename categories like [[:Category:en:Merseyside, England]] if the demonym
description mentions `co/Merseyside` and doesn't mention a more specific placename that also has a category. (In this
case there are none, but we can have demonyms at multiple levels, e.g. in France for individual villages, departments,
administrative regions, and for the entire country, and for example we only want to categorize a demonym into
[[:Category:France]] if no more specific category applies.) Unlike when invoked from {{tl|place}}, a demonym
invocation only adds the most specific holonym category and not the category of any containing polity (hence if we
add [[:Category:en:Merseyside, England]] we won't also add [[:Category:England]]).
This code also handles cities; e.g. for the first use case above, it would be used to add a page that has `city/Boston`
as a holonym to [[:Category:en:Places in Boston]], along with [[:Category:en:Places in Massachusetts, USA]] and
[[:Category:en:Places in the United States]]. The city handler tries to deal with the possibility of multiple cities
having the same name. For example, the code in [[Module:place/locations]] knows about the city of [[Columbus]],
[[Ohio]], which has containing polities `Ohio` (a state) and `the United States` (a country). If either containing
polity is mentioned, the handler proceeds to return the key `Columbus` (along with `Ohio, USA` and `the United States`).
Otherwise, if any other state or country is mentioned, the handler returns nothing, and otherwise it assumes the
mentioned city is the one we're considering and returns `Columbus` etc. This works correctly if the place only mentions
Ohio and a holonym for a Columbus in a different country is encountered, because of the function
`augment_holonyms_with_container`, which adds the US as a holonym when Ohio is encountered.
The single parameter `data` is as in category handlers. The return value is a list of categories (without the preceding
language code).
]=]
local function generic_place_cat_handler(data)
local from_demonym = data.from_demonym
local retcats = {}
local function insert_retkey(key, spec)
if from_demonym then
insert(retcats, key)
else
insert(retcats, ("Tempat di %s"):format(export.get_prefixed_key(key, spec)))
end
end
local group, key, spec, container_trail = export.find_matching_holonym_location(data)
if group then
if not spec.no_generic_place_cat then
-- This applies to continents and continental regions.
insert_retkey(key, spec)
end
-- Categorize both in key, and in the larger location(s) that the key is part of, e.g. [[Hirakata]] goes in
-- both [[Category:Places in Osaka Prefecture, Japan]] and [[Category:Places in Japan]]. But not when
-- no_container_cat is set (e.g. for 'United Kingdom').
if not spec.no_container_cat then
for _, container_set in ipairs(container_trail) do
local stop_adding_containers = false
for _, container in ipairs(container_set) do
if not container.spec.no_generic_place_cat then
insert_retkey(container.key, container.spec)
end
if container.spec.no_container_cat then
stop_adding_containers = true
end
end
if stop_adding_containers then
break
end
end
end
return retcats
end
end
--[==[
Special category handler run for all placetypes that checks for specified division placetypes of known locations and
categorizes appropriately.
]==]
function export.political_division_cat_handler(data)
if data.from_demonym then
return
end
local group, key, spec, container_trail = export.find_matching_holonym_location(data)
if group then
local divlists = {}
if spec.divs then
insert(divlists, spec.divs)
end
if spec.addl_divs then
insert(divlists, spec.addl_divs)
end
for _, divlist in ipairs(divlists) do
if type(divlist) ~= "table" then
divlist = {divlist}
end
for _, div in ipairs(divlist) do
if type(div) == "string" then
div = {type = div}
end
local sgdiv = export.maybe_singularize_placetype(div.type) or div.type
local prep = div.prep or "di"
local cat_as = div.cat_as or div.type
if type(cat_as) ~= "table" then
cat_as = {cat_as}
end
if not export.placetype_data[sgdiv] then
internal_error("Placetype %s associated with known location key %s and data %s not found in " ..
"`placetype_data`", sgdiv, key, spec)
end
if sgdiv == data.entry_placetype then
local retcats = {}
for _, pt_cat in ipairs(cat_as) do
if type(pt_cat) == "string" then
pt_cat = {type = pt_cat}
end
local pt_prep = pt_cat.prep or prep
insert(retcats, ucfirst(pt_cat.type) .. " " .. pt_prep .. " " ..
export.get_prefixed_key(key, spec))
end
return retcats
end
end
end
end
end
--[==[
This is used to add pages to "bare" categories like [[:Category:en:Georgia, USA]] for `[[Georgia]]` and any
foreign-language terms that are translations of the state of Georgia. We look at the page title (or its overridden value
in {{para|pagename}}) as well as the glosses in {{para|t}}/{{para|t2}} etc., various extra-info values such as the
modern names in {{para|modern}}, and any values specified using a form-of directive. We need to pay attention to the
entry placetypes specified so we don't overcategorize; e.g. the US state of Georgia is `[[Джорджия]]` in Russian but the
country of Georgia is `[[Грузия]]`, and if we just looked for matching names, we'd get both Russian terms categorized
into both [[:Category:ru:Georgia, USA]] and [[:Category:ru:Georgia]]. We also need to check the containing holonyms to
make sure there isn't a mismatch (so we don't e.g. categorize Newark, Delaware in [[:Category:en:Newark]], which is
intended for Newark, New Jersey).
]==]
function export.get_bare_categories(args, overall_place_spec)
local bare_cats = {}
local place_descs = overall_place_spec.descs
local possible_placetypes_by_place_desc = {}
for i, place_desc in ipairs(place_descs) do
possible_placetypes_by_place_desc[i] = {}
for _, placetype in ipairs(place_desc.placetypes) do
if not export.placetype_is_ignorable(placetype) then
local equivs = export.get_placetype_equivs(placetype, {register_former_as_non_former = true})
for _, equiv in ipairs(equivs) do
insert(possible_placetypes_by_place_desc[i], equiv.placetype)
end
end
end
end
local function check_term(term)
-- Treat Wikipedia links like local ones.
term = term:gsub("%[%[w:", "[["):gsub("%[%[wikipedia:", "[[")
term = export.remove_links_and_html(term)
term = term:gsub("^the ", "")
for i, place_desc in ipairs(place_descs) do
-- Iterate over all matching locations in case there are multiple, as with Delhi defined as
-- {{place|en|megacity/and/union territory|c/India|containing the national capital [[New Delhi]]}}.
for group, key, spec, container_trail in export.iterate_matching_holonym_location {
holonym_placetype = possible_placetypes_by_place_desc[i],
holonym_placename = term,
place_desc = place_desc,
} do
insert(bare_cats, key)
end
end
end
-- FIXME: Should we only do the following if the language is English (requires that the lang is passed in)?
-- We should always do it if `pagename` is given (as it is with {{tcl}}) but maybe not otherwise unless 1=en. There
-- are cases like [[Ankara]] = English name for capital of Turkey, but also the name in various languages for the
-- capital of Ghana (= English [[Accra]]). But this should get caught by mismatching the containing country. The
-- advantage of checking when the language isn't English is we catch those places that fail to give an English
-- translation but where the translation happens to be the same as the other-language spelling. However, I don't
-- know how often this situation occurs.
check_term(args.pagename or mw.title.getCurrentTitle().subpageText)
for _, t in ipairs(args.t) do
check_term(t)
end
local function check_termobj_list(terms)
for _, term in ipairs(terms) do
if term.eq then
check_term(term.eq)
end
if term.alt or term.term then
check_term(term.alt or term.term)
end
end
end
for _, extra_info_terms in ipairs(overall_place_spec.extra_info) do
local arg = extra_info_terms.arg
if arg == "modern" or arg == "now" or arg == "full" or arg == "short" then
check_termobj_list(extra_info_terms.terms)
end
end
for _, directive in ipairs(overall_place_spec.directives) do
check_termobj_list(directive.terms)
end
return bare_cats
end
--[==[
This is used to augment the holonyms associated with a place description with the containing polities. For example,
given the following:
`# {{tl|place|en|subprefecture|pref/Hokkaido}}.`
We auto-add Japan as another holonym so that the term gets categorized into [[:Category:Subprefectures of Japan]].
To avoid over-categorizing we need to check to make sure no other countries are specified as holonyms.
]==]
function export.augment_holonyms_with_container(place_descs)
for _, place_desc in ipairs(place_descs) do
if place_desc.holonyms then
-- This ends up containing a copy of the original holonyms, with the augmented holonyms inserted in their
-- appropriate position. We don't just put them at the end because some holonyms have use the `:also`
-- modifier, which causes category processing to restart at that point after generating categories for a
-- preceding holonym, and we don't want the preceding holonym's augmented holonyms interfering with
-- categorization of a later holonym. We proceed from right to left, and each time we augment, we copy
-- the holonyms with the augmented holonym(s) inserted appropriately and replace the place description's
-- holonyms with the augmented ones before the next iteration. The reason for this is so that e.g.
-- {{place|neighborhood|city/Birmingham|co/West Midlands|cc/England}} doesn't throw an error during the
-- augmentation process due to 'Birmingham' referring to two known locations (in England and Alabama). If
-- we go left to right, we will throw an ambiguity error on `city/Birmingham` because code to exclude
-- Birmingham, Alabama needs `c/United Kingdom` present (to cause a mismatch with `c/United States`),
-- which isn't yet present as the augmentation code hasn't gotten to `cc/England` yet. For similar
-- reasons, we need to include the augmented holonyms in the holonyms considered in the next iteration
-- rather than modifying the place description once at athe end.
for i = #place_desc.holonyms, 1, -1 do
local holonym = place_desc.holonyms[i]
if holonym.placetype and not export.placetype_is_ignorable(holonym.placetype) then
local group, key, spec, container_trail = export.find_matching_holonym_location {
holonym_placetype = holonym.placetype,
holonym_placename = holonym.unlinked_placename,
holonym_index = i,
place_desc = place_desc,
}
if group and container_trail[1] and not spec.no_auto_augment_container then
local augmented_holonyms = {}
for j = 1, i do
insert(augmented_holonyms, place_desc.holonyms[j])
end
for _, containers in ipairs(container_trail) do
local any_no_auto_augment_container = false
for _, container in ipairs(containers) do
any_no_auto_augment_container = any_no_auto_augment_container or
container.spec.no_auto_augment_container
local containing_type = container.spec.placetype
if type(containing_type) == "table" then
-- If the containing type is a list, use the first element as the canonical variant.
containing_type = containing_type[1]
end
local full_container_placename, elliptical_container_placename =
m_locations.key_to_placename(container.group, container.key)
-- Don't side-effect holonyms while processing them.
local new_holonym = {
-- By the time we run, the display has already been generated so we don't need to
-- set display_placename.
placetype = containing_type,
-- placename_to_key() for the group should correctly handle both full and elliptical
-- placenames, but the full placename seems less likely to be ambiguous. FIXME: We
-- should just store the key directly and use it when available to avoid having to
-- convert key to placename and back to key.
unlinked_placename = full_container_placename,
-- Indicate that this is an augmented holonym, and was derived from the specified
-- holonym. In iterate_matching_holonym_location(), we ignore augmented holonyms
-- derived from holonyms that are different from the holonym we're searching for but
-- of the same placetype. This is to correctly handle a situation like
-- {{place|river|dept/Ardèche,Gard,Vaucluse,Bouches-du-Rhône|c/France}}. Here,
-- `Ardèche` is in `r/Auvergne-Rhône-Alpes`, while `Gard` is in `r/Occitania` and
-- the other two are in `r/Provence-Alpes-Côte d'Azur`. Augmenting proceeds from
-- right to left, so after it adds `r/Provence-Alpes-Côte d'Azur` to
-- `Bouches-du-Rhône`, Vaucluse gets augmented correctly but `Gard` fails to match
-- in find_matching_holonym_location() because of the mismatch between augmented
-- `r/Provence-Alpes-Côte d'Azur` and actual `r/Occitania`. Similarly, all later
-- calls to find_matching_holonym_location() fail to match `Gard` (and likewise
-- `Ardèche`) against any known location. To deal with this, we mark augmented
-- holoynms as being augmented due to a source holonym, and when processing a given
-- holonym, ignore augmented holonyms from other holonyms of the same placetype.
-- The restriction to the same placetype is so that `Birmingham` still gets
-- correctly disambiguated to Birmingham, England in the example given above near
-- the top of this function, using the augmented holonym `c/United Kingdom` added by
-- the specified `cc/England` (whose placetype `constituent country` differs from
-- the placetype `city` of Birmingham).
augmented_from_holonym = holonym,
}
insert(augmented_holonyms, new_holonym)
-- But it is safe to modify other parts of the place_desc.
export.key_holonym_into_place_desc(place_desc, new_holonym)
end
if any_no_auto_augment_container then
break
end
end
for j = i + 1, #place_desc.holonyms do
insert(augmented_holonyms, place_desc.holonyms[j])
end
place_desc.holonyms = augmented_holonyms
end
end
end
end
end
end
-- Cat handler for district, areas, neighborhoods and suburbs. Districts are tricky because they can either be political
-- divisions or city neighborhoods. Areas similarly can be political divisions (rarely; specifically, in Kuwait), city
-- neighborhoods or larger geographical areas/regions. We handle this as follows:
-- (1) `placetype_data` cat entries for specific countries or country divisions take precedence over cat_handlers, so if
-- the user says {{tl|place|district|s/Maharashtra|c/India}}, we won't even be called because there is an entry that
-- categorizes into [[:Category|Districts of Maharashtra, India]].
-- (2) If we're called, we check the holonym we're called on to see if it is a recognized city, e.g. if we're called
-- using {{tl|place|district|city/Mumbai|s/Maharashtra|c/India}}. If so, we categorize under e.g.
-- [[:Category:Neighbourhoods of Mumbai]]. (Choosing the spelling "neighbourhoods" because we're in India.)
-- (3) If we're called and the holonym is not a recognized city, we check if the placetype has has_neighborhoods set.
-- If so, it's "city-like" and we categorize under the first containing polity that we recognize. For example, if
-- we're called using {{tl|place|district|town/Northampton|co/Hampshire|s/Massachusetts|c/US}}, we should recognize
-- town as "city-like" and categorize under [[:Category:Neighborhoods in Massachusetts]]. (Note "di" not "bagi", and
-- note the spelling "neighborhoods" because we're in the US.)
-- (4) If the holonym is not city-like, we do nothing. If there's a city or city-like placetype farther up (e.g. we're
-- called as {{tl|place|district|ward/Foo|mun/Bar|...}}), we will handle the city-like entity according to (2) or
-- (3) when called on that holonym. Otherwise either the categorization in (1) takes place or there's no
-- categorization.
local function district_neighborhood_cat_handler(data)
local function get_plural_entry_placetype(location_spec, container_trail)
if data.entry_placetype == "suburb" then
return "Suburbs"
else
-- Check for `british_spelling` setting on the spec itself or any container.
local uses_british_spelling = location_spec.british_spelling
if uses_british_spelling == nil and container_trail then
for _, container_set in ipairs(container_trail) do
local must_outer_break = false
for _, container in ipairs(container_set) do
if container.spec.british_spelling ~= nil then
uses_british_spelling = container.spec.british_spelling
must_outer_break = true
break
end
end
if must_outer_break then
break
end
end
end
return uses_british_spelling and "Neighbourhoods" or "Neighborhoods"
end
end
-- First check the immediate holonym to see if it's a city or a city-like top-level entity (Hong Kong, Bonaire,
-- etc.)
local group, key, spec, container_trail = export.find_matching_holonym_location(data)
if group and not spec.is_former_place and spec.is_city then
return {get_plural_entry_placetype(spec, container_trail) .. " bagi " .. export.get_prefixed_key(key, spec)}
end
-- If the entry placetype is neighbo(u)rhood, assume it is a neighborhood even if there isn't a city-like
-- entity father up the chain. (E.g. due to a mistaken use of m/ instead of mun/ for municipality.)
local has_neighborhoods
local entry_placetype = data.entry_placetype
if entry_placetype == "neighborhood" or entry_placetype == "neighbourhood" or entry_placetype == "suburb" then
has_neighborhoods = true
else
-- Otherwise, make sure the current holonym is city-like.
has_neighborhoods = export.get_equiv_placetype_prop(data.holonym_placetype, function(pt)
return export.get_placetype_prop(pt, "has_neighborhoods")
end, {continue_on_nil_only = true})
end
if has_neighborhoods then
-- Loop up the holonyms, looking for city and city-like entities in case of e.g. [[Sepulveda]] written
-- {{place|en|neighborhood|valley/San Fernando Valley|city/Los Angeles|s/California|c/USA}}
-- but also look for a recognizable poldiv, and if so categorize as "Neighborhoods in POLDIV". We need
-- to start with the current holonym, which is especially important for neighborhoods and suburbs that
-- may have the first holonym be a recognizable province, etc. but can't hurt otherwise. (Previously
-- we skipped the first/current holonym.)
for other_holonym_index, other_holonym in export.get_holonyms_to_check(data.place_desc,
data.holonym_index) do
local other_holonym_data = {
holonym_placetype = other_holonym.placetype,
holonym_placename = other_holonym.unlinked_placename,
holonym_index = other_holonym_index,
place_desc = data.place_desc,
}
local group, key, spec, container_trail = export.find_matching_holonym_location(other_holonym_data)
if group and not spec.is_former_place then
return {get_plural_entry_placetype(spec, container_trail) .. (spec.is_city and " bagi " or " di ") ..
export.get_prefixed_key(key, spec)}
end
end
end
end
function export.check_already_seen_string(holonym_placename, already_seen_strings)
local canon_placename = ulower(m_links.remove_links(holonym_placename))
if type(already_seen_strings) ~= "table" then
already_seen_strings = {already_seen_strings}
end
for _, already_seen_string in ipairs(already_seen_strings) do
if canon_placename:find(already_seen_string) then
return true
end
end
return false
end
-- Prefix display handler that adds a prefix such as "Metropolitan Borough of " to the display
-- form of holonyms. We make sure the holonym doesn't contain the prefix or some variant already.
-- We do this by checking if any of the strings in ALREADY_SEEN_STRINGS, either a single string or
-- a list of strings, or the prefix if ALREADY_SEEN_STRINGS is omitted, are found in the holonym
-- placename, ignoring case and links. If the prefix isn't already present, we create a link that
-- uses the raw form as the link destination but the prefixed form as the display form, unless the
-- holonym already has a link in it, in which case we just add the prefix.
local function prefix_display_handler(prefix, holonym_placename, already_seen_strings)
if export.check_already_seen_string(holonym_placename, already_seen_strings or ulower(prefix)) then
return holonym_placename
end
if holonym_placename:find("%[%[") then
return prefix .. " " .. holonym_placename
end
return prefix .. " [[" .. holonym_placename .. "]]"
end
-- Suffix display handler that adds a suffix such as " parish" to the display form of holonyms.
-- Works identically to prefix_display_handler but for suffixes instead of prefixes.
local function suffix_display_handler(suffix, holonym_placename, already_seen_strings, include_suffix_in_link)
if export.check_already_seen_string(holonym_placename, already_seen_strings or ulower(suffix)) then
return holonym_placename
end
if holonym_placename:find("%[%[") then
return holonym_placename .. " " .. suffix
end
if include_suffix_in_link then
return "[[" .. holonym_placename .. " " .. suffix .. "]]"
else
return "[[" .. holonym_placename .. "]] " .. suffix
end
end
-- Display handler for boroughs. New York City boroughs are display as-is. Others are suffixed
-- with "borough".
local function borough_display_handler(holonym_placetype, holonym_placename)
local unlinked_placename = m_links.remove_links(holonym_placename)
if m_locations.new_york_boroughs[unlinked_placename] then
-- Hack: don't display "borough" after the names of NYC boroughs
return holonym_placename
end
return suffix_display_handler("borough", holonym_placename)
end
local function county_display_handler(holonym_placetype, holonym_placename)
local unlinked_placename = m_links.remove_links(holonym_placename)
-- Display handler for Irish counties. Irish counties are displayed as e.g. "County [[Cork]]".
if m_locations.ireland_counties["County " .. unlinked_placename .. ", Ireland"] or
m_locations.northern_ireland_counties["County " .. unlinked_placename .. ", Northern Ireland"] then
return prefix_display_handler("kaunti", holonym_placename)
end
-- Display handler for Taiwanese counties. Taiwanese counties are displayed as e.g. "[[Chiayi]] County".
if m_locations.taiwan_counties[unlinked_placename .. " County, Taiwan"] then
return suffix_display_handler("kaunti", holonym_placename)
end
-- Display handler for Romanian counties. Romanian counties are displayed as e.g. "[[Cluj]] County".
if m_locations.romania_counties[unlinked_placename .. " County, Romania"] then
return suffix_display_handler("kaunti", holonym_placename)
end
-- FIXME, we need the same for US counties but need to key off the country, not the specific county.
-- Others are displayed as-is.
return holonym_placename
end
-- Display handler for prefectures. Japanese prefectures are displayed as e.g. "[[Fukushima]] Prefecture".
-- Others are displayed as e.g. "[[Fthiotida]] prefecture".
local function prefecture_display_handler(holonym_placetype, holonym_placename)
local unlinked_placename = m_links.remove_links(holonym_placename)
local suffix = m_locations.japan_prefectures[unlinked_placename .. " Prefecture, Japan"] and "Prefecture" or "prefecture"
return suffix_display_handler(suffix, holonym_placename)
end
-- Display handler for provinces of Iran, Laos, North and South Korea, Thailand, Turkey and Vietnam. Recognized
-- provinces are displayed as e.g. "[[Gyeonggi]] Province" or "[[Antalya]] Province". Others are displayed as-is.
local function province_display_handler(holonym_placetype, holonym_placename)
local unlinked_placename = m_links.remove_links(holonym_placename)
if
m_locations.iran_provinces[unlinked_placename .. " Province, Iran"] or
m_locations.laos_provinces[unlinked_placename .. " Province, Laos"] or
m_locations.north_korea_provinces[unlinked_placename .. " Province, North Korea"] or
m_locations.south_korea_provinces[unlinked_placename .. " Province, South Korea"] or
m_locations.thailand_provinces[unlinked_placename .. " Province, Thailand"] or
m_locations.turkey_provinces[unlinked_placename .. " Province, Turkey"] or
m_locations.vietnam_provinces[unlinked_placename .. " Province, Vietnam"] then
return suffix_display_handler("Province", holonym_placename)
end
return holonym_placename
end
-- Display handler for Nigerian states. Nigerian states are display as "[[Kano]] State". Others are displayed as-is.
local function state_display_handler(holonym_placetype, holonym_placename)
local unlinked_placename = m_links.remove_links(holonym_placename)
if m_locations.nigeria_states["Negeri " .. unlinked_placename .. ", Nigeria"] then
return suffix_display_handler("Negeri", holonym_placename)
end
return holonym_placename
end
-- Display handler for voivodeships. Display as e.g. [[Subcarpathian Voivodeship]].
local function voivodeship_display_handler(holonym_placetype, holonym_placename)
return suffix_display_handler("Voivodeship", holonym_placename, nil, "include_suffix_in_link")
end
------------------------------------------------------------------------------------------
-- Placetype data --
------------------------------------------------------------------------------------------
--[==[ var:
Main placetype data structure. This specifies, for each canonicalized placetype, various properties. The keys are
placetypes (in the singular, except for category-only placetypes, which are plural and followed by `!`), and the value
is a table of properties. The `"*"` key is special and is used for adding "generic" categories of the form
`Places in ``location`` `; it runs for all entry placetypes. Keys in the form of plural placetypes followed by `!` are
used only in [[Module:category tree/topic cat/data/Places]] for specifying the properties of categories containing the
specified placetype, esp. bare categories like [[:Category:States and territories]] (rather than qualified categories
like [[:Category:States and territories of Australia]]).
Keys under the value table for a given placetype of are two types: ''property keys'' (which specify the value of
specific properties) and ''categorization keys'' (which tell how to categorize certain sorts of holonyms if the
placetype in question occurs as an entry placetype). Categorization keys are either the special value `default` or are
wildcard strings with a slash in them, such as `"country/*"`. Note that only wildcard strings are currently allowed
directly in the placetype data; everything else is handled through category handlers, either per-placetype or special
(such as `political_division_cat_handler`). The algorithm for how category keys and handlers are used to generate
categories is described at the top of [[Module:place]].
There are several recognized property keys, of various types:
1. The following link-related property keys are recognized:
* `link`: '''Required''' except in category-only placetypes ending in `!`. Describes how to link and display the
placetype in the formatted description when occurring as an entry placetype. Also used for formatting pluralized
placetypes (which may occur in entry placetypes, esp. new-format ones, such as `two <<islands>>`) and may occur in
categories). The possible values are:
*# `true`: Link to the same-named Wiktionary entry. This creates a raw link, e.g. `<nowiki>[[city]]</nowiki>`, which is
converted to an English-specific link by JavaScript postprocessing. If the placetype is plural, this creates a
two-part raw link e.g. `<nowiki>[[city|cities]]</nowiki>`.
*# `"w"`: Link to the same-named Wikipedia entry. This creates a two-part link, e.g.
`<nowiki>[[w:census town|census town]]</nowiki>`, or `<nowiki>[[w:census town|census towns]]</nowiki>` if the
placetype is given plural.
*# `"+..."`: Create a two-part link to the entry following the `+` sign. For example, if `cercle` specifies
`"+w:cercles of Mali"`, a two-part link `<nowiki>[[w:cercles of Mali|cercle]]</nowiki>` will be generated, or
`<nowiki>[[w:cercles of Mali|cercles]]</nowiki>` if plural `cercles` is specified.
*# `"separately"`: Link each word separately. For example, if `administrative territory` specifies `"separately"`, it
will be linked as `<nowiki>[[administrative]] [[territory]]</nowiki>`, or as
`<nowiki>[[administrative]] [[territory|territories]]</nowiki>` if plural `administrative territories` is given.
*# another string: Use that string directly. If the placetype is plural, `pluralize()` in [[Module:en-utilities]] is
called on the string, which will correctly pluralize most strings, including those with links in them. (If there
are multiple links, the display form of the last link is pluralized.)
*# `false`: This placetype is not allowed as an entry placetype. An error will be thrown if this placetype is given as
an entry placetype. This is specified for internal-use placetypes, especially placetypes used in conjunction with
the qualifiers `former`, `ancient`, `historical` and such.
* `plural_link`: If specified and the placetype is plural, use the value in place of generating a pluralized version of
the link spec in `link`. Most commonly, this is either a string with links in it (which is used directly) or the
value `false`, indicating that the placetype cannot occur plural. (This is used for example by `caplc`, which displays
as `<nowiki>[[capital]] and [[large]]st [[city]]</nowiki>`, where a plural version doesn't make sense.) Generally if
this is specified, `plural` also needs to be specified to give a special placetype plural; this situation occurs
especially with multiword placetypes where something other than the last word is pluralized. An example is
`town with bystatus`, whose plural is `towns with bystatus`, which needs to be explicitly given. This example uses
`link = <nowiki>"[[town]] with [[bystatus#Norwegian Bokmål|bystatus]]"</nowiki>` ({{m|nb|bystatus}}) is a Norwegian
Bokmål word, and template calls aren't currently permitted in link strings), along with
`plural_link = <nowiki>"[[town]]s with [[bystatus#Norwegian Bokmål|bystatus]]"</nowiki>`.
* `category_link`: Spec indicating how to display the placetype when occurring in category descriptions. Defaults to
the value of `link`, and in turn is overridden by more specific `category_link_*` keys; see below. Category-only
placetypes (which are plural and end in `!`) usually use `category_link` in preference to `link`. The value of
`category_link` can be any of the types of specs given above, but most commonly is a plural string with links in it,
spelling out the description; in this case it is used directly. When both `category_link` and `link` are given, the
value in `category_link` is typically longer and more descriptive. For example, `polity` uses `link = true`, which
just generates a link `<nowiki>[[polity]]</nowiki>` or plural `<nowiki>[[polity|polities]]</nowiki>`, but specifies a
separate `category_link = <nowiki>"[[independent]] or [[semi-]][[independent]] [[polity|polities]]"</nowiki>`, which
clarifies in the category description what a polity is.
* `category_link_top_level`: Spec indicating how to display top-level (bare/unqualified) categories, i.e. categories
where the placetype is not followed by `in ``location`` ` or `of ``location`` `. If given, this overrides
`category_link` for this type of category.
* `category_link_before_noncity`: Spec indicating how to display qualified categories of the form
` ``placetypes`` in/of ``location`` ` where ``location`` does not refer to a city. If given, this overrides
`category_link` for this type of category.
* `category_link_before_city`: Spec indicating how to display qualified categories of the form
` ``placetypes`` in/of ``location`` ` where ``location`` refer to a city. If given, this overrides `category_link` for
this type of category. An example where this is given is `neighborhood`, which uses the following specs:<ol>
<li>`link = true`</li>
<li>`category_link = <nowiki>"[[neighborhood]]s, [[district]]s and other subportions of [[city|cities]]"</nowiki>`</li>
<li>`category_link_before_city = <nowiki>"[[neighborhood]]s, [[district]]s and other subportions"</nowiki>`</li>
</ol> This has the effect of making the entry placetype `neighborhood` display as just
`<nowiki>[[neighborhood]]</nowiki>`, while e.g. a category like `Neighborhoods of Chicago` displays as
`<nowiki>[[neighborhood]]s, [[district]]s and other subportions of [[Chicago]], ...</nowiki>` and a category like
`Neighborhoods in Illinois, USA` displays as
`<nowiki>[[neighborhood]]s, [[district]]s and other subportions of [[city|cities]] in [[Illinois]], ...</nowiki>`.
* `disallow_in_entries`: If specified, this placetype cannot occur as an entry placetype, and the specified value
(a message indicating what to use instead) is displayed in the error message.
* `disallow_in_holonyms`: If specified, this placetype cannot occur as a holonym placetype, and the specified value
(a message indicating what to use instead) is displayed in the error message.
2. There is currently one fallback-related property key recognized:
* `fallback`: If specified, its value is a placetype which will be used for categorization purposes if no categories
get added using the placetype itself. As an example, `branch` sets a fallback of `river` but also sets
`preposition = "bagi"`, meaning that {{tl|place|en|branch|riv/Mississippi}} displays as `a branch of the Mississippi`
(whereas `river` itself uses the preposition `in`), but otherwise categorizes the same as `river`. A more complex
example is `area`, which sets a fallback of `geographic and cultural area` and also sets a category handler that
checks for cities or city-like entities (e.g. boroughs) occurring as holonyms and categorizes the toponym under
[[:Category:Neighborhoods of CITY]] (for recognized cities) or otherwise [[:Category:Neighborhoods of POLDIV]] (for
the nearest containing recognized location). In addition, `area` is set as a political division of Kuwait, meaning if
`c/Kuwait` occurs as holonym, the toponym is categorized under [[:Category:Areas of Kuwait]]. If none of these
categories trigger, the fallback of `geographic and cultural area` will take effect, and the toponym will be
categorized as e.g. [[:Category:Geographic and cultural areas of England]].
3. There is currently one property to control irregular plurals of placetypes:
* `plural`: If specified, its value is the plural of the placetype. Otherwise, the default pluralization algorithm in
[[Module:en-utilities]] applies (which correctly pluralizes most words, including those ending in `-y`, `-ch`, `-sh`,
`-x`, etc.). The value of `plural` is also used when converting a pluralized placetype into its singular equivalent;
for example, since the placetype `kibbutz` has `plural = "kibbutzim"`, the placetype `kibbutzim` will be recognized
as a plural and singularized to `kibbutz`. For this reason, it's occasionally necessary to specify a `plural` value
even when the default pluralization algorithm works correctly, if the default singularization algorithm won't
correctly reverse the pluralization (as with `pass` and other terms ending in `-ss`).
4. The following property keys relate to generating categories for entry placetypes and specifying the parents of those
categories:
* `class`: The general class of placetype. This is used for various purposes: (a) to categorize placetypes preceded by
a qualifier such as `former`, `ancient`, `medieval` or `historical` (note that these placetypes are not all treated
alike); (b) to determine the parent category of bare placetype categories (e.g. [[:Category:Villages]] for placetype
`village`); (c) to determine whether to add a parent category `political divisions of specific countries` to
qualified placetype categories (e.g. [[:Category:Villages in Mali]]). The possible values are:
*# `polity`: a more-or-less sovereign/independent polity, such as a country, kingdom or empire.
*# `subpolity`: a non-sovereign division of a polity, above the level of an individual settlement.
*# `settlement`: a city or smaller equivalent, such as a village. This also includes administrative divisions of a
settlement, such as wards and barangays.
*# `non-admin settlement`: similar to a settlement but without administrative or political significance, such as an
unincorporated community, farm or neighborhood.
*# `capital`: a settlement that is a capital. A former capital is generally still in existence, just not the capital
any more.
*# `natural feature`: any non-man-made feature, such as a lake, mountain, island, ocean, etc.
*# `man-made structure`: a man-made feature below the level of a neighborhood, such as a house, airport, university,
metro station, park or the like.
*# `geographic region`: a geographic or cultural region or area that has no administrative significance. These may vary
greatly in size but typically have some sort of cultural significance (possibly historical). The `former`, `ancient`,
etc. qualifier has no effect on the category of these placetypes.
*# `generic place`: a place that isn't further qualified into any specific subtype.
* `former_type`: The class of placetype used for categorizing placetypes preceded by a qualifier such as `former`,
`ancient`, `medieval` or `historical`. The possible values are the same as for `class` but with the addition of
`dependent territory` (for colonies, protectorates and the like) and `!` (ignore the historical/former/ancient/etc.
qualifier; used e.g. with `fictional location` and `mythological location`). If not specified, the value of `class`
is used. When a qualifier such as `former`, `ancient`, `medieval` or `historical` is encountered (specifically, those
in `former_qualifiers`), it is mapped using `former_qualifiers` to the appropriate internal qualifier or qualifiers
(one or both of `ANCIENT` and/or `FORMER`, which are written in all-caps to distinguish them from user-specified
qualifiers), which is prepended to the value of `former_type` or `class` to form a placetype whose properties are
looked up to determine how to categorize the toponym in question. For example, if `medieval village` is given, we map
`medieval` to `ANCIENT` and `FORMER`, and `village` to its `class` of `settlement`, and enter the placetypes
`ANCIENT settlement` and `FORMER settlement` (in that order) into the list of equivalent placetypes returned by
`get_placetype_equivs`. In this case, there is an entry in `placetype_data` for `ANCIENT settlement`, so its default
category spec `Ancient settlements` is used as the category. If on the other hand `medieval kingdom` is given, where
`kingdom` has a `class` value `polity`, we first look up `ANCIENT polity`, see there is no entry in `placetype_data`
for it, and then look up `FORMER polity`, which exists and has a default category spec `Former polities`, which is
used as the category. Note that if the placetype following the "former" qualifier is recognized in `placetype_data`
but has no `former_type` or `class` and no fallback with a `former_type` or `class` specified, it is an internal
error; but if the placetype isn't recognized (e.g. something like `former greenhouse` is specified and we don't have
an entry for `greenhouse`), we just track the occurrence and end up not categorizing.
* `bare_category_parent`: This specifies the first parent category of a bare placetype category named according to the
placetype in question (e.g. [[:Category:Atolls]] for placetype `atoll`, or [[:Category:Named buildings]] for
placetype `named buildings!`). If not specified, the first parent category is determined by the value of `class`,
using the mapping `class_to_bare_category_parent` in [[Module:category tree/topic cat/data/Places]].
* `addl_bare_category_parents`: Extra parent categories to add a bare placetype category to (see `bare_category_parent`
just above).
* `bare_category_breadcrumb`: Breadcrumb for bare placetype categories. Also used as the sort key of
`bare_category_parent` if it is a string.
* `inherently_former`: If specified and the given placetype is used as an entry placetype, act as if `former` or
`ancient` (depending on the value of `inherently_former`) were prefixed to the placetype. This is for placetypes that
always refer to no-longer-existing entities, such as `satrapy` and `treaty port`. The value of `inherently_former` is
a list of internal qualifiers (one or more of `ANCIENT` and/or `FORMER`), just as for `former_qualifiers`, and the
implementation is the same.
* `cat_handler`: Handler used to generate the categories to add a given toponym to, if its entry placetype is the
placetype in question. Generally the `cat_handler` function checks the holonyms specified in order to determine which
category or categories to generate. For example, `district_neighborhood_cat_handler` handles placetypes `district`,
`neighborhood`, `subdivision`, `suburb` and the like, and either adds the toponym to a category like
`Neighborhoods of ``city`` ` (if a recognized city is given as a holonym), or otherwise a category like
`Neighborhoods in ``location`` ` (for the first recognized non-city location given as a holonym, if an unrecognized
city or city-like entity is given before the recognized non-city). The algorithm that runs the category handlers
iterates over holonyms from left to right, running the `cat_handler` function on each holonym in turn until one or
more categories are returned; see below for more specifics. (Note that countries for which e.g. a `district` is a
political division do not get the corresponding category added by the `district_neighborhood_cat_handler` function but
by `political_division_cat_handler`.) `cat_handler` functions are called with one argument, `data`, describing the
resolved entry placetype (i.e. after resolving placetype aliases and fallbacks) and the holonym being processed. The
return value should be a list of category specs (categories minus the langcode prefix, with `+++` standing for the
holonym key, or the value `true`, which stands for ` ``Placetypes`` in/of ``Holonym`` `, i.e. the pluralized placetype
with the appropriate preposition as specified in `placetype_data`). `data` contains the following fields:
** `entry_placetype`: the resolved entry placetype for the entry placetype being processed (i.e. it will always have an
entry in `placetype_data` but may not be the original placetype given by the user);
** `holonym_placetype` and `holonym_placename`: the holonym placetype and placename being processed;
** `holonym_index`: the index of the holonym being processed, or {nil} if we're handling an overriding holonym (FIXME:
we will change the overriding holonym algorithm so there will be an index even when processing overriding holonyms);
** `place_desc`: a full description of the {{tl|place}} call, as specified at the top of [[Module:place]];
** `from_demonym`: If set, we are called from [[Module:demonym]], triggered by {{tl|demonym-adj}} or
{{tl|demonym-noun}}, instead of being triggered by {{tl|place}}.
* `has_neighborhoods`: If `true`, the specified placetype is city-like. This is used in the
`district_neighborhood_cat_handler` to determine whether to add a category such as `Neighborhoods in ``location`` `;
see the section just above on `cat_handler`.
5. The following preposition-related property keys are recognized:
* `preposition`: The preposition used after this placetype when it occurs as an entry placetype. Defaults to `"di"`.
* `generic_before_non_cities`: If specified, the appropriate category description handler in
[[Module:category tree/topic cat/data/Places]] will recognize categories of the form
` ``Placetype`` in/of ``location`` ` for the specified placetype and preposition, if ``location`` is a non-city. This
is used to generate descriptions for categories added by category handlers and by explicit category specs in the
placetype data. All placetypes that specify `generic_before_non_cities` or `generic_before_cities` *MUST* also specify
a value for `class` so that the category tree code can determine whether it's a political or non-political division.
* `generic_before_cities`: Like `generic_before_non_cities` but for locations referring to cities.
6. The following property keys control the auto-addition of affixes when formatting holonyms of a particular placetype:
* `affix_type`: If specified, add the placetype as an affix before or after holonyms of this placetype. Possible values
are:
*# `"pref"` (the holonym will display as `(the) placetype of Holonym`, where `the` appears when the holonym directly
follows an entry placetype);
*# `"Pref"` (same as `"pref"` but the placetype is capitalized; each word is capitalized if there are multiple);
*# `"suf"` (the holonym will display as `Holonym placetype`);
*# `"Suf"` (the holonym will display as `Holonym Placetype`, i.e. same as `"suf"` but the placetype is capitalized).
* `suffix`: String to use in place of the placetype itself when the placetype is displayed as a suffix after a holonym.
Note that `suffix` can be used independently of `affix_type` because the user can also request a suffix explicitly
using a syntax like `adr:suf/Occitania`, which will display as `Occitania region` because the placetype
`administrative region` specifies `suffix = "wilayah"`.
* `prefix`: Like `suffix` but for use when the placetype is displayed as a prefix before the holonym.
* `affix`: Like `suffix` and `prefix` but for use when the placetype is displayed as an affix either before or after the
holonym. If both `suffix` or `prefix` and `affix` are given for a single placetype, `suffix` or `prefix` take
precedence.
* `no_affix_strings`: String or list of strings that, if they occur in the holonym, suppress the addition of any affix
requested using `affix_type`. Defaults to the placetype itself. For example, `autonomous okrug` specifies
`affix_type = "Suf"` so that `aokr/Nenets` displays as `Nenets Autonomous Okrug`, but also specifies
`no_affix_strings = "okrug"` so that `aokr/Nenets Okrug` or `aokr/Nenets Autonomous Okrug` displays as specified,
without a redundant `Autonomous Okrug` added. Matching is case-insensitive but whole-word.
* `display_handler`: A function of two arguments, `holonym_placetype` and `holonym_placename` (specifying a holonym).
Its return value is a string specifying the display form of the holonym.
7. The following property keys control the indefinite and definite articles used before entry placetypes and/or holonyms
of the specified placetype.
* `entry_placetype_use_the`: Use `"the"` before this placetype when it occurs as an entry placetype.
* `entry_placetype_indefinite_article`: Indefinite article used before this placetype when it occurs as an entry
placetype (usually `"a"`, specifically for placetypes beginning with u- that don't take the indefinite article
`"an"`). Defaults to the appropriate indefinite article (`"a"` or `"an"` depending on whether the placetype begins
with a vowel). Overridden by `entry_placetype_use_the`, and unlike for most properties, does not apply to equivalent
placetypes (i.e. fallbacks or those formed by removing a qualifier from the beginning); only to the exact placetype
specified.
* `holonym_use_the`: Use `"the"` before holonyms of this placetype.
'''NOTE:'''
# The `link` property must be specified on all placetypes, except those ending in `!` (category-only placetypes), which
must have either `link` or `category_link` specified.
# Either the `class` or `former_type` property must be specified on all placetypes not ending in `!` that do not have a
fallback (if a placetype has a fallback and omits the `class` and `former_type` properties, they are taken from the
fallback). An internal error will result if a placetype has no `class` or `former_type` property derivable either
directly or through a fallback, if an attempt is made to categorize a former/ancient/historical/etc. entity of this
placetype.
# It is possible to have multiple levels of fallback (e.g. `frazione` falls back to `hamlet`, which falls back
to `village`). Fallback loops will cause an internal error. All placetypes specified as fallbacks must exist in
`placetype_data` or an internal error occurs.
]==]
export.placetype_data = {
--[=[
If you need to sort the following, do this (using Vim):
1. Make sure all full-line comments are within the { ... } table, or are moved after and on the same line as single-line
entries.
2. Make sure the table uses tabs everywhere for indent, and not spaces.
3. Mark the top of the table with `ma`, go to the bottom and execute the following two lines in sequence:
:'a,.s/\n/\\n/g
:s/\\n\(\t\[\)/\r\1/g
The first command converts every newline to a literal `\n` sequence, so the whole thing becomes a single line, while
the second command restores the newlines before the beginning of each entry. The effect is to convert all entries to
a single line while not losing any information. (Potentially a negative lookahead could be used to do it all in one
command.)
4. Execute the following to sort:
:'a,.!perl -pe 's/^(\t\[")(.*?)(".*)$/$2 @@@ $1$2$3/' | sort -f | perl -pe 's/.*? @@@ //'
Note that a simple `sort -f` (where `-f` means case-insensitive) would almost work, but it would sort "hill station"
before "hill" and "county borough" before "kaunti" because the space after e.g. "hill station" sorts before the
quotation mark after e.g. "hill". The above command deals with this by extracting the key, prepending it followed by
` @@@ `, sorting, and then removing key (the classic decorate-sort-undecorate pattern).
5. Put the table back to multi-line format by marking the top of the table with `ma`, going to the bottom and executing
:'a,.s/\\n/\r/g
Note that for some reason, in order to get a match a newline in the left side of a replacement, you must use \n, but
to insert a newline in the right sode of a replacement you must use \r.
]=]
["*"] = {
link = false,
cat_handler = generic_place_cat_handler,
},
["administrative atoll"] = {
-- Maldives
link = "+w:administrative divisions of the Maldives",
preposition = "bagi",
class = "subtatanegara",
},
["administrative capital"] = {
link = "w",
fallback = "ibu kota",
},
["administrative center"] = {
link = "w",
fallback = "non-city capital",
},
["administrative centre"] = {
link = "w",
fallback = "administrative center",
},
["administrative county"] = {
link = "w",
fallback = "kaunti",
},
["administrative district"] = {
link = "w",
fallback = "daerah",
},
["administrative headquarters"] = {
link = "separately",
fallback = "administrative centre",
},
["administrative region"] = {
link = true,
preposition = "bagi",
suffix = "wilayah", -- but prefix is still "administrative region (of)"
fallback = "wilayah",
class = "subtatanegara",
},
["administrative seat"] = {
link = "w",
fallback = "administrative centre",
},
["administrative territory"] = {
link = "separately",
preposition = "bagi",
suffix = "wilayah", -- but prefix is still "administrative territory (of)"
fallback = "wilayah",
class = "subtatanegara",
},
["administrative unit"] = {
-- Grrr, it's difficult to generalize about "administrative units". In Albania, "administrative unit" is an
-- official term for a city-level division of municipalities; Wikipedia renders it using the more practical term
-- "commune". In Pakistan, "administrative unit" is a collective term used to refer to all the different types
-- of first-level divisions (four provinces, one federal territory, and two "disputed territories", i.e. Azad
-- Kashmir and Gilgit-Balistan, that are variously described). For this reason, we set no fallback, but we need
-- to include this so that it can be used as a placetype for Albania, categorizing as communes.
link = "w",
class = "subtatanegara",
},
["administrative village"] = {
link = "w",
preposition = "bagi",
has_neighborhoods = true,
class = "petempatan",
},
["aimag"] = {
-- used in Mongolia, Russia and China (Inner Mongolia); in Mongolia, equivalent to a province;
-- in China, equivalent to a prefecture (below a province); in Russia, equivalent to a municipal district.
link = "w",
fallback = "prefecture",
},
["airport"] = {
link = true,
class = "man-made structure",
default = {true},
},
["alliance"] = {
link = true,
fallback = "persekutuan",
},
["archipelago"] = {
link = true,
fallback = "pulau",
},
["area"] = {
link = true,
preposition = "bagi",
fallback = "kawasan geografi dan budaya",
-- Areas can either be administrative divisions (specifically of Kuwait) or geographic areas. Assume the former
-- when categorizing 'Areas' but the latter when handling e.g. 'historical area'.
class = "subtatanegara",
former_type = "kawasan geografi",
cat_handler = district_neighborhood_cat_handler,
},
["arm"] = {
link = true,
preposition = "bagi",
class = "sifat semula jadi",
default = {"Laut"},
},
["arrondissement"] = {
link = true,
preposition = "bagi",
-- FIXME!!! Grrrrr!!! In some countries, arrondissements are divisions of cities; in others, they are divisions
-- of departments or provinces. Need to conditionalize on the country for both of the following.
class = "subtatanegara",
has_neighborhoods = true,
},
["associated province"] = {
link = "separately",
fallback = "province",
},
["atoll"] = {
-- FIXME! Atolls are administrative divisions of the Maldives but natural features elsewhere. Need to
-- conditionalize `class` on the country. See also `administrative atoll`.
link = true,
class = "sifat semula jadi",
bare_category_parent = "pulau",
default = {true},
},
["autonomous city"] = {
link = "w",
preposition = "bagi",
fallback = "bandar",
has_neighborhoods = true,
},
["autonomous community"] = {
-- Spain; refers to regional entities, not village-like entities, as might be expected from "community"
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["autonomous island"] = {
-- Comoros; seems like an administrative atoll of the Maldives.
link = "+w:autonomous islands of Comoros",
preposition = "bagi",
class = "subtatanegara",
},
["autonomous oblast"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
no_affix_strings = "oblast",
class = "subtatanegara",
},
["autonomous okrug"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
no_affix_strings = "okrug",
class = "subtatanegara",
},
["autonomous prefecture"] = {
link = true,
fallback = "prefecture",
},
["autonomous province"] = {
link = "w",
fallback = "province",
},
["autonomous region"] = {
link = "w",
preposition = "bagi",
fallback = "administrative region",
-- "administrative region" sets an affix of "wilayah" but we want to display as "Tibet Autonomous Region"
-- if the user writes 'ar:Suf/Tibet'.
affix = "autonomous region",
},
["autonomous republic"] = {
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["autonomous territorial unit"] = {
-- Moldova; only two of them, one for Gagauzia and one for Transnistria.
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["autonomous territory"] = {
link = "w",
fallback = "dependent territory",
},
["bailiwick"] = {
-- Jersey, etc.
link = true,
fallback = "tatanegara",
},
["barangay"] = {
-- Philippines
link = true,
class = "petempatan",
-- Barangays are formal administrative divisions of a city rather than informal neighborhoods, but can use
-- some of the properties of a neighborhood.
fallback = "neighborhood",
},
["barrio"] = {
-- Spanish-speaking countries; Philippines
link = true,
-- FIXME: Not completely correct, in some countries barrios are formal administrative divisions of a city.
-- `class` will need to conditionalize on the country to be completely correct.
fallback = "neighborhood",
},
["basin"] = {
link = true,
fallback = "tasik",
},
["bay"] = {
link = true,
preposition = "bagi",
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["beach"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"air"},
default = {true},
},
["beach resort"] = {
link = "w",
fallback = "resort town",
},
["bishopric"] = {
link = true,
fallback = "tatanegara",
},
["badan air!"] = {
-- FIXME: This is (maybe?) a type category not a name category. There should be an option for this. We need to
-- straighten out the type vs. name vs. related-to issue.
category_link = "[[body of water|bodies of water]]",
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi", "ekosistem", "air"},
},
["borough"] = {
link = true,
preposition = "bagi",
display_handler = borough_display_handler,
has_neighborhoods = true,
-- "former borough" could be a former settlement or a former part of a city but seems more likely to
-- be a former subpolity, particularly in England. FIXME, we really need a handler to take care of this
-- properly.
class = "subtatanegara",
-- Grr, some boroughs are city-like but some (e.g. in Britain) may be larger.
},
["borough seat"] = {
link = "separately",
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
},
["branch"] = {
link = true,
preposition = "bagi",
fallback = "river",
},
["bridge"] = {
link = true,
class = "man-made structure",
default = {"Named bridges"},
},
["building"] = {
link = true,
class = "man-made structure",
default = {"Named buildings"},
},
["built-up area"] = {
link = "w",
fallback = "area",
},
["burgh"] = {
link = true,
fallback = "borough",
},
["business park"] = {
link = true,
fallback = "park",
},
["caliphate"] = {
link = true,
fallback = "tatanegara",
},
["canton"] = {
link = true,
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["cape"] = {
link = true,
fallback = "headland",
},
["capital"] = {
link = true,
fallback = "ibu kota",
},
["ibu kota"] = {
plural = "ibu kota",
link = true,
category_link = "[[ibu kota]]: kawasan pusat pentadbiran rasmi negara atau pembahagiannya",
entry_placetype_use_the = true,
preposition = "di",
has_neighborhoods = true,
class = "capital",
bare_category_parent = "bandar",
cat_handler = capital_city_cat_handler,
default = {true},
-- The following is necessary so that e.g. [[Melbourne]] defined as {{place|en|capital city|s/Victoria|c/Australia}}
-- gets categorized in the bare category [[Category:en:Melbourne]]; otherwise placetype 'capital city' wouldn't
-- match against the placetype 'city' of Melbourne.
fallback = "bandar",
},
["caplc"] = {
link = "[[capital]] and [[large]]st [[city]]",
plural_link = false,
fallback = "ibu kota",
},
["captaincy"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
inherently_former = {"FORMER"},
},
["caravan city"] = {
link = "w",
fallback = "bandar",
class = "petempatan",
inherently_former = {"ANCIENT", "FORMER"},
},
["castle"] = {
link = true,
fallback = "building",
},
["cathedral city"] = {
link = true,
fallback = "bandar",
},
["cattle station"] = {
-- Australia
link = true,
fallback = "farm",
},
["census area"] = {
link = true,
affix_type = "Suf",
has_neighborhoods = true,
class = "non-admin settlement",
},
["census-designated place"] = {
-- United States
link = true,
class = "non-admin settlement",
},
["census division"] = {
-- Canada
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["census town"] = {
link = "w",
fallback = "pekan",
},
["central business district"] = {
link = true,
fallback = "neighborhood",
},
["cercle"] = {
-- Mali
link = "+w:cercles of Mali",
preposition = "bagi",
class = "subtatanegara",
},
["ceremonial county"] = {
link = true,
fallback = "kaunti",
},
["chain of islands"] = {
link = "[[chain]] of [[island]]s",
plural = "chains of islands",
plural_link = "[[chain]]s of [[island]]s",
fallback = "pulau",
},
["channel"] = {
link = true,
fallback = "selat",
},
["charter community"] = {
-- Northwest Territories, Canada
link = "w",
fallback = "kampung",
},
["chiwog"] = {
-- Bhutan
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["bandar"] = {
link = true,
plural = "bandar",
generic_before_non_cities = "di",
has_neighborhoods = true,
class = "petempatan",
cat_handler = city_type_cat_handler,
default = {true},
},
["negara kota"] = {
plural = "negara kota",
link = true,
category_link = "[[negara mikro]] [[daulat]] terdiri daripada sebuah [[bandar]] tunggal dengan [[w:wilayah tanggungan|wilayah tanggungan]]",
has_neighborhoods = true,
class = "petempatan",
["benua/*"] = {"Negara kota", "Bandar di +++", "Negara di +++", "Ibu negara"},
default = {"Negara kota", "Bandar", "Negara", "Ibu negara"},
},
["civil parish"] = {
-- Mostly England; similar to municipalities
link = true,
preposition = "bagi",
affix_type = "suf",
has_neighborhoods = true,
class = "subtatanegara",
},
["claimed political division"] = {
link = "[[claim]]ed [[political]] [[division]]",
class = "subtatanegara",
default = {true},
},
["co-capital"] = {
link = "[[co-]][[capital]]",
fallback = "ibu kota",
},
["coal city"] = {
link = "+w:coal town",
fallback = "bandar",
},
["coal town"] = {
link = "w",
fallback = "pekan",
},
["collectivity"] = {
link = "w",
preposition = "bagi",
-- No default; these are weird one-off governmental divisions in France (esp. for overseas collectivities)
class = "subtatanegara",
},
["colony"] = {
link = true,
fallback = "dependent territory",
},
["comarca"] = {
-- per Wikipedia: traditional region or local administrative division found in Portugal, Spain, and some of
-- their former colonies, like Brazil, Nicaragua, and Panama. In the Valencian Community, for example, it
-- sits between municipalities and provinces, something like a county or district.
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["commandery"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
inherently_former = {"ANCIENT", "FORMER"},
},
["commonwealth"] = {
link = true,
preposition = "bagi",
-- No default; applies specifically to Puerto Rico
class = "subtatanegara",
},
["commune"] = {
link = true,
fallback = "municipality",
},
["community"] = {
link = true,
category_link = "[[community|communities]] of all sizes",
fallback = "kampung",
},
["community development block"] = {
-- in India; appears to be similar to a rural municipality; groups several villages, unclear if there will be
-- neighborhoods so I'm not setting `has_neighborhoods` for now
link = "w",
affix_type = "suf",
no_affix_strings = "block",
class = "subtatanegara",
},
["comune"] = {
-- Italy, Switzerland
link = true,
fallback = "municipality",
},
["condominium"] = {
link = true,
fallback = "tatanegara",
},
["confederacy"] = {
link = true,
fallback = "persekutuan",
},
["persekutuan"] = {
plural = "persekutuan",
link = true,
fallback = "tatanegara",
},
["constituency"] = {
-- currently we have them as political divisions of Namibia but many countries have them
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["negara bahagian"] = {
plural = "negara bahagian",
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["constituent part"] = {
link = "separately",
preposition = "bagi",
class = "subtatanegara",
},
["constituent republic"] = {
-- Of Russia, Yugoslavia, etc.
link = "separately",
preposition = "bagi",
class = "subtatanegara",
},
["counties and county-level cities!"] = {
-- This is used when grouping counties and county-level cities under prefecture-level cities in China.
category_link = "[[county|counties]] and [[county-level city|county-level cities]]",
class = "subtatanegara",
},
["benua"] = {
plural = "benua",
link = true,
category_link = false, -- can't occur as a bare category
class = "sifat semula jadi",
default = {"Benua dan kawasan benua"},
},
["kawasan benua"] = {
plural = "kawasan benua",
link = "separately",
category_link = false, -- can't occur as a bare category
class = "kawasan geografi",
fallback = "benua",
},
["benua dan kawasan benua!"] = {
category_link = "[[continent]]s and [[continent]]-[[level]] [[region]]s (e.g. [[Polynesia]])",
class = "kawasan geografi",
},
["council area"] = {
link = true,
-- in Scotland; similar to a county
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["negara"] = {
plural = "negara",
link = true,
class = "tatanegara",
["benua/*"] = {true, "Countries"},
default = {true},
},
["country-like entities!"] = {
category_link = "[[polity|polities]] not normally considered [[country|countries]] but treated similarly for categorization purposes; typically, [[unrecognized]] [[de-facto]] countries or [[w:dependent territory|dependent territories]]",
class = "tatanegara",
},
["kaunti"] = {
plural = "kaunti",
link = true,
preposition = "bagi",
display_handler = county_display_handler,
class = "subtatanegara",
},
["county borough"] = {
link = true,
-- in Wales; similar to a county
preposition = "bagi",
affix_type = "suf",
fallback = "borough",
class = "subtatanegara",
},
["county seat"] = {
link = "separately",
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
},
["county town"] = {
link = true,
entry_placetype_use_the = true,
preposition = "bagi",
fallback = "pekan",
has_neighborhoods = true,
class = "capital",
},
["county-administered city"] = {
-- In Taiwan, per Wikipedia similar to a Taiwanese township or district, which is a small city.
-- NOT anything like a "county-level city" in PR China, which is a county masquerading as a city.
link = "w",
fallback = "bandar",
has_neighborhoods = true,
class = "petempatan",
},
["county-controlled city"] = {
-- Taiwan
link = "w",
fallback = "county-administered city",
},
["county-level city"] = {
-- PR China
link = "w",
fallback = "prefecture-level city",
},
["crater lake"] = {
link = true,
fallback = "tasik",
},
["creek"] = {
link = true,
fallback = "stream",
},
["Crown colony"] = {
link = "+crown colony",
fallback = "crown colony",
},
["crown colony"] = {
link = true,
fallback = "colony",
},
["Crown dependency"] = {
link = true,
fallback = "dependent territory",
},
["crown dependency"] = {
link = true,
fallback = "dependent territory",
},
["cultural area"] = {
link = "w",
fallback = "kawasan geografi dan budaya",
},
["cultural region"] = {
link = "w",
fallback = "kawasan geografi dan budaya",
},
["delegation"] = {
-- Tunisia
link = "+w:delegations of Tunisia",
preposition = "bagi",
class = "subtatanegara",
},
["department"] = {
link = true,
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["departmental capital"] = {
link = "separately",
fallback = "ibu kota",
},
["dependency"] = {
link = true,
fallback = "dependent territory",
},
["dependent territory"] = {
link = "w",
preposition = "bagi",
class = "subtatanegara",
former_type = "dependent territory",
bare_category_parent = "pembahagian politik",
["negara/*"] = {true},
default = {true},
},
["gurun"] = {
plural = "gurun",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"ekosistem"},
default = {true},
},
["deserted mediaeval village"] = {
link = "w",
fallback = "deserted medieval village",
},
["deserted medieval village"] = {
link = "w",
fallback = "ANCIENT petempatan",
},
["direct-administered municipality"] = {
-- China
link = "+w:direct-administered municipalities of China",
fallback = "municipality",
},
["direct-controlled municipality"] = {
-- several countries
link = "w",
fallback = "municipality",
},
["distributary"] = {
link = true,
preposition = "bagi",
fallback = "river",
},
["daerah"] = {
plural = "daerah",
link = true,
preposition = "di",
affix_type = "suf",
-- Grrr! FIXME! Here is where we need handlers for `class`. Using similar logic to
-- district_neighborhood_cat_handler, we need to check if we're below or above a city to determine if the class
-- is "settlement" or "subtatanegara".
class = "subtatanegara",
cat_handler = district_neighborhood_cat_handler,
-- No default. Countries for which districts are political divisions will get entries.
},
["districts and autonomous regions!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case Portugal.
category_link = "[[district]]s and [[autonomous region]]s",
class = "subtatanegara",
},
["districts and autonomous territorial units!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case Moldova.
category_link = "[[district]]s and [[w:autonomous territorial unit|autonomous territorial unit]]s",
class = "subtatanegara",
},
["ibu daerah"] = {
plural = "ibu daerah",
link = "separately",
fallback = "ibu kota",
},
["district headquarters"] = {
link = "separately",
fallback = "administrative centre",
},
["district municipality"] = {
-- In Canada, a district municipality is equivalent to a rural municipality and won't have neighborhoods; in
-- South Africa, district municipalities group local municipalities and hence won't have neighborhoods.
link = "w",
preposition = "bagi",
affix_type = "suf",
no_affix_strings = {"daerah", "municipality"},
fallback = "municipality",
class = "subtatanegara",
},
["division"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["division capital"] = {
link = "separately",
fallback = "ibu kota",
},
["dome"] = {
link = true,
fallback = "gunung",
},
["dormant volcano"] = {
link = true,
fallback = "volcano",
},
["duchy"] = {
link = true,
fallback = "tatanegara",
},
["emirate"] = {
link = true,
preposition = "bagi",
-- FIXME: Can be subpolities (of the United Arab Emirates).
fallback = "tatanegara",
},
["empayar"] = {
plural = "empayar",
link = true,
fallback = "tatanegara",
},
["enclave"] = {
link = true,
preposition = "bagi",
-- Enclaves can theoretically be any size but assume a subpolity.
class = "subtatanegara",
},
["entity"] = {
-- Bosnia and Herzegovina
link = "+w:entities of Bosnia and Herzegovina",
preposition = "bagi",
class = "subtatanegara",
},
["escarpment"] = {
link = true,
fallback = "gunung",
},
["ethnographic region"] = {
-- used in Lithuania
link = "+w:ethnographic regions of Lithuania",
fallback = "kawasan geografi dan budaya",
},
["exclave"] = {
link = true,
preposition = "bagi",
-- exclaves can theoretically be any size but assume a subpolity.
class = "subtatanegara",
},
["external territory"] = {
link = "separately",
fallback = "dependent territory",
},
["farm"] = {
link = true,
class = "non-admin settlement",
default = {"Farms and ranches"},
},
["farms and ranches!"] = {
category_link = "[[farm]]s and [[ranch]]es",
class = "non-admin settlement",
},
["federal city"] = {
link = "w",
preposition = "bagi",
fallback = "bandar",
},
["federal district"] = {
link = true,
preposition = "bagi",
-- Might have neighborhoods as federal districts are often cities (e.g. Mexico City)
has_neighborhoods = true,
class = "petempatan",
},
["federal subject"] = {
-- In Russia; a generic term for first-level administrative divisions (republics, oblasts, okrugs, krais,
-- autonomous okrugs and autonomous oblasts).
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["wilayah persekutuan"] = {
plural = "wilayah persekutuan",
link = "w",
fallback = "wilayah",
},
["fictional location"] = {
link = "separately",
former_type = "!",
class = "hypothetical location",
bare_category_parent = "tempat",
default = {true},
},
["First Nations reserve"] = {
-- Canada
link = "[[First Nations]] [[w:Indian reserve|reserve]]",
-- Wikipedia uses "Indian reserve"; presumably that is the legal term
fallback = "Indian reserve",
class = "subtatanegara",
},
["fjord"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["footpath"] = {
link = true,
fallback = "road",
},
["hutan"] = {
plural = "hutan",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"ekosistem", "perhutanan"},
default = {true},
},
["fort"] = {
link = true,
fallback = "building",
},
["fortress"] = {
link = true,
-- The default plural algorithm gets this right but the singularization algorithm incorrectly converts
-- fortresses -> fortresse, so put an entry here to ensure we singularize correctly.
plural = "fortresses",
fallback = "building",
},
["frazione"] = {
link = "w",
fallback = "hamlet",
},
["freeway"] = {
link = true,
fallback = "road",
},
["French prefecture"] = {
link = "[[w:prefectures in France|prefecture]]",
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
},
["kawasan geografi dan budaya"] = {
plural = "kawasan geografi dan budaya",
link = "+w:cultural area",
-- `generic_before_non_cities` is used when generating the category description of categories of the format
-- `Geographic and cultural areas of PLACE`. `preposition` is used when generating {{place}} description and
-- categories for any placetype that falls back to `geographic and cultural area`.
generic_before_non_cities = "bagi",
preposition = "bagi",
class = "kawasan geografi",
bare_category_parent = "tempat",
["negara/*"] = {true},
["negara bahagian/*"] = {true},
["benua/*"] = {true},
default = {true},
},
["geographic area"] = {
link = "+w:geographic region",
fallback = "kawasan geografi dan budaya",
},
["kawasan geografi"] = {
plural = "kawasan geografi",
link = "w",
fallback = "kawasan geografi dan budaya",
},
["geographical area"] = {
link = "w",
fallback = "kawasan geografi dan budaya",
},
["geographical region"] = {
link = "w",
fallback = "kawasan geografi dan budaya",
},
["geopolitical zone"] = {
-- Nigeria
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["gewog"] = {
-- Bhutan
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["ghost town"] = {
link = true,
generic_before_non_cities = "di",
class = "non-admin settlement",
bare_category_parent = "former settlements",
cat_handler = city_type_cat_handler,
default = {true},
},
["glen"] = {
link = true,
fallback = "valley",
},
["kegabenoran"] = {
plural = "kegabenoran",
link = true,
preposition = "di",
affix_type = "suf",
class = "subtatanegara",
},
["greater administrative region"] = {
-- China (former division)
link = "w",
preposition = "bagi",
class = "subtatanegara",
inherently_former = {"FORMER"},
},
["gromada"] = {
-- Poland (former division)
link = "w",
preposition = "bagi",
affix_type = "Pref",
class = "subtatanegara",
inherently_former = {"FORMER"},
},
["group of islands"] = {
link = "[[group]] of [[island]]s",
plural = "groups of islands",
plural_link = "[[group]]s of [[island]]s",
fallback = "island group",
},
["gulf"] = {
link = true,
preposition = "bagi",
holonym_use_the = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["hamlet"] = {
link = true,
fallback = "kampung",
},
["harbor city"] = {
link = "separately",
fallback = "bandar",
},
["harbor town"] = {
link = "separately",
fallback = "pekan",
},
["harbour city"] = {
link = "separately",
fallback = "bandar",
},
["harbour town"] = {
link = "separately",
fallback = "pekan",
},
["headland"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
},
["headquarters"] = {
link = "w",
fallback = "administrative centre",
},
["heath"] = {
link = true,
fallback = "moor",
},
["hemisfera"] = {
plural = "hemisfera",
link = true,
entry_placetype_use_the = true,
fallback = "kawasan benua",
},
["lebuh raya"] = {
plural = "lebuh raya",
link = true,
fallback = "road",
},
["bukit"] = {
plural = "bukit",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
},
["hill station"] = {
link = "w",
fallback = "pekan",
},
["hill town"] = {
link = "w",
fallback = "pekan",
},
["historic region"] = {
-- provided only for the link
link = "+w:historical region",
fallback = "FORMER kawasan geografi",
},
["historical county"] = {
-- needed for historical counties of England/etc.
link = "+w:historic county",
fallback = "FORMER subtatanegara",
},
["historical region"] = {
-- provided only for the link
link = "w",
fallback = "FORMER kawasan geografi",
},
["home rule city"] = {
link = "w",
fallback = "bandar",
},
["home rule municipality"] = {
link = "w",
fallback = "municipality",
},
["hot spring"] = {
link = true,
fallback = "spring",
},
["house"] = {
link = true,
fallback = "building",
},
["housing estate"] = {
-- not the same as a housing project (i.e. public housing)
link = true,
-- not exactly the case but approximately
fallback = "neighborhood",
},
["hromada"] = {
-- Ukraine
link = "w",
disallow_in_entries = "Use placetype 'urban hromada', 'rural hromada' or 'settlement hromada' in place of bare 'hromada'",
disallow_in_holonyms = "Use placetype 'urban hromada'/'uhrom', 'rural hromada'/'rhrom' or 'settlement hromada'/'shrom' in place of bare 'hromada'",
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["inactive volcano"] = {
link = "w",
fallback = "dormant volcano",
},
["independent city"] = {
link = true,
fallback = "bandar",
},
["independent town"] = {
link = "+independent city",
fallback = "pekan",
},
["Indian reservation"] = {
link = "w",
-- In the US. Also known as "Native American reservation" or "domestic dependent nation", and the reservations
-- themselves often use the term "nation" in their official name (e.g. the "Navajo Nation"). But Wikipedia puts
-- the article at [[w:Indian reservation]] and uses that term when describing e.g. what the Navajo Nation is,
-- so this must still be the legal term.
preposition = "bagi",
class = "subtatanegara",
default = {true},
},
["Indian reserve"] = {
link = "w",
-- In Canada. "First Nations reserve" sounds more modern/PC but Wikipedia uses "Indian reserve"; presumably that
-- is still the legal term.
preposition = "bagi",
class = "subtatanegara",
default = {true},
},
["inland sea"] = {
-- note, we also have 'inland' as a qualifier
link = true,
fallback = "laut",
},
["inner city area"] = {
link = "[[inner city]] [[area]]",
fallback = "neighborhood",
},
["pulau"] = {
plural = "pulau",
link = true,
preposition = "bagi",
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
},
["island country"] = {
-- FIXME: The following should map to both 'island' and 'country'.
link = "w",
fallback = "negara",
},
["island group"] = {
link = "separately",
fallback = "pulau",
},
["island municipality"] = {
link = "w",
fallback = "municipality",
},
["islet"] = {
link = "w",
fallback = "pulau",
},
["Israeli settlement"] = {
link = "w",
class = "petempatan",
default = {true},
},
["judicial capital"] = {
link = "w",
fallback = "ibu kota",
},
["khanate"] = {
link = true,
fallback = "tatanegara",
},
["kibbutz"] = {
link = true,
plural = "kibbutzim",
class = "non-admin settlement",
default = {true},
},
["kingdom"] = {
link = true,
fallback = "monarchy",
},
["krai"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
class = "subtatanegara",
},
["tasik"] = {
plural = "tasik",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["bentuk muka bumi!"] = {
category_link = "[[landform]]s",
bare_category_parent = "tempat",
addl_bare_category_parents = {"Bumi"},
},
["largest city"] = {
link = "[[large]]st [[city]]",
entry_placetype_use_the = true,
fallback = "bandar",
has_neighborhoods = true,
},
["league"] = {
link = true,
fallback = "persekutuan",
},
["legislative capital"] = {
link = "separately",
fallback = "ibu kota",
},
["library"] = {
link = true,
fallback = "building",
},
["lieutenancy area"] = {
-- used in the United Kingdom; per Wikipedia:
-- In England, lieutenancy areas are colloquially known as the ceremonial counties, although this phrase does
-- not appear in any legislation referring to them. The lieutenancy areas of Scotland are subdivisions of
-- Scotland that are more or less based on the counties of Scotland, making use of the major cities as separate
-- entities.[2] In Wales, the lieutenancy areas are known as the preserved counties of Wales and are based on
-- those used for lieutenancy and local government between 1974 and 1996. The lieutenancy areas of Northern
-- Ireland correspond to the six counties and two former county boroughs.[3]
link = "w",
fallback = "ceremonial county",
},
["local authority district"] = {
link = "w",
fallback = "local government district",
},
["local government area"] = {
-- Australia
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["local council"] = {
-- Malta; similar to municipalities
link = "+w:local councils of Malta",
preposition = "bagi",
fallback = "municipality",
},
["local government district"] = {
link = "w",
preposition = "bagi",
affix_type = "suf",
affix = "daerah",
class = "subtatanegara",
},
["local government district with borough status"] = {
link = "[[w:local government district|local government district]] with [[w:borough status|borough status]]",
plural = "local government districts with borough status",
plural_link = "[[w:local government district|local government districts]] with [[w:borough status|borough status]]",
preposition = "bagi",
affix_type = "suf",
affix = "daerah",
class = "subtatanegara",
},
["local urban district"] = {
link = "w",
fallback = "unincorporated community",
},
["locality"] = {
link = "+w:locality (settlement)",
-- not necessarily true, but usually is the case
fallback = "kampung",
},
["London borough"] = {
link = "w",
preposition = "bagi",
affix_type = "pref",
affix = "borough",
fallback = "local government district with borough status",
has_neighborhoods = true,
},
["macroregion"] = {
link = true,
fallback = "wilayah",
},
["man-made structures!"] = {
category_link = "[[w:geographical feature#Engineered constructs|man-made structures]] such as [[airport]]s, [[university|universities]] and [[metro station]]s",
bare_category_parent = "tempat",
},
["manor"] = {
-- FIXME: or is this more like a farm?
link = true,
fallback = "building",
},
["marginal sea"] = {
link = true,
preposition = "bagi",
fallback = "laut",
},
["market city"] = {
link = "+market town",
fallback = "bandar",
},
["market town"] = {
link = true,
fallback = "pekan",
},
["massif"] = {
link = true,
fallback = "gunung",
},
["megacity"] = {
link = true,
fallback = "bandar",
},
["metro station"] = {
link = true,
class = "man-made structure",
},
["metropolitan borough"] = {
link = true,
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = {"borough", "bandar"},
fallback = "local government district",
has_neighborhoods = true,
},
["metropolitan city"] = {
-- These exist e.g. in Italy and are more like municipalities or even provinces than cities.
link = true,
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = {"metropolitan", "bandar"},
class = "subtatanegara",
},
["metropolitan county"] = {
link = true,
fallback = "kaunti",
},
["metropolitan municipality"] = {
-- In South Africa, metropolitan municipalities group local municipalities and are like districts, between
-- provinces and municipalities.
-- In Turkey, metropolitan municipalities are provinces-level.
link = "w",
preposition = "bagi",
affix_type = "Suf",
no_affix_strings = {"metropolitan", "municipality"},
fallback = "municipality",
class = "subtatanegara",
},
["microdistrict"] = {
-- residential complex in post-Soviet states
link = true,
fallback = "neighborhood",
},
["micronations!"] = {
-- FIXME, merge with microstate
category_link = "[[micronation]]s",
bare_category_parent = "countries",
},
["microstate"] = {
link = true,
fallback = "negara",
},
["military base"] = {
link = "w",
class = "petempatan", -- or "man-made structure"?
default = {true},
},
["minster town"] = {
-- England
link = "separately",
fallback = "pekan",
},
["monarchy"] = {
link = true,
fallback = "tatanegara",
},
["moor"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi", "ekosistem"},
default = {true},
},
["moorland"] = {
link = true,
fallback = "moor",
},
["motorway"] = {
link = true,
fallback = "road",
},
["gunung"] = {
plural = "gunung",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
},
["mountain indigenous district"] = {
-- Taiwan
link = "+w:district (Taiwan)",
fallback = "daerah",
},
["mountain indigenous township"] = {
-- Taiwan
link = "+w:township (Taiwan)",
fallback = "township",
},
["mountain pass"] = {
link = true,
-- The default plural algorithm gets this right but the singularization algorithm incorrectly converts
-- passes -> passe, so put an entry here to ensure we singularize correctly.
plural = "mountain passes",
class = "sifat semula jadi",
addl_bare_category_parents = {"mountains"},
default = {true},
},
["mountain range"] = {
link = true,
fallback = "gunung",
},
["mountainous region"] = {
link = "separately",
fallback = "wilayah",
},
["mukim"] = {
-- Malaysia, Brunei, Indonesia, Singapore
link = true,
preposition = "di",
class = "subtatanegara",
},
["municipal district"] = {
link = "w",
-- meaning varies depending on the country; for now, assume no neighborhoods.
-- FIXME: has_neighborhoods might have to be a function that looks at the containing holonyms.
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = "daerah",
fallback = "municipality",
},
["municipality"] = {
link = true,
preposition = "bagi",
has_neighborhoods = true,
class = "subtatanegara",
},
["municipality with city status"] = {
link = "[[municipality]] with [[w:city status|city status]]",
plural = "municipalities with city status",
plural_link = "[[municipality|municipalities]] with [[w:city status|city status]]",
fallback = "municipality",
},
["museum"] = {
link = true,
fallback = "building",
},
["mythological location"] = {
link = "separately",
former_type = "!",
class = "hypothetical location",
bare_category_parent = "tempat",
default = {true},
},
["named bridges!"] = {
category_link = "notable [[bridge]]s",
bare_category_parent = "man-made structures",
addl_bare_category_parents = {"bridges"},
},
["named buildings!"] = {
category_link = "notable [[house]]s, [[library|libraries]] and other [[building]]s",
bare_category_parent = "man-made structures",
addl_bare_category_parents = {"buildings"},
},
["named roads!"] = {
category_link = "notable [[road]]s, [[highway]]s, [[trail]]s and similar linear structures",
bare_category_parent = "man-made structures",
addl_bare_category_parents = {"roads"},
},
["ibu negara"] = {
plural = "ibu negara",
link = "w",
fallback = "ibu kota",
},
["national park"] = {
link = true,
fallback = "park",
},
["sifat semula jadi!"] = {
category_link = "[[w:geographical feature#Natural features|natural features]] such as [[lake]]s, [[mountain]]s, [[island]]s and [[ocean]]s",
bare_category_parent = "tempat",
},
["neighborhood"] = {
-- The majority of the properties here apply to both `neighborhoods` and `neighbourhoods`; the choice of which
-- one to use is made by district_neighborhood_cat_handler() based on the value of `british_spelling` for the
-- location (city, political division, etc.) of the holonym that follows the word "neighbo(u)hoods" in the
-- category name. It does *NOT* depend on whether the {{place}} call uses "neighborhoods" or "neighbourhoods".
-- (In general it can't, because other things like "urban areas", "daerah", "subdivisions" and the like also
-- categorize as neighbo(u)rhoods.)
link = true,
-- See below. These are used by category handlers in [[Module:category tree/topic cat/data/Places]].
generic_before_non_cities = "di",
generic_before_cities = "bagi",
-- The following text is suitable for the top-level description of a neighborhood as well as categories of the
-- form `Neighborhoods in POLDIV` e.g. `Neighborhoods in Illinois, USA` but not for categories of the form
-- `Neighborhoods of Chicago`, where we'd get "... and other subportions of [[city|cities]] of [[Chicago]]".
category_link = "[[neighborhood]]s, [[district]]s and other subportions of [[city|cities]]",
category_link_before_city = "[[neighborhood]]s, [[district]]s and other subportions",
-- NOTE: This setting is needed for administrative divisions like barangays that fall back to `neighborhood`,
-- when set in [[Module:place/locations]] for a specific country (e.g. the Philippines). The above settings
-- for `generic_before_non_cities` and `generic_before_cities` are used by category handlers in
-- [[Module:category tree/topic cat/data/Places]] for `Neighborhoods in POLDIV` and `Neighborhoods of CITY`
-- categories. In fact, district_neighborhood_cat_handler() does not currently pay attention to them, but
-- generates "bagi" before cities and "di" before non-cities regardless. (FIXME: We should change that.)
preposition = "bagi",
class = "non-admin settlement",
cat_handler = district_neighborhood_cat_handler,
},
["neighbourhood"] = {
link = true,
category_link = "[[neighbourhood]]s, [[district]]s and other subportions of [[city|cities]]",
category_link_before_city = "[[neighbourhood]]s, [[district]]s and other subportions",
fallback = "neighborhood",
},
["new area"] = {
-- China (type of economic development zone, varying greatly in size)
link = "w",
preposition = "di",
class = "subtatanegara", --?
},
["new town"] = {
link = true,
fallback = "pekan",
},
["non-city capital"] = {
link = "[[capital]]",
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
cat_handler = function(data)
return capital_city_cat_handler(data, "non-city")
end,
-- FIXME, do we need the following?
default = {true},
},
["non-metropolitan county"] = {
link = "w",
fallback = "kaunti",
},
["non-metropolitan district"] = {
link = "w",
fallback = "local government district",
},
["non-sovereign kingdom"] = {
-- especially in Africa and Asia
link = "+w:non-sovereign monarchy",
generic_before_non_cities = "di",
class = "subtatanegara",
["negara/*"] = {true},
["benua/*"] = {true},
default = {true},
},
["non-sovereign monarchy"] = {
link = "w",
fallback = "non-sovereign kingdom",
},
["oblast"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
class = "subtatanegara",
},
["oblasts and autonomous republics!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case Ukraine.
category_link = "[[oblast]]s and [[w:autonomous republic|autonomous republic]]s",
class = "subtatanegara",
},
["lautan"] = {
plural = "lautan",
link = true,
holonym_use_the = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"laut", "badan air"},
default = {true},
},
["okrug"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
class = "subtatanegara",
},
["overseas collectivity"] = {
link = "w",
fallback = "collectivity",
},
["overseas department"] = {
link = "w",
fallback = "department",
},
["overseas territory"] = {
link = "w",
fallback = "dependent territory",
},
["parish"] = {
link = true,
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["parish municipality"] = {
-- in Quebec, often similar to a rural village; the famous [[Saint-Louis-du-Ha! Ha!]] is one of them.
link = "+w:parish municipality (Quebec)",
preposition = "bagi",
fallback = "municipality",
has_neighborhoods = true,
},
["parish seat"] = {
link = "separately",
entry_placetype_use_the = true,
preposition = "bagi",
class = "capital",
has_neighborhoods = true,
},
["park"] = {
link = true,
class = "man-made structure",
default = {true},
},
["pass"] = {
link = "+mountain pass",
-- The default plural algorithm gets this right but the singularization algorithm incorrectly converts
-- passes -> passe, so put an entry here to ensure we singularize correctly.
plural = "passes",
fallback = "mountain pass",
},
["path"] = {
link = true,
fallback = "road",
},
["peak"] = {
link = true,
fallback = "gunung",
},
["semenanjung"] = {
plural = "semenanjung",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
},
["periphery"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["tempat!"] = {
generic_before_non_cities = "di",
generic_before_cities = "di",
class = "tempat am",
category_link = "[[tempat]] secara umum",
-- `category_link_top_level` control the description used in the top-level [[Category:Places]] and
-- language-specific variants such as [[Category:en:Places]]. The actual text for a language-spefic variant is
-- "{{{langname}}} names of [[geographical]] [[place]]s of all sorts; [[toponym]]s." where the "names of"
-- portion is automatically generated by the appropriate handler in
-- [[Module:category tree/topic cat/data/Places]].
category_link_top_level = "[[tempat]] [[geografi]] secara umum; [[toponim]]",
bare_category_parent = "nama",
},
["planned community"] = {
-- Include this so we don't categorize 'planned community' into villages, as 'community' does.
link = true,
class = "petempatan",
has_neighborhoods = true,
},
["plateau"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true},
-- FIXME: Should generate both "Plateaus" and the appropriate 'geographic and cultural area' category
},
["Polish colony"] = {
link = "[[w:colony (Poland)|colony]]",
affix_type = "suf",
affix = "colony",
fallback = "kampung",
has_neighborhoods = true,
},
["pembahagian politik!"] = {
category_link = "[[political]] [[division]]s and [[subdivision]]s, such as [[state]]s, [[province]]s, [[county|counties]] or [[district]]s",
bare_category_parent = "tempat",
},
["tatanegara"] = {
plural = "tatanegara",
link = true,
category_link = "[[independent]] or [[semi-]][[independent]] [[polity|polities]]",
class = "tatanegara",
bare_category_parent = "tempat",
default = {true},
},
["populated place"] = {
link = "+w:populated place",
-- not necessarily true, but usually is the case
fallback = "kampung",
},
["port"] = {
link = true,
class = "man-made structure",
default = {true},
},
["port city"] = {
-- FIXME: should categorize into "Ports" as well as "Cities"
link = true,
fallback = "bandar",
},
["port town"] = {
-- FIXME: should categorize into "Ports" as well as "Towns"
link = "w",
fallback = "pekan",
},
["prefecture"] = {
-- FIXME! `prefecture` is like a county in Japan and elsewhere but a department capital city in France.
-- May need `has_neighborhoods` to be a function.
link = true,
preposition = "bagi",
display_handler = prefecture_display_handler,
class = "subtatanegara",
},
["prefecture-level city"] = {
-- China; they are huge entities with a central city; not cities themselves.
link = "w",
preposition = "bagi",
class = "subtatanegara",
},
["preserved county"] = {
-- In Wales; they are former counties enshrined in law; there are 8 of them and each consists of one or more
-- "principal areas" (styled as "kaunti" or "county boroughs"), of which there are 22.
link = "w",
preposition = "bagi",
class = "subtatanegara",
inherently_former = {"FORMER"},
},
["primary area"] = {
-- a grouping of "daerah" (neighborhoods) in Gothenburg, Sweden
link = "+w:sv:primärområde",
fallback = "neighborhood",
},
["principality"] = {
link = true,
fallback = "monarchy",
},
["promontory"] = {
link = true,
fallback = "headland",
},
["protectorate"] = {
link = true,
fallback = "dependent territory",
},
["province"] = {
link = true,
preposition = "bagi",
display_handler = province_display_handler,
class = "subtatanegara",
},
["provinces and autonomous regions!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case China.
category_link = "[[province]]s and [[autonomous region]]s",
class = "subtatanegara",
},
["provinces and territories!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case Canada and Pakistan.
category_link = "[[province]]s and [[territory|territories]]",
class = "subtatanegara",
},
["provincial capital"] = {
link = true,
fallback = "ibu kota",
},
["raion"] = {
link = true,
preposition = "bagi",
affix_type = "Suf",
class = "subtatanegara",
},
["ranch"] = {
link = true,
fallback = "farm",
},
["range"] = {
-- FIXME: Where is this used? Is it a mountain range?
link = true,
holonym_use_the = true,
class = "sifat semula jadi",
},
["regency"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["wilayah"] = {
plural = "wilayah",
link = true,
preposition = "bagi",
-- If 'region' isn't a specific administrative division, fall back to 'geographic and cultural area'
fallback = "kawasan geografi dan budaya",
-- "former region" is a subpolity but traditional/historic(al)/ancient/medieval/etc. is a geographic region
class = "kawasan geografi",
},
["regional capital"] = {
link = "separately",
fallback = "ibu kota",
},
["regional county municipality"] = {
-- Quebec
link = "w",
preposition = "bagi",
affix_type = "Suf",
no_affix_strings = {"municipality", "kaunti"},
fallback = "municipality",
},
["regional district"] = {
link = "w",
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = "daerah",
fallback = "daerah",
},
["regional municipality"] = {
link = "w",
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = "municipality",
fallback = "municipality",
},
["regional unit"] = {
link = "w",
preposition = "bagi",
affix_type = "suf",
class = "subtatanegara",
},
["registration county"] = {
-- Used in Scotland for land registration purposes; formerly used in England, Wales and Ireland for statistical
-- purposes (registration of births, deaths and marriages, and for the output of census information).
link = "w",
fallback = "kaunti",
},
["republic"] = {
-- Of Russia, Yugoslavia, etc. "Republics" in general are sovereign but we use "negara" in that case.
link = true,
fallback = "constituent republic",
},
["research base"] = {
link = "+w:research station",
fallback = "research station",
},
["research station"] = {
link = "w",
class = "non-admin settlement", -- or "man-made structure"?
default = {true},
},
["reservoir"] = {
link = true,
fallback = "tasik",
},
["residential area"] = {
link = "separately",
fallback = "neighborhood",
},
["resort city"] = {
link = "w",
fallback = "bandar",
},
["resort town"] = {
link = "w",
fallback = "pekan",
},
["river"] = {
link = true,
generic_before_non_cities = "di",
holonym_use_the = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
cat_handler = city_type_cat_handler,
["benua/*"] = {true},
default = {true},
},
["river island"] = {
link = "w",
fallback = "pulau",
},
["road"] = {
link = true,
class = "man-made structure",
default = {"Named roads"},
},
["Roman province"] = {
-- FIXME! Eliminate this in favor of 'former province|emp/Roman Empire'
link = "w",
default = {"Provinces of the Roman Empire"},
class = "subtatanegara",
},
["royal borough"] = {
link = "w",
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = {"royal", "borough"},
fallback = "local government district with borough status",
has_neighborhoods = true,
},
["royal burgh"] = {
link = true,
fallback = "borough",
},
["royal capital"] = {
link = "w",
fallback = "ibu kota",
},
["rural committee"] = {
-- Hong Kong; a group of villages
link = "w",
affix_type = "Suf",
has_neighborhoods = true,
class = "petempatan",
},
["rural community"] = {
-- New Brunswick
link = "+w:list of municipalities in New_Brunswick#Rural communities",
fallback = "municipality",
},
["rural hromada"] = {
link = "[[rural]] [[w:hromada|hromada]]",
affix_type = "suf",
fallback = "hromada",
},
["rural municipality"] = {
link = "w",
preposition = "bagi",
affix_type = "Pref",
no_affix_strings = "municipality",
fallback = "municipality",
has_neighborhoods = true, --?
},
["rural township"] = {
-- Taiwan
link = "+w:rural township (Taiwan)",
fallback = "township",
},
["sanctuary"] = {
link = true,
fallback = "temple",
},
["satrapy"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
inherently_former = {"ANCIENT", "FORMER"},
},
["laut"] = {
plural = "laut",
link = true,
holonym_use_the = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["seaport"] = {
link = true,
fallback = "port",
},
["seat"] = {
link = true,
fallback = "administrative centre",
},
["self-administered area"] = {
-- Myanmar (groups self-administered divisions and zones)
link = "+w:self-administered zone",
preposition = "bagi",
class = "subtatanegara",
},
["self-administered division"] = {
-- Myanmar (only one of them: Wa Self-Administered Division)
link = "w",
fallback = "self-administered area",
},
["self-administered zone"] = {
-- Myanmar (five of them)
link = "w",
fallback = "self-administered area",
},
["separatist state"] = {
link = "separately",
fallback = "unrecognized country",
},
["petempatan"] = {
plural = "petempatan",
link = true,
category_link = "[[petempatan]] seperti [[bandar]], [[kampung]] dan [[ladang]]",
bare_category_parent = "tempat",
-- not necessarily true, but usually is the case
fallback = "kampung",
},
["settlement hromada"] = {
link = "[[w:Populated places in Ukraine#Rural settlements|settlement]] [[w:hromada|hromada]]",
affix_type = "suf",
fallback = "hromada",
},
["sheading"] = {
-- Isle of Man
link = true,
fallback = "daerah",
},
["sheep station"] = {
-- Australia
link = true,
fallback = "farm",
},
["shire"] = {
link = true,
fallback = "kaunti",
},
["shire county"] = {
link = "w",
fallback = "kaunti",
},
["shire town"] = {
link = true,
fallback = "county seat",
},
["ski resort city"] = {
link = "[[ski resort]] [[city]]",
fallback = "bandar",
},
["ski resort town"] = {
link = "[[ski resort]] [[town]]",
fallback = "pekan",
},
["spa city"] = {
link = "+w:spa town",
fallback = "bandar",
},
["spa town"] = {
link = "w",
fallback = "pekan",
},
["space station"] = {
link = true,
fallback = "research station",
},
["special administrative region"] = {
-- in China; in practice they are city-like (Hong Kong, Macau); also [[Oecusse]] in East Timor is formally a
-- "special administrative region"; North Korea had one such region planned (Sinuiju) but abandoned; Indonesia
-- has similar "special regions" of Jakarta, Yogyakarta and Aceh; and South Sudan has three "special
-- administrative areas"
link = "+w:special administrative regions of China",
preposition = "bagi",
class = "subtatanegara",
has_neighborhoods = true, --?
-- no suffix since places in Hong Kong or Macau are listed without China, except Hong Kong and Macau themselves
-- they also contain regions (or areas), e.g. [[Kowloon]], so it would be confusing
suffix = "",
},
["special collectivity"] = {
link = "w",
fallback = "collectivity",
},
["special municipality"] = {
-- formerly linked to the Taiwan article but there are also special municipalities of the Netherlands
link = "w",
fallback = "municipality",
},
["special ward"] = {
-- Tokyo
link = true,
fallback = "municipality",
},
["spit"] = {
link = true,
fallback = "semenanjung",
},
["spring"] = {
link = true,
class = "sifat semula jadi",
default = {true},
},
["bintang"] = {
plural = "bintang",
link = true,
class = "sifat semula jadi",
default = {true},
},
["negeri"] = {
plural = "negeri",
link = true,
preposition = "di",
generic_before_non_cities = "di",
class = "subtatanegara",
-- 'former/historical state' could refer either to a state of a country (a division) or a state = sovereign
-- entity. The latter appears more common (e.g. in various "ancient states" of East Asia).
former_type = "tatanegara",
},
["negeri dan wilayah!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case Australia.
category_link = "[[negeri]] dan [[wilayah]]",
class = "subtatanegara",
},
["states and union territories!"] = {
-- This and other similar "combined placetypes" are for use in the plural when grouping first-level
-- administrative regions of certain countries, in this case India.
category_link = "[[state]]s and [[union territory|union territories]]",
class = "subtatanegara",
},
["ibu negeri"] = {
plural = "ibu negeri",
link = "separately",
fallback = "ibu kota",
},
["state park"] = {
link = true,
fallback = "park",
},
["state-level new area"] = {
-- China (type of economic development zone, varying greatly in size)
link = "w",
fallback = "new area",
},
["statistical region"] = {
-- Slovenia
link = true,
fallback = "administrative region",
},
["statutory city"] = {
link = "w",
fallback = "bandar",
},
["statutory town"] = {
link = "w",
fallback = "pekan",
},
["selat"] = {
plural = "selat",
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"badan air"},
default = {true},
},
["stream"] = {
link = true,
fallback = "river",
},
["street"] = {
link = true,
fallback = "road",
},
["strip"] = {
link = true,
fallback = "kawasan geografi",
},
["strip of land"] = {
link = "[[strip]] of [[land]]",
plural = "strips of land",
plural_link = "[[strip]]s of [[land]]",
fallback = "kawasan geografi",
},
["sub-metropolitan city"] = {
link = "+w:List of cities in Nepal#Sub-metropolitan cities",
fallback = "bandar",
},
["sub-prefectural city"] = {
link = "w",
fallback = "subprovincial city",
},
["subdaerah"] = {
plural = "subdaerah",
link = true,
preposition = "di",
has_neighborhoods = true, --?
-- FIXME: subdistricts can be neighborhood-like (of Jakarta) or larger (in China); need a handler
class = "subtatanegara",
default = {true},
},
["subbahagian"] = {
plural = "subbahagian",
link = true,
preposition = "di",
affix_type = "suf",
-- FIXME: subdivisions can be neighborhood-like or larger; need a handler
class = "subtatanegara",
cat_handler = district_neighborhood_cat_handler,
},
["submerged ghost town"] = {
-- FIXME: Consider just having "submerged" as a qualifier.
link = "[[submerged]] [[ghost town]]",
fallback = "ghost town",
},
["subnational kingdom"] = {
link = "+w:subnational monarchy",
fallback = "non-sovereign kingdom",
},
["subnational monarchy"] = {
link = "w",
fallback = "non-sovereign kingdom",
},
["subprefecture"] = {
link = true,
affix_type = "suf",
preposition = "bagi",
class = "subtatanegara",
},
["subprovince"] = {
link = true,
preposition = "bagi",
class = "subtatanegara",
},
["subprovincial city"] = {
link = "w",
-- China; special status given to certain prefecture-level cities
fallback = "prefecture-level city",
},
["subprovincial district"] = {
link = "w",
-- China; special status given to Binhai New Area and Pudong New Area, which are county-level districts
preposition = "bagi",
class = "subtatanegara",
},
["subregion"] = {
link = true,
fallback = "kawasan geografi",
},
["suburb"] = {
link = true,
-- The following text is suitable for the top-level description of a suburb as well as categories of the form
-- 'Suburbs in POLDIV' e.g. 'Suburbs in Illinois, USA' but not for categories of the form 'Suburbs of Chicago',
-- where we'd get "[[suburb]]s of [[city|cities]] of [[Chicago]]".
category_link = "[[suburb]]s of [[city|cities]]",
category_link_before_city = "[[suburb]]s",
-- See comments under "neighborhood" for the following three settings. They are used by
-- [[Module:category tree/topic cat/data/Places]] for generating the text of 'Suburbs in/of PLACE' categories
-- but currently ignored by district_neighborhood_cat_handler (which actually generates the categories for a
-- given page), which hardcodes "di" for non-cities and "bagi" for cities. (FIXME: Change this.)
generic_before_non_cities = "di",
generic_before_cities = "bagi",
preposition = "bagi",
has_neighborhoods = true, --?
class = "non-admin settlement", --?
cat_handler = district_neighborhood_cat_handler,
},
["suburban area"] = {
link = "w",
fallback = "suburb",
},
["subway station"] = {
link = "w",
fallback = "metro station",
},
["sum"] = {
-- In China, Mongolia, Russia; something like a county in Mongolia but a township in China (Inner Mongolia),
-- and equivalent to a [[selsoviet]] in the parts of Russia where it's in use (a rural council, below a raion).
link = "+w:sum (administrative division)",
-- This fallback is somewha arbitrary. We could use "kaunti" but that has a display handler
-- which we don't want to be active (FIXME: If the display handler would be active, that's a bug).
fallback = "division",
},
["superbenua"] = {
plural = "superbenua",
link = true,
fallback = "benua",
},
["tehsil"] = {
link = true,
affix_type = "suf",
no_affix_strings = {"tehsil", "tahsil"},
class = "subtatanegara",
},
["temple"] = {
link = true,
fallback = "building",
},
["territorial authority"] = {
link = "w",
fallback = "daerah",
},
["territory"] = {
link = "[[wilayah]]",
plural_link = "[[wilayah]]",
category_link = "[[wilayah]]",
preposition = "di",
generic_before_non_cities = "di",
class = "subtatanegara",
},
["theme"] = {
link = "+w:theme (Byzantine district)",
preposition = "bagi",
class = "subtatanegara",
},
["pekan"] = {
plural = "pekan",
link = true,
generic_before_non_cities = "di",
has_neighborhoods = true,
class = "petempatan",
cat_handler = city_type_cat_handler,
default = {true},
},
["town with bystatus"] = {
-- can't use templates in links currently
link = "[[town]] with [[bystatus#Norwegian Bokmål|bystatus]]",
plural = "towns with bystatus",
plural_link = "[[town]]s with [[bystatus#Norwegian Bokmål|bystatus]]",
fallback = "pekan",
},
["township"] = {
link = true,
has_neighborhoods = true,
class = "petempatan", --?
default = {true},
},
["township municipality"] = {
-- Quebec
link = "+w:township municipality (Quebec)",
preposition = "bagi",
fallback = "municipality",
has_neighborhoods = true, --?
},
["traditional county"] = {
link = true,
fallback = "kaunti",
},
["traditional region"] = {
-- FIXME: Verify this works. Same for 'historic(al) region'.
-- provided only for the link
link = "w",
fallback = "FORMER kawasan geografi",
},
["trail"] = {
link = true,
fallback = "road",
},
["treaty port"] = {
link = "w",
fallback = "bandar",
class = "petempatan",
inherently_former = {"FORMER"},
},
["tributary"] = {
link = true,
preposition = "bagi",
fallback = "river",
},
["underground station"] = {
link = "w",
fallback = "metro station",
},
["unincorporated area"] = {
link = "w",
-- I don't know if this fallback makes sense everywhere.
fallback = "unincorporated community",
},
["unincorporated community"] = {
link = true,
generic_before_non_cities = "di",
class = "non-admin settlement",
},
["unincorporated territory"] = {
link = "w",
fallback = "wilayah",
},
["union territory"] = {
-- India
link = true,
preposition = "bagi",
entry_placetype_indefinite_article = "a",
class = "subtatanegara",
},
["unitary authority"] = {
-- UK, New Zealand
link = true,
entry_placetype_indefinite_article = "a",
fallback = "local government district",
},
["unitary district"] = {
link = "w",
entry_placetype_indefinite_article = "a",
fallback = "local government district",
},
["united township municipality"] = {
-- Quebec
link = "+w:united township municipality (Quebec)",
entry_placetype_indefinite_article = "a",
fallback = "township municipality",
has_neighborhoods = true, --?
},
["university"] = {
link = true,
entry_placetype_indefinite_article = "a",
class = "man-made structure",
default = {true},
},
["unrecognised country"] = {
link = "w",
fallback = "unrecognized country",
},
["unrecognized and nearly unrecognized countries!"] = {
category_link = "[[de facto]] [[independent]] [[state]]s with little or no {{w|international recognition}}",
bare_category_parent = "country-like entities",
},
["unrecognized country"] = {
link = "w",
class = "tatanegara",
default = {"Unrecognized and nearly unrecognized countries"},
},
["unrecognised state"] = {
link = "w",
fallback = "unrecognized country",
},
["unrecognized state"] = {
link = "w",
fallback = "unrecognized country",
},
["urban area"] = {
link = "separately",
fallback = "neighborhood",
},
["urban hromada"] = {
link = "[[urban]] [[w:hromada|hromada]]",
affix_type = "suf",
fallback = "hromada",
},
["urban service area"] = {
-- A strange beast existing in Alberta; technically a type of hamlet but in practice used for much larger
-- cities and treated equivalent to a city. (There are only two of them, [[Fort McMurray]] and [[Sherwood Park]]).
link = "w",
fallback = "bandar",
},
["urban township"] = {
link = "w",
fallback = "township",
},
["urban-type settlement"] = {
-- appears to be a particular type of small urban settlement in post-Soviet states,
-- had an administrative function.
link = "w",
fallback = "pekan",
},
["valley"] = {
link = true,
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi", "air"},
default = {true},
},
["viceroyalty"] = {
-- in essence, a type of colony
link = true,
fallback = "dependent territory",
},
["kampung"] = {
plural = "kampung",
link = true,
generic_before_non_cities = "di",
category_link = "[[village]]s, [[hamlet]]s, and other small [[community|communities]] and [[settlement]]s",
class = "petempatan",
cat_handler = city_type_cat_handler,
default = {true},
},
["village development committee"] = {
-- former administrative structure in Nepal; also exists in India but not as a formal unit
link = "+w:village development committee (Nepal)",
inherently_former = {"FORMER"},
fallback = "kampung",
},
["village municipality"] = {
-- Quebec
link = "+w:village municipality (Quebec)",
preposition = "bagi",
fallback = "municipality",
has_neighborhoods = true, --?
},
["voivodeship"] = {
-- Poland
link = true,
display_handler = voivodeship_display_handler,
preposition = "bagi",
class = "subtatanegara",
},
["volcano"] = {
link = true,
plural = "volcanoes",
class = "sifat semula jadi",
addl_bare_category_parents = {"bentuk muka bumi"},
default = {true, "Mountains"},
},
["ward"] = {
link = true,
class = "petempatan",
-- Wards are formal administrative divisions of a city but have some properties of neighborhoods.
fallback = "neighborhood",
},
["watercourse"] = {
link = true,
fallback = "channel",
},
["Welsh community"] = {
-- Wales
link = "[[w:community (Wales)|community]]",
preposition = "bagi",
affix_type = "suf",
affix = "community",
has_neighborhoods = true,
class = "petempatan",
},
["zone"] = {
-- administrative division of Ethiopia, Qatar, Nepal, India
link = "+w:zone#Place names",
preposition = "bagi",
class = "subtatanegara",
},
----------------------------------------------------------------------------------------------
-- Categories for former places --
----------------------------------------------------------------------------------------------
["ANCIENT capital"] = {
link = false,
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
-- FIXME: Consider removing 'ancient settlements' here. Ancient capitals, like former capitals, often still
-- exist but just aren't the capital any more. Maybe we should have an 'Ancient capitals' category.
default = {"Ancient settlements", "Former capitals"},
},
["ANCIENT non-admin settlement"] = {
link = false,
class = "non-admin settlement",
fallback = "ANCIENT petempatan",
},
["ANCIENT petempatan"] = {
link = false,
has_neighborhoods = true,
class = "petempatan",
default = {"Ancient settlements"},
},
["ancient settlements!"] = {
category_link = "former [[city|cities]], [[town]]s and [[village]]s that existed in [[antiquity]]",
bare_category_parent = "former settlements",
},
["FORMER capital"] = {
link = false,
entry_placetype_use_the = true,
preposition = "bagi",
has_neighborhoods = true,
class = "capital",
default = {"Former capitals"},
},
["former capitals!"] = {
category_link = "former [[capital]] [[city|cities]] and [[town]]s",
bare_category_parent = "settlements",
},
["former counties and county-level cities!"] = {
-- For categorizing former counties and county-level cities of China
category_link = "no-longer existing [[county|counties]] and [[county-level city|county-level cities]]",
bare_category_breadcrumb = "counties and county-level cities",
bare_category_parent = "former political divisions",
},
["FORMER kaunti"] = {
-- For categorizing former counties and county-level cities of China
link = false,
fallback = "FORMER subtatanegara",
},
["FORMER county-level city"] = {
-- For categorizing former counties and county-level cities of China
link = false,
fallback = "FORMER subtatanegara",
},
["former countries and country-like entities!"] = {
category_link = "[[country|countries]] and similar [[polity|polities]] that no longer exist",
bare_category_breadcrumb = "countries and country-like entities",
bare_category_parent = "former polities",
},
["FORMER negara"] = {
link = false,
class = "tatanegara",
default = {"Former countries and country-like entities"},
},
["former dependent territories!"] = {
category_link = "[[w:dependent territory|dependent territories]] (colonies, dependencies, protectorates, etc.) that no longer exist",
bare_category_breadcrumb = "dependent territories",
bare_category_parent = "former political divisions",
},
["FORMER dependent territory"] = {
link = false,
preposition = "bagi",
class = "subtatanegara",
default = {"Former dependent territories"},
},
["bekas daerah!"] = {
-- For categorizing former districts of China
category_link = "no-longer-existing [[district]]s",
bare_category_breadcrumb = "daerah",
bare_category_parent = "former political divisions",
},
["FORMER daerah"] = {
-- For categorizing former districts of China
link = false,
fallback = "FORMER subtatanegara",
},
["FORMER kawasan geografi"] = {
link = false,
fallback = "kawasan geografi dan budaya",
},
["FORMER man-made structure"] = {
link = false,
class = "man-made structure",
default = {"Former man-made structures"},
},
["former man-made structures!"] = {
category_link = "man-made structures such as [[airport]]s and [[park]]s that no longer exist",
bare_category_breadcrumb = "man-made structures",
bare_category_parent = "former places",
},
["former municipalities!"] = {
-- For categorizing former municipalities of the Netherlands
category_link = "no-longer-existing [[municipality|municipalities]]",
bare_category_breadcrumb = "municipalities",
bare_category_parent = "former political divisions",
},
["FORMER municipality"] = {
-- For categorizing former municipalities of the Netherlands
link = false,
fallback = "FORMER subtatanegara",
},
["FORMER sifat semula jadi"] = {
link = false,
class = "sifat semula jadi",
default = {"Former natural features"},
},
["former natural features!"] = {
category_link = "sifat semula jadi seperti [[tasik]], [[sungai]] dan [[pulau]] yang tidak lagi wujud",
bare_category_breadcrumb = "sifat semula jadi",
bare_category_parent = "former places",
},
["FORMER non-admin settlement"] = {
link = false,
class = "non-admin settlement",
fallback = "FORMER petempatan",
},
["former places!"] = {
category_link = "[[place]]s of all sorts that no longer exist",
bare_category_breadcrumb = "former",
bare_category_parent = "tempat",
},
["former political divisions!"] = {
category_link = "[[political]] [[division]]s (states, provinces, counties, etc.) that no longer exist",
bare_category_breadcrumb = "pembahagian politik",
bare_category_parent = "former places",
},
["former polities!"] = {
category_link = "[[polity|polities]] (countries, kingdoms, empires, etc.) that no longer exist",
bare_category_breadcrumb = "polities",
bare_category_parent = "former places",
},
["FORMER tatanegara"] = {
link = false,
class = "tatanegara",
default = {"Former polities"},
},
["former prefectures!"] = {
-- For categorizing former prefectures of China
category_link = "no-longer-existing [[prefecture]]s",
bare_category_breadcrumb = "prefectures",
bare_category_parent = "former political divisions",
},
["FORMER prefecture"] = {
-- For categorizing former prefectures of China
link = false,
fallback = "FORMER subtatanegara",
},
["former provinces!"] = {
-- For categorizing former provinces of China, etc.
category_link = "no-longer-existing [[province]]s",
bare_category_breadcrumb = "provinces",
bare_category_parent = "former political divisions",
},
["FORMER province"] = {
-- For categorizing ancient/historical/former provinces of the Roman Empire
link = false,
fallback = "FORMER subtatanegara",
},
["former region"] = {
-- A former region is considered a former political division, but not a 'historical/traditional/etc.' region.
link = "separately",
preposition = "bagi",
inherently_former = {"FORMER"},
class = "subtatanegara",
},
["FORMER petempatan"] = {
link = false,
has_neighborhoods = true,
class = "petempatan",
default = {"Former settlements"},
},
["former settlements!"] = {
category_link = "[[city|cities]], [[town]]s and [[village]]s that no longer exist or have been merged or reclassified",
bare_category_breadcrumb = "settlements",
bare_category_parent = "former political divisions",
},
["FORMER subtatanegara"] = {
link = false,
preposition = "bagi",
class = "subtatanegara",
default = {"Former political divisions"},
},
----------------------------------------------------------------------------------------------
-- form-of categories --
----------------------------------------------------------------------------------------------
---------- Abbreviations ----------
["abbreviations of counties!"] = {
-- For categorizing abbreviations of counties of e.g. England
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[county|counties]]",
bare_category_breadcrumb = "kaunti",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of countries!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "abbreviations of places",
},
["abbreviations of departments!"] = {
-- For categorizing abbreviations of departments of e.g. France
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[department]]s",
bare_category_breadcrumb = "departments",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of districts!"] = {
-- For categorizing abbreviations of districts of e.g. ???
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[district]]s",
bare_category_breadcrumb = "daerah",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of divisions!"] = {
-- For categorizing abbreviations of divisions of e.g. Bangladesh
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[division]]s",
bare_category_breadcrumb = "divisions",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of former countries!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[country|countries]] that no longer [[exist]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "abbreviations of former places",
},
["abbreviations of former places!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[place]]s that no longer [[exist]]",
bare_category_breadcrumb = "abbreviations",
bare_category_parent = "former places",
addl_bare_category_parents = {{name = "abbreviations of places", sort = "former"}},
},
["abbreviations of places!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[place]]s",
bare_category_breadcrumb = "abbreviations",
bare_category_parent = "tempat",
},
["abbreviations of political divisions!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[political]] [[division]]s",
bare_category_breadcrumb = "pembahagian politik",
bare_category_parent = "abbreviations of places",
},
["abbreviations of prefectures!"] = {
-- For categorizing abbreviations of prefectures of e.g. Japan
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[prefecture]]s",
bare_category_breadcrumb = "prefectures",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of provinces!"] = {
-- For categorizing abbreviations of provinces of e.g. Canada
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[province]]s",
bare_category_breadcrumb = "provinces",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of provinces and territories!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[province]]s and [[territory|territories]]",
bare_category_breadcrumb = "provinces and territories",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of regions!"] = {
-- For categorizing abbreviations of regions of e.g. Italy
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[administrative region]]s",
bare_category_breadcrumb = "wilayah",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of states!"] = {
-- For categorizing abbreviations of states of e.g. the United States
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[state]]s",
bare_category_breadcrumb = "negeri",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of states and territories!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[state]]s and [[territory|territories]]",
bare_category_breadcrumb = "states and territories",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of states and union territories!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[state]]s and [[union territory|union territories]]",
bare_category_breadcrumb = "states and union territories",
bare_category_parent = "abbreviations of political divisions",
},
["abbreviations of territories!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[territory|territories]]",
bare_category_breadcrumb = "territories",
bare_category_parent = "abbreviations of political divisions",
},
["ABBREVIATION_OF barangay"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF negara"] = {
link = false,
default = {"Abbreviations of countries"},
},
["ABBREVIATION_OF kaunti"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF department"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF daerah"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF division"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF FORMER negara"] = {
link = false,
default = {"Abbreviations of former countries"},
},
["ABBREVIATION_OF FORMER place"] = {
link = false,
default = {"Abbreviations of former places"},
},
["ABBREVIATION_OF place"] = {
link = false,
default = {"Abbreviations of places"},
},
["ABBREVIATION_OF prefecture"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF province"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF wilayah"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF negeri"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF subtatanegara"] = {
link = false,
default = {"Abbreviations of political divisions"},
},
["ABBREVIATION_OF territory"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
["ABBREVIATION_OF union territory"] = {
link = false,
fallback = "ABBREVIATION_OF subtatanegara",
},
---------- Archaic forms ----------
["archaic forms of places!"] = {
full_category_link = "{{glossary|archaic}} [[form]]s of [[name]]s of [[place]]s",
bare_category_breadcrumb = "archaic forms",
bare_category_parent = "tempat",
},
["ARCHAIC_FORM_OF place"] = {
link = false,
default = {"Archaic forms of places"},
},
---------- Clippings ----------
["clippings of places!"] = {
full_category_link = "{{glossary|clipping}}s of [[name]]s of [[place]]s",
bare_category_breadcrumb = "clippings",
bare_category_parent = "tempat",
},
["CLIPPING_OF place"] = {
link = false,
default = {"Clippings of places"},
},
---------- Dated forms ----------
["dated forms of places!"] = {
full_category_link = "{{glossary|dated}} [[form]]s of [[name]]s of [[place]]s",
bare_category_breadcrumb = "dated forms",
bare_category_parent = "tempat",
},
["DATED_FORM_OF place"] = {
link = false,
default = {"Dated forms of places"},
},
---------- Derogatory names ----------
["derogatory names for cities!"] = {
full_category_link = "{{glossary|derogatory}} [[name]]s for [[city|cities]]",
bare_category_breadcrumb = "cities",
bare_category_parent = "derogatory names for places",
addl_bare_category_parents = {"nicknames for cities"},
},
["derogatory names for continents!"] = {
full_category_link = "{{glossary|derogatory}} [[name]]s for [[continent]]s",
bare_category_breadcrumb = "continents",
bare_category_parent = "derogatory names for places",
addl_bare_category_parents = {"nicknames for continents"},
},
["derogatory names for countries!"] = {
full_category_link = "{{glossary|derogatory}} [[name]]s for [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "derogatory names for places",
addl_bare_category_parents = {"nicknames for countries"},
},
["derogatory names for places!"] = {
full_category_link = "{{glossary|derogatory}} [[name]]s for [[place]]s",
bare_category_breadcrumb = "derogatory names",
bare_category_parent = "nicknames for places",
},
["derogatory names for states!"] = {
full_category_link = "{{glossary|derogatory}} [[name]]s for [[state]]s",
bare_category_breadcrumb = "negeri",
bare_category_parent = "derogatory names for places",
addl_bare_category_parents = {"nicknames for states"},
},
["DEROGATORY_NAME_FOR capital"] = {
link = false,
default = {"Derogatory names for cities"},
},
["DEROGATORY_NAME_FOR city"] = {
link = false,
default = {"Derogatory names for cities"},
},
["DEROGATORY_NAME_FOR continent"] = {
link = false,
default = {"Derogatory names for continents"},
},
["DEROGATORY_NAME_FOR country"] = {
link = false,
default = {"Derogatory names for countries"},
},
["DEROGATORY_NAME_FOR metropolitan city"] = {
-- "metropolitan city" doesn't fall back to "bandar"
link = false,
default = {"Derogatory names for cities"},
},
["DEROGATORY_NAME_FOR place"] = {
link = false,
default = {"Derogatory names for places"},
},
["DEROGATORY_NAME_FOR prefecture-level city"] = {
-- "prefecture-level city" doesn't fall back to "bandar" but things like "county-level city" and
-- "subprovincial city" fall back to "prefecture-level city"
link = false,
default = {"Derogatory names for cities"},
},
["DEROGATORY_NAME_FOR state"] = {
link = false,
default = {"Derogatory names for states"},
},
["DEROGATORY_NAME_FOR town"] = {
link = false,
default = {"Derogatory names for cities"},
},
---------- Ellipses ----------
["ellipses of places!"] = {
full_category_link = "{{glossary|ellipsis|ellipses}} of [[name]]s of [[place]]s",
bare_category_breadcrumb = "ellipses",
bare_category_parent = "tempat",
},
["ELLIPSIS_OF place"] = {
link = false,
default = {"Ellipses of places"},
},
---------- Former long-form names ----------
["former long-form names of countries!"] = {
full_category_link = "no-longer-[[use]]d [[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "former long-form names of places",
addl_bare_category_parents = {{name = "former names of countries", sort = "long-form"}},
},
["former long-form names of places!"] = {
full_category_link = "no-longer-[[use]]d [[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[place]]s",
bare_category_breadcrumb = "long-form",
bare_category_parent = "former names of places",
},
["FORMER_LONG_FORM_OF country"] = {
link = false,
default = {"Former long-form names of countries"},
},
["FORMER_LONG_FORM_OF place"] = {
link = false,
default = {"Former long-form names of places"},
},
---------- Former names ----------
["former names of capitals!"] = {
full_category_link = "[[former]] [[name]]s of [[capital city|capital cities]] that generally still exist but under a different name",
bare_category_breadcrumb = "capitals",
bare_category_parent = "former names of settlements",
},
["former names of countries!"] = {
full_category_link = "[[former]] [[name]]s of [[country|countries]] that generally still exist but under a different name",
bare_category_breadcrumb = "countries",
bare_category_parent = "former names of places",
},
["former names of places!"] = {
full_category_link = "[[former]] [[name]]s of [[place]]s that generally still exist but under a different name",
bare_category_breadcrumb = "former names",
bare_category_parent = "tempat",
},
["former names of political divisions!"] = {
full_category_link = "[[former]] [[name]]s of [[political]] [[division]]s (states, provinces, counties, etc.) that generally still exist but under a different name",
bare_category_breadcrumb = "pembahagian politik",
bare_category_parent = "former names of places",
},
["former names of polities!"] = {
full_category_link = "[[former]] [[name]]s of [[polity|polities]] (e.g. [[country|countries]]) that generally still exist but under a different name",
bare_category_breadcrumb = "polities",
bare_category_parent = "former names of places",
},
["former names of settlements!"] = {
full_category_link = "[[former]] [[name]]s of [[city|cities]], [[town]]s, [[village]]s, etc. that generally still exist but under a different name",
bare_category_breadcrumb = "settlements",
bare_category_parent = "former names of political divisions",
},
["FORMER_NAME_OF capital"] = {
link = false,
default = {"Former names of capitals"},
},
["FORMER_NAME_OF negara"] = {
link = false,
default = {"Former names of countries"},
},
["FORMER_NAME_OF place"] = {
link = false,
default = {"Former names of places"},
},
["FORMER_NAME_OF tatanegara"] = {
link = false,
default = {"Former names of polities"},
},
["FORMER_NAME_OF wilayah"] = {
link = false,
fallback = "FORMER_NAME_OF subtatanegara",
},
["FORMER_NAME_OF petempatan"] = {
link = false,
default = {"Former names of settlements"},
},
["FORMER_NAME_OF subtatanegara"] = {
link = false,
default = {"Former names of political divisions"},
},
---------- Former nicknames ----------
["former nicknames for cities!"] = {
full_category_link = "no-longer-used [[nickname]]s for [[city|cities]], e.g. the [[Eternal City]] for [[Kyoto]] during the {{w|Heian period}} ({{circa2|800–1100|short=yes}} {{AD}})",
bare_category_breadcrumb = "cities",
bare_category_parent = "former nicknames for places",
addl_bare_category_parents = {"nicknames for cities"},
},
["former nicknames for places!"] = {
full_category_link = "no-longer-used [[nickname]]s for [[place]]s",
bare_category_breadcrumb = "former",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {{name = "former names of places", sort = "nicknames"}},
},
["FORMER_NICKNAME_FOR capital"] = {
link = false,
default = {"Former nicknames for cities"},
},
["FORMER_NICKNAME_FOR city"] = {
link = false,
default = {"Former nicknames for cities"},
},
["FORMER_NICKNAME_FOR metropolitan city"] = {
-- "metropolitan city" doesn't fall back to "bandar"
link = false,
default = {"Former nicknames for cities"},
},
["FORMER_NICKNAME_FOR place"] = {
link = false,
default = {"Former nicknames for places"},
},
["FORMER_NICKNAME_FOR prefecture-level city"] = {
-- "prefecture-level city" doesn't fall back to "bandar" but things like "county-level city" and
-- "subprovincial city" fall back to "prefecture-level city"
link = false,
default = {"Former nicknames for cities"},
},
["FORMER_NICKNAME_FOR town"] = {
link = false,
default = {"Former nicknames for cities"},
},
---------- Former official names ----------
["former official names of countries!"] = {
full_category_link = "no-longer-[[use]]d [[official]] [[name]]s of [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "former official names of places",
addl_bare_category_parents = {{name = "former names of countries", sort = "official"}},
},
["former official names of places!"] = {
full_category_link = "no-longer-[[use]]d [[official]] [[name]]s of [[place]]s",
bare_category_breadcrumb = "official",
bare_category_parent = "former names of places",
},
["FORMER_OFFICIAL_NAME_OF country"] = {
link = false,
default = {"Former official names of countries"},
},
["FORMER_OFFICIAL_NAME_OF place"] = {
link = false,
default = {"Former official names of places"},
},
---------- Long-form names ----------
["long-form names of countries!"] = {
full_category_link = "[[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "long-form names of places",
},
["long-form names of places!"] = {
full_category_link = "[[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[place]]s",
bare_category_breadcrumb = "long-form names",
bare_category_parent = "tempat",
},
["LONG_FORM_OF country"] = {
link = false,
default = {"Long-form names of countries"},
},
["LONG_FORM_OF place"] = {
link = false,
default = {"Long-form names of places"},
},
---------- Nicknames ----------
["nicknames for cities!"] = {
full_category_link = "[[nickname]]s for [[city|cities]], e.g. the [[Big Apple]] for [[New York City]]",
bare_category_breadcrumb = "cities",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"cities"},
},
["nicknames for continents!"] = {
full_category_link = "[[nickname]]s for [[continent]]s",
bare_category_breadcrumb = "continents",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"continents"},
},
["nicknames for countries!"] = {
full_category_link = "[[nickname]]s for [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"countries"},
},
["nicknames for places!"] = {
full_category_link = "[[nickname]]s for [[place]]s",
bare_category_breadcrumb = "tempat",
bare_category_parent = "nicknames",
addl_bare_category_parents = {"tempat"},
},
["nicknames for states!"] = {
-- For categorizing nicknames for states of e.g. the United States
full_category_link = "[[nicknames]] for [[state]]s",
bare_category_breadcrumb = "negeri",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"negeri"},
},
["NICKNAME_FOR capital"] = {
link = false,
default = {"Nicknames for cities"},
},
["NICKNAME_FOR city"] = {
link = false,
default = {"Nicknames for cities"},
},
["NICKNAME_FOR continent"] = {
link = false,
default = {"Nicknames for continents"},
},
["NICKNAME_FOR country"] = {
link = false,
default = {"Nicknames for countries"},
},
["NICKNAME_FOR metropolitan city"] = {
-- "metropolitan city" doesn't fall back to "bandar"
link = false,
default = {"Nicknames for cities"},
},
["NICKNAME_FOR place"] = {
link = false,
default = {"Nicknames for places"},
},
["NICKNAME_FOR prefecture-level city"] = {
-- "prefecture-level city" doesn't fall back to "bandar" but things like "county-level city" and
-- "subprovincial city" fall back to "prefecture-level city"
link = false,
default = {"Nicknames for cities"},
},
["NICKNAME_FOR state"] = {
link = false,
default = {"Nicknames for states"},
},
["NICKNAME_FOR town"] = {
link = false,
default = {"Nicknames for cities"},
},
---------- Obsolete forms ----------
["obsolete forms of places!"] = {
full_category_link = "{{glossary|obsolete}} [[form]]s of [[name]]s of [[place]]s",
bare_category_breadcrumb = "obsolete forms",
bare_category_parent = "tempat",
},
["OBSOLETE_FORM_OF place"] = {
link = false,
default = {"Obsolete forms of places"},
},
---------- Official names ----------
["official names of countries!"] = {
full_category_link = "[[official]] [[name]]s of [[country|countries]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "official names of places",
},
["official names of former countries!"] = {
full_category_link = "[[official]] [[name]]s of [[country|countries]] that no longer [[exist]]",
bare_category_breadcrumb = "countries",
bare_category_parent = "official names of former places",
},
["official names of former places!"] = {
full_category_link = "[[official]] [[name]]s of [[place]]s that no longer [[exist]]",
bare_category_breadcrumb = "official names",
bare_category_parent = "former places",
addl_bare_category_parents = {{name = "official names of places", sort = "former"}},
},
["official names of places!"] = {
full_category_link = "[[official]] [[name]]s of [[place]]s",
bare_category_breadcrumb = "official names",
bare_category_parent = "tempat",
},
["OFFICIAL_NAME_OF negara"] = {
link = false,
default = {"Official names of countries"},
},
["OFFICIAL_NAME_OF FORMER negara"] = {
link = false,
default = {"Official names of former countries"},
},
["OFFICIAL_NAME_OF FORMER place"] = {
link = false,
default = {"Official names of former places"},
},
["OFFICIAL_NAME_OF place"] = {
link = false,
default = {"Official names of places"},
},
---------- Official nicknames ----------
["official nicknames for places!"] = {
full_category_link = "[[official]] [[nickname]]s for [[place]]s",
bare_category_breadcrumb = "official",
bare_category_parent = "nicknames for places",
},
["official nicknames for states!"] = {
-- For categorizing official nicknames for states of e.g. the United States
full_category_link = "[[official]] [[nicknames]] for [[state]]s",
bare_category_breadcrumb = "official",
bare_category_parent = "nicknames for states",
addl_bare_category_parents = {"negeri"},
},
["OFFICIAL_NICKNAME_FOR place"] = {
link = false,
default = {"Official nicknames for places"},
},
["OFFICIAL_NICKNAME_FOR state"] = {
link = false,
default = {"Official nicknames for states"},
},
}
export.plural_placetype_to_singular = {}
for sg_placetype, spec in pairs(export.placetype_data) do
if spec.plural then
export.plural_placetype_to_singular[spec.plural] = sg_placetype
end
end
return export
svhpgqszk8fg51cpkwzfe7c2txgbmb1
Modul:etymon/categories
828
82358
375913
375784
2026-09-26T07:48:29Z
Hakimi97
2668
Halaman > Laman
375913
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
etymology = "Module:etymology",
affix = "Module:affix",
etymology_specialized = "Module:etymology/specialized",
utilities = "Module:utilities",
roots = "Module:roots",
},
loadData = {
data = "Module:etymon/data",
},
})
-- Fungsi utiliti untuk huruf besar
local function ucfirst(text)
if not text then return text end
return mw.ustring.upper(mw.ustring.sub(text, 1, 1)) .. mw.ustring.sub(text, 2)
end
-- Nilaikan sama ada kata kunci adalah transitif bagi sesuatu istilah
local function is_transitive(transitive_mode, page_lang, term_lang)
if transitive_mode == M.data.TRANSITIVE.ALWAYS then
return true
elseif transitive_mode == M.data.TRANSITIVE.NEVER then
return false
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then
return page_lang:getCode() ~= term_lang:getCode()
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
return page_lang:getCode() ~= term_lang:getCode()
end
error("Mod transitif tidak diketahui: " .. tostring(transitive_mode))
end
-- Dapatkan konfigurasi kata kunci dengan pengesampingan khusus bahasa
local function get_keyword_config(keyword, lang_exc)
local base_config = M.data.keywords[keyword]
if not base_config then
return nil -- Kata kunci tidak sah
end
local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword]
if not overrides then
return base_config
end
-- Gabungkan pengesampingan ke dalam konfigurasi asas
local merged = {}
for k, v in pairs(base_config) do
merged[k] = v
end
for k, v in pairs(overrides) do
merged[k] = v
end
return merged
end
function export.get_cat_name(source)
local _, cat_name = M.etymology.get_display_and_cat_name(source, true)
return cat_name
end
-- Normalkan alias jenis imbuhan
local aftype_aliases = {
["pre"] = "awalan",
["suf"] = "akhiran",
["in"] = "infix",
["inter"] = "interfix",
["circum"] = "circumfix",
["naf"] = "non-affix",
["root"] = "non-affix",
}
local function add_category(categories, cat_name, sort_key, sort_base)
if categories[cat_name] == nil then
categories[cat_name] = {
sort_key = sort_key,
sort_base = sort_base,
}
return
end
local existing = categories[cat_name]
if existing.sort_key == nil and sort_key ~= nil then
existing.sort_key = sort_key
end
if existing.sort_base == nil and sort_base ~= nil then
existing.sort_base = sort_base
end
end
-- Kumpulkan kategori imbuhan daripada bekas kumpulan peringkat atas
local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
local parts = {}
local part_index = 1
for _, container in ipairs(node.children or {}) do
local config = container.keyword_info
if config and config.affix_categories then
for _, term in ipairs(container.terms or {}) do
if not term.unknown_term then
local part_data = {
term = term.title,
tr = term.tr,
ts = term.ts,
alt = term.alt,
itemno = part_index,
orig_index = part_index
}
-- Tentukan jenis imbuhan: aftype tersurat > pos=root > auto-kesan
local aftype = term.aftype
if aftype then
aftype = aftype_aliases[aftype] or aftype
part_data.type = aftype
elseif term.args and term.args.pos and term.args.pos == "root" then
part_data.type = "non-affix"
end
if term.lang:getCode() ~= page_lang:getCode() then
part_data.lang = term.lang
end
local target_ids = available_etymon_ids[term.target_key]
local has_multiple_ids = target_ids and #target_ids > 1
local id_exists_in_disambiguation = false
local matched_id = nil
-- Hitung senseid yang tersedia untuk laman sasaran
local senseid_count = 0
local target_prefix = term.target_key .. ":"
if senseid_parent_etymon then
for key, _ in pairs(senseid_parent_etymon) do
if key:sub(1, #target_prefix) == target_prefix then
senseid_count = senseid_count + 1
end
end
end
local has_multiple_senseids = senseid_count > 1
if term.id then
-- Periksa jika pengguna menyediakan senseid yang sah
local senseid_key = term.target_key .. ":" .. term.id
if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then
if has_multiple_senseids then
-- senseid kabur: gunakan senseid
matched_id = term.id
id_exists_in_disambiguation = true
elseif has_multiple_ids then
-- senseid unik tetapi etimon kabur: gunakan ID etimon
matched_id = term.etymon_id or term.id
id_exists_in_disambiguation = true
end
else
-- Periksa jika pengguna menyediakan ID etimon yang sah
if has_multiple_ids and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.id then
-- Etimon kabur: gunakan ID etimon
id_exists_in_disambiguation = true
matched_id = term.id
break
end
end
end
-- Sandaran: periksa etymon_id yang diselesaikan (cth. daripada langkah-langkah sebelumnya)
if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.etymon_id then
id_exists_in_disambiguation = true
matched_id = term.etymon_id
break
end
end
end
end
end
-- Gunakan ID yang sepadan jika dijumpai
if term.override or id_exists_in_disambiguation then
part_data.id = matched_id or term.id
end
table.insert(parts, part_data)
part_index = part_index + 1
end
end
end
end
if #parts == 0 then return {} end
local affix_data = {
lang = page_lang,
parts = parts,
pos = "perkataan",
sort_key = nil,
}
if #parts == 1 then
affix_data.allow_no_affixes_or_compounds = true
end
local affix_categories = M.affix.get_affix_categories_only(affix_data)
local result = {}
for _, cat in ipairs(affix_categories) do
if type(cat) == "table" then
table.insert(result, { cat = cat.cat, sort_key = cat.sort_key, sort_base = cat.sort_base })
else
table.insert(result, { cat = cat })
end
end
return result
end
local function lang_is_source(page_lang, source)
return page_lang:getCode() == source:getCode() or page_lang:hasParent(source)
end
local function is_borrowing_keyword_config(config)
return config and (config.borrowing_type or config.specialized_borrowing)
end
local function add_reborrow_category(categories, page_lang)
local lang_name = page_lang:getFullName()
add_category(categories, "Perkataan " .. lang_name .. " yang dipinjam kembali ke dalam " .. lang_name)
end
local function borrow_returns_to_page_lang(page_lang, source, in_foreign_branch)
if not in_foreign_branch then
return false
end
if source:getFullCode() == page_lang:getFullCode() then
return true
end
return page_lang:hasParent(source)
end
local function node_borrows_from_lang(node, page_lang, visited, in_foreign_branch)
visited = visited or {}
if not node or visited[node] then
return false
end
visited[node] = true
if node.is_duplicate then
if node.duplicate_of then
return node_borrows_from_lang(node.duplicate_of, page_lang, visited, in_foreign_branch)
end
return false
end
local node_is_foreign = in_foreign_branch
or (node.lang and node.lang:getFullCode() ~= page_lang:getFullCode())
for _, container in ipairs(node.children or {}) do
if is_borrowing_keyword_config(container.keyword_info) then
for _, child_term in ipairs(container.terms or {}) do
if borrow_returns_to_page_lang(page_lang, child_term.lang, node_is_foreign) then
return true
end
end
end
for _, child_term in ipairs(container.terms or {}) do
if child_term.status == M.data.STATUS.OK or child_term.status == M.data.STATUS.INLINE then
if node_borrows_from_lang(child_term, page_lang, visited, node_is_foreign) then
return true
end
end
end
end
return false
end
local function should_add_reborrow_category(page_lang, term)
if page_lang:getCode() == term.lang:getCode() then
return false
end
if term.status ~= M.data.STATUS.OK and term.status ~= M.data.STATUS.INLINE then
return false
end
return node_borrows_from_lang(term, page_lang, {}, false)
end
-- Tambah kategori berkaitan peminjaman (peringkat atas sahaja)
local function collect_borrowing_categories(categories, page_lang, term, config, check_reborrow_path)
if check_reborrow_path and should_add_reborrow_category(page_lang, term) then
add_reborrow_category(categories, page_lang)
end
if config.borrowing_type == "borrowed" and not lang_is_source(page_lang, term.lang) then
local temp_categories = {}
M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang)
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
if config.specialized_borrowing and not lang_is_source(page_lang, term.lang) then
local result = M.etymology_specialized.specialized_borrowing {
bortype = config.specialized_borrowing,
lang = page_lang,
sources = { term.lang },
terms = { { lang = term.lang, term = "-" } },
notext = true,
nocat = false,
}
for cat_name in result:gmatch("%[%[Category:([^%]]+)%]%]") do
add_category(categories, cat_name)
end
end
end
-- Tambah kategori terbitan berasaskan sumber (peringkat atas sahaja)
local function collect_source_derivation_categories(categories, page_lang, term, config)
if not config.source_category_type then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = config.source_category_type,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
-- Tambah kategori bahasa sumber
local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func)
if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
if chain.inherited then
temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = "terms inherited",
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
end
-- Tambah kategori akar/perkataan
local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain,
get_norm_lang_func, lang_exc, keyword)
local pos_types = { root = "akar", word = "perkataan" }
-- Tentukan pos: daripada postype istilah, pos_override kata kunci, atau args.pos
local pos
local config = get_keyword_config(keyword, lang_exc)
if term.postype then
-- Pengubahsuai postype peringkat istilah mengambil keutamaan tertinggi
pos = term.postype
elseif config and config.pos_override then
pos = config.pos_override
elseif type(term.args) == "table" and term.args.pos then
pos = term.args.pos
end
local pos_type = pos_types[pos]
if not pos_type or term.unknown_term then
return
end
-- Langkau kategori akar/perkataan untuk keturunan kumpulan imbuhan
-- if pos_type then
-- return
-- end
local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode()
-- Langkau rujukan kendiri
if same_language and root_title == term.title then
return
end
local entry_name
if pos_type == "akar" then
entry_name = term.title
M.roots.assert_root(term.lang, entry_name)
else
entry_name = term.lang:makeEntryName(term.title)
end
local lang_name = page_lang:getCanonicalName()
local cat_name
if chain.passed_through then
local etymon_lang_name = export.get_cat_name(term.lang)
cat_name = "Perkataan " .. lang_name .. " yang diterbitkan daripada " .. pos_type .. " " .. etymon_lang_name .. " " .. entry_name
else
cat_name = "Perkataan " .. lang_name .. " yang tergolong dalam " .. pos_type .. " " .. entry_name
end
-- Tambah penyahkaburan ID jika perlu (untuk akar/perkataan: gunakan etymon_id jika diselesaikan melalui senseid, jika tidak gunakan id)
local target_ids = available_etymon_ids[term.target_key]
local effective_id = term.etymon_id or term.id -- etymon_id jika senseid, jika tidak id sudah pun merupakan id etimon
if target_ids and effective_id then
local same_pos_count = 0
for _, id_data in ipairs(target_ids) do
if type(id_data) == "table" and id_data.pos == pos then
same_pos_count = same_pos_count + 1
end
end
if same_pos_count > 1 then
cat_name = cat_name .. " (" .. effective_id .. ")"
end
end
add_category(categories, cat_name)
end
-- Hitung keadaan rantaian untuk suatu istilah berdasarkan rantaian induk dan konfigurasi kata kunci
-- Corak sengkang untuk pengesanan imbuhan (sengkang biasa + khusus skrip)
local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- sengkang biasa, maqqef Ibrani, tatweel Arab, sengkang Mongolia
-- Periksa jika suatu istilah merupakan imbuhan sebenar (bukan ahli bukan imbuhan dalam kumpulan imbuhan)
local function is_actual_affix(term)
-- Periksa pengubahsuai aftype tersurat
if term.aftype then
local normalized = aftype_aliases[term.aftype] or term.aftype
return normalized ~= "non-affix"
end
-- Periksa jika pos=root (dilayan sebagai bukan imbuhan)
if term.args and term.args.pos and term.args.pos == "root" then
return false
end
-- Auto-kesan menggunakan sengkang: awalan berakhir dengan -, akhiran bermula dengan -, dsb.
if term.title then
local title = term.title
-- Tanggalkan * di hadapan untuk istilah yang direkonstruksi sebelum memeriksa sengkang
title = title:gsub("^%*", "")
-- Periksa sengkang di awal atau akhir (mengendalikan sengkang khusus skrip juga)
if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then
return true
end
end
-- Lalai: bukan imbuhan
return false
end
local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term)
-- Jejak jika kita berada di dalam imbuhan sebenar (untuk menindas kategori akar pada keturunan)
-- Hanya tetapkan jika istilah tersebut merupakan imbuhan sebenar (awalan, akhiran, dsb.), bukan ahli bukan imbuhan
local inside_affix = parent_chain.inside_affix
if config.affix_categories and term and is_actual_affix(term) then
inside_affix = true
end
-- Jika no_child_categories ditetapkan, lumpuhkan semuanya
if config.no_child_categories then
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = false,
source = false,
pos = false,
recurse = false,
inside_affix = inside_affix,
}
end
local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang)
local new_source = parent_chain.source and term_is_transitive
-- Untuk CROSS_LANG_NO_INTERNAL_SOURCE: jejak konteks bahasa terbitan dalaman
-- Periksa jika istilah ini adalah dalaman secara relatif terhadap bahasa istilah induk (jika parent_term_lang disediakan)
-- atau secara relatif terhadap bahasa laman (jika tiada parent_term_lang)
local internal_lang = parent_chain.internal_lang
local is_internal_in_context = false
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
local check_lang = parent_term_lang or page_lang
local term_lang_code = get_norm_lang_func(term_lang):getCode()
local check_lang_code = get_norm_lang_func(check_lang):getCode()
if internal_lang then
-- Sudah berada dalam konteks terbitan dalaman: periksa jika istilah ini juga dalaman
is_internal_in_context = term_lang_code == internal_lang
else
-- Periksa jika istilah ini adalah dalaman secara relatif terhadap istilah induk (atau laman jika tiada induk)
is_internal_in_context = term_lang_code == check_lang_code
end
end
-- Tingkah laku rantaian sumber untuk CROSS_LANG_NO_INTERNAL_SOURCE
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
if is_internal_in_context then
-- Terbitan dalaman
new_source = false
internal_lang = get_norm_lang_func(term_lang):getCode()
else
-- Merentas bahasa
new_source = parent_chain.source and term_is_transitive
internal_lang = nil
end
end
local new_pos = parent_chain.pos
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = parent_chain.inherited and config.inherited_chain,
source = new_source,
pos = new_pos,
internal_lang = internal_lang,
recurse = new_source or new_pos,
inside_affix = inside_affix,
}
end
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local page_lang = opts.page_lang
local available_etymon_ids = opts.available_etymon_ids
local senseid_parent_etymon = opts.senseid_parent_etymon
local get_norm_lang_func = opts.get_norm_lang_func
local lang_exc = opts.lang_exc
local categories = {}
local seen = {}
local lang_name = page_lang:getCanonicalName()
local root_title = data_tree.title
-- Kumpulkan pepohon secara rekursif
local function collect(node, parent_chain, is_toplevel)
-- Elakkan memproses nod yang sama dua kali
if not node.unknown_term and node.title then
local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "")
if seen[key] then return end
seen[key] = true
end
-- Kumpulkan kategori imbuhan pada peringkat atas sahaja
if is_toplevel then
local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
for _, cat in ipairs(affix_cats) do
-- Buang cantuman "lang_name" dari sini kerana Modul:affix sudah menjana nama bahasa yang lengkap
add_category(categories, cat.cat, cat.sort_key, cat.sort_base)
end
if node.supplements then
for _, supplement in ipairs(node.supplements) do
local config = supplement.config
if config and config.toplevel_category then
add_category(categories, ucfirst(config.toplevel_category) .. " bahasa " .. lang_name)
end
end
end
end
-- Proses setiap bekas
for _, container in ipairs(node.children or {}) do
local keyword = container.keyword
local config = get_keyword_config(keyword, lang_exc)
-- Langkau kata kunci yang tidak sah
if config then
-- Proses setiap istilah dalam bekas
for _, term in ipairs(container.terms or {}) do
local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term)
local no_child_categories = config.no_child_categories == true
local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang)
-- Pemprosesan peringkat atas sahaja
if is_toplevel then
-- Penjejakan etimon yang hilang/kabur
if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then
add_category(categories, "Lema bahasa " .. lang_name .. " yang merujuk etimon yang hilang")
end
if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then
add_category(categories, "Lema bahasa " .. lang_name .. " yang merujuk etimon yang kabur")
end
if term.missing_descendants_header then
add_category(categories, "Lema bahasa " .. lang_name .. " yang merujuk etimon tanpa bahagian Keturunan")
end
if term.missing_descendants_entry then
add_category(categories, "Lema bahasa " .. lang_name .. " yang merujuk etimon tanpa istilah ini dalam bahagian Keturunan")
end
-- Kategori peringkat atas (cth., "terbitan tidak ditakrifkan")
if config.toplevel_category then
add_category(categories, ucfirst(config.toplevel_category) .. " bahasa " .. lang_name)
end
-- Kategori peminjaman (bor, lbor, slbor, ubor, obor)
if config.borrowing_type or config.specialized_borrowing then
collect_borrowing_categories(categories, page_lang, term, config, true)
end
-- Kategori peminjaman daripada pengubahsuai <bor>, <lbor>, atau <slbor> pada istilah kumpulan imbuhan
local kw_config = M.data.keywords[keyword]
if kw_config and kw_config.affix_categories then
if term.bor then
local bor_config = { borrowing_type = "borrowed" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.lbor then
local bor_config = { specialized_borrowing = "learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.slbor then
local bor_config = { specialized_borrowing = "semi-learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
end
end
-- Kategori terbitan berasaskan sumber (sl, calque, pcal)
if config.source_category_type then
collect_source_derivation_categories(categories, page_lang, term, config)
end
-- Langkau semua pengkategorian anak jika no_child_categories ditetapkan
if not no_child_categories then
-- Kategori sumber hanya jika transitif
if term_is_transitive then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
-- Kategori pos sentiasa (melainkan no_child_categories)
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
else
-- Di bawah peringkat atas, patuhi rantaian induk
if parent_chain.source then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
if parent_chain.pos then
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
end
-- Rekursi ke dalam anak istilah jika perlu dan status membenarkan
if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then
collect(term, term_chain, false)
end
end
end
end
end
-- Keadaan rantaian awal
local initial_chain = {
passed_through = false,
inherited = true,
source = true,
pos = true,
internal_lang = nil,
recurse = true,
inside_affix = false,
}
collect(data_tree, initial_chain, true)
local cat_list = {}
for cat_name, sort_data in pairs(categories) do
if sort_data.sort_key ~= nil or sort_data.sort_base ~= nil then
table.insert(cat_list, {
name = cat_name,
sort_key = sort_data.sort_key,
sort_base = sort_data.sort_base,
})
else
table.insert(cat_list, cat_name)
end
end
return cat_list
end
function export.build(opts)
opts = opts or {}
local categories = {}
if not opts.suppress_categories and not opts.nocat then
categories = export.render({
data_tree = opts.data_tree,
page_lang = opts.page_lang,
available_etymon_ids = opts.available_etymon_ids,
senseid_parent_etymon = opts.senseid_parent_etymon,
get_norm_lang_func = opts.get_norm_lang_func,
lang_exc = opts.lang_exc,
})
end
local page_lang = opts.page_lang
if not page_lang then
return categories
end
local lang_name = page_lang:getCanonicalName()
table.insert(categories, "Laman dengan etimon")
table.insert(categories, "Lema bahasa " .. lang_name .. " dengan etimon")
if opts.tree then
table.insert(categories, "Laman dengan pepohon etimologi")
table.insert(categories, "Lema bahasa " .. lang_name .. " dengan pepohon etimologi")
end
if opts.text then
table.insert(categories, "Lema bahasa " .. lang_name .. " dengan teks etimologi")
end
if opts.exnihilo then
table.insert(categories, "Perkataan " .. lang_name .. " yang dicipta ex nihilo")
end
if opts.toplevel_has_inline_etymology then
table.insert(categories, "Laman dengan etimon sebaris untuk pautan merah")
end
if opts.toplevel_redundant_etymology then
table.insert(categories, "Laman dengan etimon sebaris lewah")
end
if opts.toplevel_idless_etymon then
table.insert(categories, "Laman yang menggunakan etimon tanpa ID")
end
if opts.has_mismatched_id then
table.insert(categories, "Lema bahasa " .. lang_name .. " yang merujuk etimon dengan ID yang tidak sepadan")
end
if opts.linked_page_multiple_etymons_idless then
table.insert(categories,
"Lema bahasa " .. lang_name .. " yang merujuk laman dengan berbilang etimon yang kehilangan ID")
end
if opts.linked_page_partial_etymology_sections then
table.insert(categories,
"Lema bahasa " .. lang_name .. " yang merujuk laman dengan bahagian etimologi yang kehilangan etimon")
end
if opts.text_stop_lang_missing then
table.insert(categories, "Laman dengan bahasa henti teks etimologi bukan dalam rantaian")
table.insert(categories, "Lema bahasa " .. lang_name .. " dengan bahasa henti teks etimologi bukan dalam rantaian")
end
return categories
end
function export.format(entries, lang)
if type(entries) ~= "table" or #entries == 0 then
return ""
end
local parts = {}
for _, category in ipairs(entries) do
if type(category) == "table" and type(category.name) == "string" then
table.insert(parts, M.utilities.format_categories({ category.name }, lang, category.sort_key, category.sort_base))
elseif type(category) == "string" then
table.insert(parts, M.utilities.format_categories({ category }, lang))
end
end
return table.concat(parts)
end
return export
ffa22kr5qruo24hv99j6jkr5zd4zduo
Modul:inc-headword
828
85479
375878
245546
2026-09-25T13:02:30Z
Hakimi97
2668
Mengemas kini mengikut padanan Wikikamus bahasa Inggeris (semakan [[en:Special:Diff/92367469|92367469]])
375878
Scribunto
text/plain
local export = {}
local pos_functions = {}
--[==[ intro:
This module provides support for modern Indic-language headword templates. It currently supports Hindi, Punjabi, Urdu,
Palula and Kohistani Shina. Eventually it will support other Indic languages, such as Marathi, Gujarati, Bengali,
Assamese, etc. Ancient Indic languages such as Sanskrit, Pali and Prakrit are handled by separate modules because they
have their own morphological complexities (esp. Sanskrit), which have no equivalent in the modern languages.
]==]
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local require_when_needed = require("Module:utilities/require when needed")
local m_links = require("Module:links")
local m_table = require("Module:table")
local en_utilities_module = "Module:en-utilities"
local headword_module = "Module:headword"
local headword_utilities_module = "Module:headword utilities"
local languages_module = "Module:languages"
local parse_interface_module = "Module:parse interface"
local scripts_module = "Module:scripts"
local ur_hi_translit_module = "Module:ur-hi-translit"
local pa_Aran_Guru_translit_module = "Module:pa-Aran-Guru-translit"
local m_en_utilities = require_when_needed(en_utilities_module)
local m_headword_utilities = require_when_needed(headword_utilities_module)
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local boolean_param = {type = "boolean"}
local list_param = {list = true, disallow_holes = true}
local gender_param = {type = "genders"}
local gender_param_with_default = {type = "genders", default = "?"}
local list_to_set = m_table.listToSet
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local insert = table.insert
local concat = table.concat
local misc_pos_with_gender = list_to_set {
"numerals",
"suffixes",
"adjective forms",
"noun forms",
"proper noun forms",
"pronoun forms",
"determiner forms",
"verb forms",
"postposition forms",
}
local function generate_hindis_from_urdu_heads(headobjs)
local hindis = {}
for _, headobj in ipairs(headobjs) do
local hindiobj = m_table.shallowCopy(headobj)
hindiobj.term = require(ur_hi_translit_module).tr(m_links.remove_links(headobj.term))
hindiobj.tr = nil
insert(hindis, hindiobj)
end
return hindis
end
local function generate_gur_from_shah_heads(headobjs)
local gurus = {}
for _, headobj in ipairs(headobjs) do
local guruobj = m_table.shallowCopy(headobj)
guruobj.term = require(pa_Aran_Guru_translit_module).tr(m_links.remove_links(headobj.term))
guruobj.tr = nil
insert(gurus, guruobj)
end
return gurus
end
local langs_supported = {
["hi"] = {
other_langs_scripts = {
{"ur", "ur", "Aran", "Urdu"},
},
},
["pa"] = {
other_langs_scripts = {
{"gur", "pa", "Guru", "Gurmukhi", generate_gur_from_shah_heads},
{"sha", "pa", "Aran", "Shahmukhi"},
},
sccat = true,
},
["ur"] = {
other_langs_scripts = {
{"hi", "hi", "Deva", "Hindi", generate_hindis_from_urdu_heads},
},
enable_auto_translit = true,
},
["phl"] = {
other_langs_scripts = {
{"pa", "phl", "Aran", "Arabic"},
{"lat", "phl", "Latn", "Latin"},
},
sccat = true,
},
["plk"] = {
other_langs_scripts = {
{"pa", "plk", "Aran", "Arabic"},
{"lat", "plk", "Latn", "Latin"},
},
sccat = true,
}
}
----------------------------------------------- Utilities --------------------------------------------
local function split_on_comma(val)
if val:find(",") then
return require(parse_interface_module).split_on_comma(val)
else
return {val}
end
end
local function ine(val)
if val == "" then return nil else return val end
end
local function track(page)
require("Module:debug").track("inc-headword/" .. page)
return true
end
local function validate_genders(data, genders)
data.genders = genders
if not genders then
return
end
for _, gspec in ipairs(genders) do
local g = gspec.spec
if g == "m" or g == "f" or
g == "m-p" or g == "f-p" or
g == "mf" or g == "mf-p" or
g == "mfbysense" or g == "mfbysense-p" or
g == "mfequiv" or g == "mfequiv-p" or
g == "?" then
else
error("Invalid gender: " .. g)
end
end
end
-- Parse an inflection. The raw arguments come from `args[field]`, which is parsed for inline modifiers. Multiple
-- comma-separated values are allowed.
local function parse_inflection(_data, args, field, is_head, no_include_tr, is_single_param)
local argfield = field
if type(argfield) == "table" then
argfield = argfield[1]
end
if is_single_param then
local retval
if args[argfield] then
retval = m_headword_utilities.parse_term_with_modifiers {
val = args[argfield],
paramname = field,
splitchar = ",",
is_head = is_head,
include_mods = not no_include_tr and {"tr"} or nil,
}
end
return retval or {}
else
return m_headword_utilities.parse_term_list_with_modifiers {
forms = args[argfield],
paramname = field,
splitchar = ",",
is_head = is_head,
include_mods = not no_include_tr and {"tr"} or nil,
}
end
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args[field]`, which is parsed for inline modifiers. Multiple comma-separated values are allowed. `label` is the
-- label that the inflections are given; sections enclosed in <<...>> are linked to the glossary. `accel_form` is the
-- accelerator form, or nil. `enable_auto_translit` is set if requested by the language.
local function parse_and_insert_inflection(data, args, field, label, accel_form)
local terms = parse_inflection(data, args, field)
local accel_obj
if accel_form then
local lemmas = {}
local lemma_translits = {}
for i, headobj in ipairs(data.heads) do
lemmas[i] = headobj.term
lemma_translits[i] = headobj.tr
end
accel_obj = {
lemma = lemmas,
lemma_translit = lemma_translits,
form = accel_form,
}
end
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
accel = accel_obj,
enable_auto_translit = data.langprops.enable_auto_translit,
}
end
--[==[
Main entry point. Takes two params:
; {{para|lang|req=1}}
: The language code of the language of the headword template.
; {{para|1}}
: The part of speech, pluralized; omit for {{cd|*-head}} templates such as {{tl|hi-head}}, {{tl|pa-head}} and {{tl|ur-head}}.
]==]
function export.show(frame)
local iparams = {
[1] = true,
["lang"] = {required = true},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local parargs = frame:getParent().args
local poscat = iargs[1]
local langcode = iargs.lang
if not langs_supported[langcode] then
local langcodes_supported = {}
for lang, _ in pairs(langs_supported) do
insert(langcodes_supported, lang)
end
error("This module currently only works for lang=" .. concat(langcodes_supported, "/"))
end
local lang = require(languages_module).getByCode(langcode, true)
local langname = lang:getCanonicalName()
local pos_in_1 = not poscat
if pos_in_1 then
poscat = ine(parargs[1]) or
mw.title.getCurrentTitle().fullText == "Template:" .. langcode .. "-head" and "interjection" or
error("Part of speech must be specified in 1=")
poscat = require(headword_module).canonicalize_pos(poscat)
end
local indexing_poscat = pos_in_1 and (misc_pos_with_gender[poscat] and "head_with_gender" or "head") or poscat
local langprops = langs_supported[langcode]
local params = {
["head"] = true,
["head2"] = {replaced_by = false, instead = "use comma-separated |head="},
["tr"] = true,
["tr2"] = {replaced_by = false, instead = "use comma-separated |tr= or <tr:...> inline modifier on head"},
["id"] = true,
["sort"] = true,
["nolink"] = boolean_param,
["nolinkhead"] = {type = "boolean", alias_of = "nolink"},
["suffix"] = boolean_param,
["nosuffix"] = boolean_param,
["splithyphen"] = boolean_param,
["json"] = boolean_param,
["pagename"] = true, -- for testing
}
if pos_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
for _, other_lang_script in ipairs(langprops.other_langs_scripts) do
local param, _, _, _ = unpack(other_lang_script)
params[param] = true
params[param .. "1"] = {replaced_by = false, instead = "use comma-separated items (with no space after the comma) in |" .. param .. "="}
params[param .. "2"] = {replaced_by = false, instead = "use comma-separated items (with no space after the comma) in |" .. param .. "="}
end
if pos_functions[indexing_poscat] then
for key, val in pairs(pos_functions[indexing_poscat].params) do
params[key] = val
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local data = {
lang = lang,
langname = langname,
langprops = langprops,
pos_category = poscat,
categories = {},
genders = {},
inflections = {},
pagename = pagename,
id = args.id,
sort_key = args.sort,
force_cat_output = force_cat,
-- We use our own splitting algorithm so the redundant head cat will be inaccurate.
no_redundant_head_cat = true,
sccat = langprops.sccat,
}
local trs = args.tr and split_on_comma(args.tr) or {}
local num_trs = #trs
local heads = args.head and parse_inflection(data, args, "head", "is_head", nil, "is_single_param") or {}
local user_specified_heads = heads
local num_heads = #heads
if num_heads > 0 and num_trs > 0 and num_heads ~= num_trs then
error(("%s head%s specified explicitly but %s translit%s; they must match; use '+' to stand for the default head (the pagename) or no manual translit"):format(
num_heads, num_heads > 1 and "s" or "", num_trs, num_trs > 1 and "s" or ""))
end
-- Be careful here not to overwrite user_specified_heads if it's empty so we can later check user_specified_heads
-- to see if the user provided any heads.
if num_heads == 0 and num_trs > 0 then
heads = {}
for i = 1, num_trs do
heads[i] = {term = "+"}
end
end
if not heads[1] then
heads = {{term = "+"}}
end
for i, headobj in ipairs(heads) do
if headobj.term == "+" then
headobj.term = args.nolink and pagename or m_headword_utilities.add_links_to_multiword_term(pagename,
{split_hyphen_when_space = args.splithyphen})
end
if headobj.tr and trs[i] then
if headobj.tr ~= trs[i] then
error(("Saw two different translits '%s' and '%s' for head #%s '%s'"):format(
headobj.tr, trs[i], i, headobj.term))
end
else
headobj.tr = headobj.tr or trs[i]
end
if headobj.tr == "+" then
headobj.tr = nil
end
end
data.heads = heads
data.is_suffix = false
if args.suffix or (
not args.nosuffix and pagename:find("^%-") and poscat ~= "suffixes" and poscat ~= "suffix forms"
) then
data.is_suffix = true
data.pos_category = "suffixes"
local singular_poscat = m_en_utilities.singularize(poscat)
insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
insert(data.inflections, {label = singular_poscat .. "-forming suffix"})
end
if pos_functions[indexing_poscat] then
pos_functions[indexing_poscat].func(args, data)
end
for _, other_lang_script in ipairs(langprops.other_langs_scripts) do
local param, other_langcode, other_sccode, lang_script_label, generate_from_heads = unpack(other_lang_script)
local terms = parse_inflection(data, args, param, nil, "no_include_tr", "is_single_param") or {}
if not terms[1] and generate_from_heads then
terms = generate_from_heads(user_specified_heads)
end
if terms[1] then
local other_lang = require(languages_module).getByCode(other_langcode, true)
local other_sc = require(scripts_module).getByCode(other_sccode, true)
for _, termobj in ipairs(terms) do
termobj.lang = other_lang
termobj.sc = other_sc
end
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = lang_script_label .. " spelling",
-- Don't set `enable_auto_translit` here, e.g. for Urdu.
}
end
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require(headword_module).full_headword(data)
end
pos_functions.adjectives = {
params = {
[1] = {list = "comp", disallow_holes = true},
[2] = {list = "sup", disallow_holes = true},
["f"] = list_param,
["ind"] = boolean_param,
},
func = function(args, data)
if args["ind"] then
insert(data.inflections, {label = glossary_link("indeclinable")})
insert(data.categories, data.langname .. " indeclinable adjectives")
end
parse_and_insert_inflection(data, args, {1, "comp"}, "<<comparative>>")
parse_and_insert_inflection(data, args, {2, "sup"}, "<<superlative>>")
parse_and_insert_inflection(data, args, "f", "feminine")
end,
}
pos_functions.ordinals = {
params = {
["f"] = list_param,
["ind"] = boolean_param,
},
func = function(args, data)
data.pos_category = "Kata sifat"
insert(data.categories, data.langname .. " numerals")
if args["ind"] then
insert(data.inflections, {label = glossary_link("indeclinable")})
insert(data.categories, data.langname .. " indeclinable numerals")
end
parse_and_insert_inflection(data, args, "f", "feminine")
end,
}
pos_functions.cardinals = {
params = {
[1] = gender_param,
["g"] = {replaced_by = 1},
["sym"] = list_param,
},
func = function(args, data)
data.pos_category = "numerals"
validate_genders(data, args[1])
parse_and_insert_inflection(data, args, "sym", "native script symbol")
end,
}
local function nouns(plpos)
return {
params = {
[1] = gender_param_with_default,
["g"] = {replaced_by = 1},
["pl"] = list_param,
["f"] = list_param,
["m"] = list_param,
["ind"] = boolean_param,
},
func = function(args, data)
validate_genders(data, args[1])
if args["ind"] then
if args["pl"][1] then
error("Can't specify both ind= and pl=")
end
insert(data.inflections, {label = glossary_link("indeclinable")})
insert(data.categories, data.langname .. " indeclinable " .. plpos)
else
parse_and_insert_inflection(data, args, "pl", "formal plural", "formal|p")
end
parse_and_insert_inflection(data, args, "m", "male equivalent", "m")
parse_and_insert_inflection(data, args, "f", "female equivalent", "f")
if args["m"][1] or args["f"][1] then
insert(data.categories, data.langname .. " " .. plpos .. " with other-gender equivalents")
end
end,
}
end
pos_functions.nouns = nouns("Kata nama")
pos_functions["Kata nama khas"] = nouns("Kata nama khas")
pos_functions.pronouns = {
params = {
[1] = gender_param,
["g"] = {replaced_by = 1},
},
func = function(args, data)
validate_genders(data, args[1])
end,
}
pos_functions.verbs = {
params = {
[1] = true,
},
func = function(args, data)
if args[1] then
local label
if args[1] == "t" then
label = "transitive"
insert(data.categories, data.langname .. " transitive verbs")
elseif args[1] == "i" then
label = "intransitive"
insert(data.categories, data.langname .. " intransitive verbs")
elseif args[1] == "d" then
label = "ditransitive"
insert(data.categories, data.langname .. " ditransitive verbs")
elseif args[1] == "it" or args[1] == "ti" or args[1] == "a" then
label = "ambitransitive"
insert(data.categories, data.langname .. " ambitransitive verbs")
insert(data.categories, data.langname .. " transitive verbs")
insert(data.categories, data.langname .. " intransitive verbs")
elseif args[1] == "tp" then -- only in Palula
label = "transitive"
insert(data.categories, data.langname .. " transitive verbs")
insert(data.categories, data.langname .. " passive verbs")
insert(data.inflections, {label = glossary_link("passive")})
else
error("Unrecognized param 1=" .. args[1] .. ": Should be 'i' = intransitive, 't' = transitive, 'd' = ditransitive or 'it'/'ti'/'a' = ambitransitive")
end
insert(data.inflections, {label = glossary_link(label)})
end
if data.pagename:find(" ") then
local base_verb = m_links.remove_links(data.pagename):gsub("^.* ", "")
insert(data.categories, data.langname .. " compound verbs formed with " .. base_verb)
end
end,
}
pos_functions.head_with_gender = {
params = {
[2] = gender_param,
},
func = function(args, data)
validate_genders(data, args[2])
end,
}
local pos_prelude = {
["head"] =
"This template should be used to generate the headword line for LANG terms whose part of speech does not have an associated specialized template. The current specialized templates are " ..
"{{tl|CODE-noun}}, {{tl|CODE-proper noun}}, {{tl|CODE-pron}} (pronouns), {{tl|CODE-verb}}, {{tl|CODE-adj}} (adjectives), {{tl|CODE-adv}} (adverbs), {{tl|CODE-num-card}} (cardinal numbers/numerals) and "..
"{{tl|CODE-num-ord}} (ordinal numbers/numerals). All others should use {{tl|CODE-head}}.",
}
local noun_addl_params = [=[
;{{para|pl}}
: Formal or irregular plural(s). Intended particularly for Arabic and Persian-origin plurals. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|f}}
: Female equivalent(s), for a noun referring to a male person or animal. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|m}}
: Male equivalent(s), for a noun referring to a female person or animal. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|ind|1}}
: Specify that the noun is indeclinable.
]=]
local pos_addl_params = {
["Kata nama"] = noun_addl_params,
["Kata nama khas"] = noun_addl_params,
["Kata kerja"] = [=[
;{{para|1}}
: Verb type. One of {{cd|t}} (transitive), {{cd|i}} (intransitive), {{cd|d}} (ditransitive) or {{cd|it}}/{{cd|ti}}/{{cd|a}} (ambitransitive).
]=],
["Kata sifat"] = [=[
;{{para|1}}
: Comparative form(s). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|2}}
: Superlative form(s). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|ind|1}}
: Specify that the adjective is indeclinable.
;{{para|f}}
: Feminine form(s) of an adjective with irregular feminine forms.
]=],
["cardinals"] = [=[
;{{para|sym}}
: Native script symbol(s) for this numeral. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=],
["ordinals"] = [=[
;{{para|ind|1}}
: Specify that the ordinal is indeclinable.
;{{para|f}}
: Feminine form(s) of an ordinal adjective with irregular feminine forms.
]=],
["head"] = [=[
;{{para|1|req=1}}
: Part of speech. Can be singular or plural and can be abbreviated (e.g. {{cd|n}} for noun; {{cd|nounf}} or {{cd|nf}} for noun form; {{cd|interj}} or {{cd|intj}} for interjection; {{cd|pcl}} for particle; {{cd|phr}} for phrase; etc.). The recognized abbreviations are listed in [[Template:head#Part of speech]] and are the same abbreviations that can be specified in the part-of-speech parameter to {{tl|head}}.
;{{para|2}}
: Gender(s). Specifying a gender is always optional and is only allowed for certain parts of speech where it makes sense to specify a gender (currently this includes numerals, suffixes, adjective forms, noun forms, proper noun forms, pronoun forms, determiner forms, verb forms and postposition forms). Possible values are {{cd|m}}, {{cd|f}}, {{cd|m-p}}, {{cd|f-p}}, {{cd|mf}} (can be either masculine or feminine), {{cd|mf-p}} (plural-only, can be either masculine or feminine), {{cd|mfbysense}} (can be either masculine or feminine, depending on the natural gender of the person or animal being referred to), {{cd|mfbysense-p}} (plural-only, can be either masculine or feminine, depending on the natural gender of the person or animal being referred to). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=],
}
local pos_has_gender = {
["Kata nama"] = true,
["Kata nama khas"] = true,
["pronouns"] = true,
["cardinals"] = true,
}
--[==[
Documentation generation function, used to populate the documentation describing all parameters of all headword-line templates. Supports the following parameters:
; {{para|lang|req=1}}
: The language code of the language of the headword template being documented.
; {{para|pos|req=1}}
: The plural part of speech of the headword template being documented. Use {{cd|head}} for {{tl|hi-head}}/{{tl|pa-head}}/{{tl|ur-head}}/etc.
]==]
function export.doctext(frame)
local iparams = {
["lang"] = {required = true, type = "language"},
["pos"] = {required = true},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local langcode = iargs.lang:getCode()
if not langs_supported[langcode] then
local langcodes_supported = {}
for lang, _ in pairs(langs_supported) do
insert(langcodes_supported, lang)
end
error("This module currently only works for lang=" .. concat(langcodes_supported, "/"))
end
local other_lang_script_equivs = langcode == "hi" and [=[
;{{para|ur}}
: Urdu equivalent(s). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=] or langcode == "ur" and [=[
;{{para|hi}}
: Hindi equivalent(s). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=] or langcode == "pa" and [=[
;{{para|gur}}
: Gurmukhi equivalent(s) of a Shahmukhi term. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|sha}}
: Shahmukhi equivalent(s) of a Gurmukhi term. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=] or (langcode == "phl" or langcode == "plk") and [=[
;{{para|pa}}
: Perso-Arabic spelling(s) of the term. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
;{{para|lat}}
: Latin spelling(s) of the term. Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=] or ""
local prelude = (pos_prelude[iargs.pos] or "This template should be used to generate the headword line for LANG POS.")
:gsub("LANG", iargs.lang:getCanonicalName())
:gsub("CODE", iargs.lang:getCode())
:gsub("POS", iargs.pos)
local g_text = [=[
;{{para|1}}
: Gender(s). Possible values are {{cd|m}}, {{cd|f}}, {{cd|m-p}}, {{cd|f-p}}, {{cd|mf}} (can be either masculine or feminine), {{cd|mf-p}} (plural-only, can be either masculine or feminine), {{cd|mfbysense}} (can be either masculine or feminine, depending on the natural gender of the person or animal being referred to), {{cd|mfbysense-p}} (plural-only, can be either masculine or feminine, depending on the natural gender of the person or animal being referred to). Separate multiple items with a comma (not followed by a space). Per-item inline modifiers are supported.
]=]
local includeg = pos_has_gender[iargs.pos]
local addl_params = pos_addl_params[iargs.pos] or ""
local text = prelude .. [=[
==Parameters==
The following parameters are supported:
]=] .. (includeg and g_text or "") .. addl_params .. [=[
;{{para|head}}
: Explicitly specified headword(s), for ]=] .. (langcode == "pa" and "adding vowel diacritics to Shahmukhi terms or " or langcode == "ur" and "adding vowel diacritics or " or "") ..
"introducing links in multiword expressions. Separate multiple items with a comma (not followed by a space). " ..
"Per-item inline modifiers are supported. Use {{cd|+}} to request the default linking algorithm (equivalent to omitting the value if there's only one value). " ..
"Note that by default each word of a multiword lemma is linked" .. (langcode == "ur" and "." or ", so you only need to use this " ..
(langcode == "pa" and "for Gurmukhi terms " or "") ..
"when the default links don't suffice (e.g. the multiword expression consists of non-lemma forms, which need to be linked to their lemmas).") .. "\n" .. [=[
;{{para|tr}}
: Manual transliteration(s), in case the automatic transliteration is incorrect. Separate multiple items with a comma (not followed by a space), ]=] ..
[=[and use {{cd|+}} to stand for the default automatic translation (equivalent to omitting the value if there's only one value). ]=] ..
[=[If {{para|head}} is used, there should be the same number of transliterations as head values, or an error will occur.
]=] .. other_lang_script_equivs .. [=[
;{{para|nolink|1}}, {{para|nolinkhead|1}}
: Don't link the individual words in a multiword expression.
;{{para|suffix|1}}
: Specify that the term is a suffix. Not needed if the term begins with a hyphen.
;{{para|nosuffix|1}}
: Specify that a term beginning with a hyphen is not a suffix.
;{{para|id}}
: Sense ID, for linking to this particular headword when there is more than one. See {{tl|senseid}} for more information.
; {{para|splithyph|1}}
: Indicate that automatic splitting and linking of words should split on hyphens in multiword expressions with spaces in them. Normally splitting on hyphens only occurs in terms without spaces.
; {{para|pagename}}
: Override the page name used to compute default values of various sorts. Useful when testing, for documentation pages, etc.
; {{para|sort}}
: Sort key. Rarely needs to be specified, as it is normally automatically generated.
; {{para|json|1}}
: Output the headword data in JSON form instead of the normal output. For use by bots.
]=]
local after_params_text =[=[
==Inline modifiers==
All params above that allow for multiple comma-separated values (except for {{para|tr}}) support ''inline modifiers'', e.g. {{para|pl|रायज़,फ़राइज़<l:rare>}} to attach a label ''rare'' to the second plural. The following modifiers are recognized:
* {{cd|tr}}: manual translit; cannot be specified for genders as it doesn't make sense to do so
* {{cd|q}}: qualifier, e.g. {{cd|<q:in the plural>}} or {{cd|<q:when referring to a card game>}}; this appears *BEFORE* the term, parenthesized and italicized
* {{cd|qq}}: qualifier, e.g. {{cd|<qq:in the plural>}} or {{cd|<qq:when referring to a card game>}}; this appears *AFTER* the term, parenthesized and italicized
* {{cd|l}}: comma-separated list of labels, e.g. {{cd|<l:rare>}} or {{cd|<l:dated,or,literary>}}; this appears *BEFORE* the term, parenthesized and italicized
* {{cd|ll}}: comma-separated list of labels, e.g. {{cd|<ll:rare>}} or {{cd|<ll:dated,or,literary>}}; this appears *AFTER* the term, parenthesized and italicized
* {{cd|ref}}: one or more references, in the format documented in [[Module:references]] and {{tl|IPA}}
* {{cd|id}}: sense ID; see {{temp|senseid}}; cannot be specified for headwords or genders as it doesn't make sense to do so
==Suffix handling==
If the term begins with a hyphen ({{cd|-}}), it is assumed to be a suffix rather than a base form, and is categorized into [[:Category:LANG suffixes]] and [[:Category:LANG POS-forming suffixes]] rather than [[:Category:LANG POSs]] (e.g. [[:Category:LANG noun-forming suffixes]] rather than [[:Category:LANG nouns]]). This can be overridden using {{para|nosuffix|1}}.
]=]
after_params_text = after_params_text:gsub("LANG", iargs.lang:getCanonicalName())
text = text .. after_params_text
-- Remove final newline so template code can add a newline after invocation
text = text:gsub("\n$", "")
return mw.getCurrentFrame():preprocess(text)
end
return export
tsbk1pt6dspcffedjnjvixh33sk590e
Wikikamus:ms/pasau
4
85509
375922
347405
2026-09-26T08:00:08Z
Muhammad Abdi Ramadhan
9873
/* Kata nama */
375922
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata nama===
{{inti|ms|kata nama}}
# {{lb|ms|Melaka}} [[pasar]]
==Bahasa Melayu==
===pasau===
{{lb|ms|kata tempat}}
# {{lb|ms|Rokan Hulu}} pasar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu nak kapasau?.|orang itu mau kepasar?.}}
===Rujukan===
* {{R:PRPM|gdm|keyword=pasau+pasar}}
09oe6gddllnkldlkvxlp2yyiq14l8lb
Wikikamus:mfa/abih
4
86769
376060
347254
2026-09-26T08:46:32Z
Robiyatuladawiyah05
11514
/* Kata kerja */
376060
wikitext
text/x-wiki
==Bahasa Melayu Kelantan-Patani==
=== Sebutan ===
* {{AFA|mfa|[a.bih]}}
* {{penyempangan|mfa|a|bih}}
* {{rima|mfa|bih|ih}}
===Kata kerja===
{{head|mfa|kata kerja}}
# [[habis]]
#: {{cp|mfa|Jangae pr'''abih''' maso gitu jah|Jangan kamu meng'''habis'''kan masa begitu sahaja.}}
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Habis <!--Habis-->
#: {{cp|ms|dah abih.|sudah habis.}}
===Adverba===
{{head|mfa|adverba}}
# [[habis]]
#: {{cp|mfa|'''Abih''' doh nasik dalae puyok|Nasi dalam periuk sudah '''habis'''.}}
# [[tamat]]
#: {{uxi|ms|'''abih''' maso|'''tamat''' masa}}
=== Rujukan ===
* {{R:Glosari Dialek Kelantan}}
=== Pautan luar ===
* {{R:PRPM|gdkel|keyword=abih}}
qgzrcm66ds7mw7o7t1459ny3inrnsxg
Wikikamus:mfa/sembo
4
89425
376034
250286
2026-09-26T08:40:57Z
Elvaretta Vito
11512
/* Kata kerja */
376034
wikitext
text/x-wiki
==Bahasa Melayu Kelantan-Patani==
==Bahasa Melayu==
===Kata kerja===
{{lb|mb|kata kerja}}
# {{lb|mb|Bengkalis}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Sembo Air|Sembur Air.}}
0vauz1zrc9aq6cequxhkgbkqkf9ie2s
376043
376034
2026-09-26T08:42:47Z
Elvaretta Vito
11512
/* Kata kerja */
376043
wikitext
text/x-wiki
==Bahasa Melayu Kelantan-Patani==
==Bahasa Melayu==
===Kata kerja===
{{lb|mb|kata kerja}}
# {{lb|mb|Bengkalis}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|mb|Sembo Air|Sembur Air.}}
rm45euorboi6aey4r3q2a2mil8ekru3
Wikikamus:zmi/angek
4
104185
375950
269127
2026-09-26T08:16:07Z
Muhammad Abdi Ramadhan
9873
/* Kata sifat */
375950
wikitext
text/x-wiki
== Bahasa Melayu Negeri Sembilan ==
===Kata sifat===
{{inti|zmi|kata sifat}}
# [[panas]], [[hangat]]
#: {{cp|zmi|Ado ae '''angek''' kek sinia.|Ada air '''panas''' dekat sini.}}
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} panas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|angek hari ko.|panas hari ni.}}
===Etimologi===
Daripada {{der|zmi|min|angek}}, daripada {{inh|min|poz-mly-pro|*haŋət}}, daripada {{inh|min|poz-pro|*qaŋət}}.
===Sebutan===
* {{AFA|zmi|[a.ŋɛʔ]}}
* {{penyempangan|zmi|a|ngek|}}
===Sinonim===
* {{l|zmi|paneh}}
===Antonim===
* {{l|zmi|sojuk}}
===Rujukan===
Jaafar, M. F., Aman, I., & Awal, N. M. (2017). Morfosintaksis Dialek Negeri Sembilan dan Dialek Minangkabau. ''GEMA Online® Journal of Language Studies, 17''(2), 177–191. {{doi|10.17576/gema-2017-1702-11}}
nk8u1gsgtb43ofz86jqh0mm98pszxey
Wikikamus:zmi/sojuk
4
104187
376037
268873
2026-09-26T08:41:44Z
Robiyatuladawiyah05
11514
/* Kata sifat */
376037
wikitext
text/x-wiki
==Bahasa Melayu Negeri Sembilan==
===Takrifan===
====Kata sifat====
{{inti|zmi|kata sifat}}
# sejuk
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} Dingin <!--Dingin-->
#: {{cp|ms|sojuk betol.|dingin sekali.}}
gqh144ohupngs02apssee8oqjj44i4v
Kategori:en:Tempat di Asia
14
117660
375885
327595
2026-09-25T13:35:32Z
Hakimi97
2668
Hakimi97 telah memindahkan laman [[Kategori:en:Kawasan di Asia]] ke [[Kategori:en:Tempat di Asia]]: Tajuk salah eja
327595
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Kategori:en:Kawasan dunia
14
117661
375889
327599
2026-09-25T13:43:58Z
Hakimi97
2668
Cadangan penghapusan
375889
wikitext
text/x-wiki
{{delete|digantikan dengan [[:Kategori:en:Benua dan kawasan benua]]}}
rpq86n5mxsqeni3l51qrs2bqwamqzj5
lesek
0
120215
376204
345367
2026-09-26T09:39:39Z
SY Reski
10853
376204
wikitext
text/x-wiki
==Bahasa Melayu Kelantan-Patani==
===Kata kerja===
{{inti|mfa|kata kerja}}
# {{alt sp|mfa|lèsèk}}
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|Kata Sifat}}
#{{lb|ms|Kampar}} lasak <!--lesek-->
#:{{cp|ms|lesek bonou ang ko.|kamu lasak sekali.}}
sbmhiiln32ojryh4p8mzwdbhluaxyac
lumpek
0
136601
375914
363612
2026-09-26T07:49:06Z
Muhammad Abdi Ramadhan
9873
/* =Kata kerja */
375914
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja==
{{inti|ms|kata kerja}}
# {{lb|ms|Rokan Hulu }} [[lompat]]
#: {{cp|ms|cecep bisa lumpek|cecep bisa lompat}}
g7zj48wytlsa0wyjrovxyr4e492n9xn
kojuik
0
136615
376069
363635
2026-09-26T08:49:33Z
SY Reski
10853
376069
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{inti|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} [[kejut]]
#: {{cp|ms|takojuik den|aku terkejut}}
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} kojuik <!--kejut-->
#:{{cp|ms|takojuik den dibueknyo.|terkejut sama karena kamu.}}
fio946fwk38awf8gsl8mm33ipqgyrm9
Templat:see citations
10
141420
376227
369560
2026-09-26T11:50:30Z
Hakimi97
2668
Kemas kini templat
376227
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
--><span class="see-cites"><!--
-->Untuk petikan yang menggunakan istilah ini, sila lihat [[{{#if:{{{mainspace|}}}||Petikan:}}{{logical to physical|{{{1|<noinclude>und</noinclude>}}}|{{{2|{{pagename}}}}}}}#{{langname|{{{1|<noinclude>und</noinclude>}}}}}|{{#if:{{{mainspace|}}}||Petikan:}}{{lang|{{{1|<noinclude>und</noinclude>}}}|{{{2|{{pagename}}}}}}}]].<!--
--></span><!--
--><noinclude>{{documentation}}</noinclude>
hpcrz3nc3jovihcl2gjyn3f4dxirt68
Wikikamus:Senarai keluarga
4
145825
375868
2026-09-25T12:40:15Z
Hakimi97
2668
Hakimi97 telah memindahkan laman [[Wikikamus:Senarai keluarga]] ke [[Wikikamus:Senarai keluarga bahasa]]: Penamaan semula, lebih tepat
375868
wikitext
text/x-wiki
#LENCONG [[Wikikamus:Senarai keluarga bahasa]]
s141ltwbziv3uvn3k3xz238gg3wjo00
Modul:ur-hi-translit
828
145826
375876
2026-09-25T12:59:28Z
Hakimi97
2668
Mencipta laman baru dengan kandungan 'local U = require("Module:string/char") local gsub = mw.ustring.gsub local export = {} local hri = U(0x93F) local hri2 = U(0x907) local diri = U(0x940) local diri2 = U(0x908) local hru = U(0x941) local hru2 = U(0x909) local diru = U(0x942) local diru2 = U(0x90A) local E = U(0x947) local E2 = U(0x90F) local AI = U(0x948) local AI2 = U(0x910) local O = U(0x94B) local O2 = U(0x913) local AU = U(0x94C) local AU2 = U(0x914) local A = U(0x905) local LA = U(...'
375876
Scribunto
text/plain
local U = require("Module:string/char")
local gsub = mw.ustring.gsub
local export = {}
local hri = U(0x93F)
local hri2 = U(0x907)
local diri = U(0x940)
local diri2 = U(0x908)
local hru = U(0x941)
local hru2 = U(0x909)
local diru = U(0x942)
local diru2 = U(0x90A)
local E = U(0x947)
local E2 = U(0x90F)
local AI = U(0x948)
local AI2 = U(0x910)
local O = U(0x94B)
local O2 = U(0x913)
local AU = U(0x94C)
local AU2 = U(0x914)
local A = U(0x905)
local LA = U(0x93E)
local ret = U(0x615)
local halant = U(0x94D)
local zabar = U(0x64E)
local zer = U(0x650)
local pesh = U(0x64F)
local tashdid = U(0x651) -- also called shadda
local jazm = "ْ"
local he = "ہ"
local vao2 = "ؤ"
local consonants = "ببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨوہھٹڈںڑشؕ"
local consonantS = "ببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨہھٹڈںڑشؕ"
local consonantS2 = "یببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨںوہھٹڈڑشؕ"
local sun = "تثصشسزرذدنلطظض"
local vowels = "ایئےۓوؤ"
local hes = "ہح"
local diacritics = "َُِّْٰ"
local ZZP = "َُِ"
local hiPD = "ीूेैोौ"
local mapping = {
["آ"] = 'आ', ["ب"] = 'ब', ["پ"] = 'प',
["ت"] = 'त', ["ٹ"] = 'ट', ["ث"] = 'स',
["ج"] = 'ज', ["چ"] = 'च', ["ح"] = 'ह',
["خ"] = 'ख़', ["د"] = 'द', ["ڈ"] = 'ड',
["ذ"] = 'ज़', ["ر"] = 'र', ["ڑ"] = "ड़",
["ز"] = 'ज़', ["ژ"] = 'श़', ["س"] = 'स',
["ش"] = 'श', ["ص"] = 'स', ["ض"] = 'ज़',
["ط"] = 'त', ["ظ"] = 'ज़', ["غ"] = 'ग़',
["ف"] = 'फ़', ["ق"] = 'क़', ["ک"] = 'क',
["گ"] = 'ग', ["ل"] = 'ल', ["م"] = 'म',
["ن"] = 'न', ["و"] = 'व', ["ہ"] = 'ह',
["ی"] = 'य',
["ں"] = 'ं',
["ݨ"] = 'ण', ["ࣇ"] = 'ळ', ["ك"] = 'क',
["ع"] = 'अ',
["ء"] = '',
["ئ"] = '',
["ؤ"] = 'ओ',
["أ"] = '',
-- diacritics
[zabar] = "॑",
[zer] = "" .. hri .. "",
[pesh] = "" .. hru .. "",
[jazm] = "" .. halant .. "",
[U(0x200C)] = "-", -- ZWNJ (zero-width non-joiner)
-- ligatures
["ﻻ"] = "ला",
["ﷲ"] = "अल्लाह",
-- kashida
["ـ"] = "-", -- kashida, no sound
-- numerals
["١"] = "१", ["٢"] = "२", ["٣"] = "३", ["٤"] = "४", ["٥"] = "५",
["٦"] = "६", ["٧"] = "७", ["٨"] = "८", ["٩"] = "९", ["٠"] = "०",
["۱"] = "१", ["۲"] = "२", ["۳"] = "३", ["۴"] = "४", ["۵"] = "५",
["۶"] = "६", ["۷"] = "७", ["۸"] = "८", ["۹"] = "९", ["۰"] = "०",
-- punctuation (leave on separate lines)
["۔"] = "।",
["؟"] = "?", -- question mark
["،"] = ",", -- comma
["؛"] = ";", -- semicolon
["«"] = '“', -- quotation mark
["»"] = '”', -- quotation mark
["٪"] = "%", -- percent
["؉"] = "‰", -- per mille
["٫"] = ".", -- decimals
["٬"] = ",", -- thousand
["ۓ"] = "-ये",
["ۂ"] = "-ए" -- he ye (in ezâfe)
}
local ain = 'ع'
local kzabar = 'ٰ'
local alif = 'ا'
local madda = 'آ'
local ye = 'ی'
local ye2 = 'ئ'
local ye3 = "ے"
local vao = "و"
local ye4 = "ۓ"
local he2 = "ۂ"
local aspirate = 'ھ'
local lam = 'ل'
local noon = 'ن'
local gunDia = '٘'
function export.tr(text, lang, sc)
-- EXCEPTIONS - leave as they are, unless they have been sorted out elsewhere
text = gsub(text, "یِہ", "ये")
text = gsub(text, alif .. noon .. gunDia .. "", "ाँ")
text = gsub(text, '([' .. consonants .. '])' .. ye .. "ں", "%1ें")
text = gsub(text, "ؤ" .. pesh, "ऊ")
text = gsub(text, alif .. ye2 .. '([' .. zabar .. ']?)' .. '([' .. consonants .. '])', "ाय%2")
text = gsub(text, madda .. ye2 .. '([' .. zabar .. ']?)' .. '([' .. consonants .. '])', "आय%2")
-- SSH
text = gsub(text, "ش" .. jazm .. ret, "ष्")
text = gsub(text, "(ش)" .. "([" .. ZZP .. "])" .. ret, "ष%2")
-- Tashdeed
text = gsub(text, '([' .. consonantS2 .. '])' .. tashdid, "%1" .. halant .. "%1")
text = gsub(text, '([' .. consonantS2 .. '])' .. tashdid .. '([' .. ZZP .. '])', "%1" .. halant .. "%1%2")
text = gsub(text, '([' .. ZZP .. '])' .. ye .. '([' .. ZZP .. '])' .. tashdid, "%1य्य%2")
text = gsub(text, '([' .. ZZP .. '])' .. vao .. '([' .. ZZP .. '])' .. tashdid, "%1व्व%2")
-- For some reason the tashdeed gets pushed after the other diacritics, so this line is necessary for tashdeed to work with other diacritics
text = gsub(text, '([' .. consonants .. '])' .. '([' .. ZZP .. '])' .. tashdid, "%1" .. halant .. "%1%2")
-- e, instead of i
--text = gsub(text, jazm .. '([' .. consonants .. '])' .. zer .. '([' .. consonants .. '])', "्%1" .. E .. "%2")
-- tanween diacritic
text = gsub(text, '([' .. consonants .. '])' .. 'ً' .. alif, "%1न")
text = gsub(text, alif .. 'ً', "न")
text = gsub(text, '([' .. consonants .. '])' .. 'ً', "%1न")
-- khari zabar --
text = gsub(text, '([' .. consonants .. '])' .. kzabar, "%1" .. LA .. "")
text = gsub(text, '([' .. vowels .. '])' .. kzabar, "" .. LA .. "")
text = gsub(text, '([' .. consonants .. '])' .. tashdid .. alif, "%1" .. halant .. "%1" .. LA .. "")
---- nasalisation
text = gsub(text, "آن٘([کگجچٹڈتدن])" ,"आँ%1")
text = gsub(text, "ن٘([ہو])" , "ँ%1")
text = gsub(text, "نْ([کگجچٹڈتدن])" , "ं%1")
text = gsub(text, "ن٘([کگجچٹڈتدن])" , "ं%1")
text = gsub(text, "مْ([بپمو])" , "ं%1")
----
-- ‘ain
text = gsub(text, ain .. pesh .. vao .. '([' .. consonantS .. '])', "ऊ%1")
text = gsub(text, '([' .. consonants .. '])' .. zabar .. ain .. zabar, "%1ा")
text = gsub(text, '([' .. consonants .. '])' .. zabar .. alif .. "", "%1ा")
text = gsub(text, zer .. ain .. jazm, "े") -- see example: مَواقِع
text = gsub(text, pesh .. ain .. jazm, "ो") -- see example: شُعْلَہ
text = gsub(text, '([' .. consonants .. '])' .. ain .. zabar .. he, "%1" .. LA .. "")
text = gsub(text, ain .. alif .. ain, "आ")
text = gsub(text, alif .. ain .. '([' .. consonants .. '])', "" .. E2 .. "%1")
text = gsub(text, '([' .. consonants .. '])' .. ain .. he, "%1अ")
text = gsub(text, '([' .. consonants .. '])' .. '([' .. zer .. pesh .. ']?)' .. ain, "%1%2")
text = gsub(text, ain .. zabar .. vao .. '([' .. consonants .. '])', "औ%1")
text = gsub(text, ain .. zabar .. ye .. '([' .. consonants .. '])', "ऐ%1")
text = gsub(text, ain .. zer .. '([' .. consonants .. '])', "इ%1")
text = gsub(text, ain .. pesh .. '([' .. consonants .. '])', "उ%1")
text = gsub(text, ain .. zer .. ye .. '([' .. consonants .. '])', "ई%1")
text = gsub(text, ain .. jazm, "" .. LA .. "")
-- Zammah Majhool --
text = gsub(text, "([" .. consonants .. "])" .. pesh .. he , "%1ो") -- affects voh
-- medial/final consonants.
text = gsub(text, zabar .. he .. ye .. jazm .. "" , "हे") -- related to jahez
text = gsub(text, zabar .. he .. ye .. "" , "हे") -- related to jahez
text = gsub(text, zabar .. he .. zer .. ye, "ही") -- related to nahin
text = gsub(text, zer .. he .. alif , "िहा")
text = gsub(text, zabar .. he .. alif, "हा") -- related to raha
text = gsub(text, zabar .. he .. '([' .. consonants .. vowels .. '])', "ह%1") -- related to pahle
text = gsub(text, '([' .. consonants .. zabar .. '])' .. alif, "%1ा")
text = gsub(text, '([' .. consonants .. '])' .. tashdid .. alif, "%1%1ा")
text = gsub(text, '([' .. consonants .. '])' .. vao, "%1ो")
text = gsub(text, '([' .. consonants .. '])' .. tashdid .. vao, "%1%1ो")
text = gsub(text, zer .. ye .. alif, "िया")
text = gsub(text, zer .. ye .. zabar .. alif, "िया")
text = gsub(text, "" .. '([' .. consonants .. '])' .. zer .. 'ی' .. vao .. '([' .. ZZP .. '])', "%1ीव%2") -- affects levar
text = gsub(text, "" .. '([' .. consonants .. '])' .. zer .. 'ی' .. vao, "%1ियो") -- affects boliyan
text = gsub(text, '([' .. consonants .. '])' .. ye .. '([' .. consonants .. '])', "%1े%2")
text = gsub(text, ye2 .. ye, "ई")
text = gsub(text, ye2 .. 'ے', "ए")
text = gsub(text,'([' .. consonants .. '])' .. ye .. ye3, "%1" .. diri .. "ए")
text = gsub(text, alif .. zabar .. ye3, "" .. AI2 .. "")
text = gsub(text, '([' .. consonants .. alif .. '])' .. ye2 .. ye, "%1ई")
text = gsub(text, '([' .. consonants .. '])' .. ye2 .. ye3, "%1ए")
text = gsub(text, zabar .. ye3, "ै")
text = gsub(text, '([' .. consonants .. '])' .. zer .. " ", "%1-ए-")
text = gsub(text, '([' .. consonants .. '])' .. ye3, "%1" .. E .. "")
text = gsub(text, '([' .. consonants .. '])' .. vao, "%1" .. O .. "")
text = gsub(text, '([' .. consonants .. '])' .. ye, "%1" .. diri .. "")
text = gsub(text, alif .. ye .. '([' .. consonants .. '])', "" .. E2 .. "%1")
text = gsub(text, alif .. vao .. '([' .. consonants .. '])', "" .. O2 .. "%1")
-- diacritics
text = gsub(text, "([" .. consonants .. "])" .. zabar .. vao, "%1ौ")
text = gsub(text, "([" .. consonants .. "])" .. zabar .. ye, "%1ै")
text = gsub(text, "([" .. consonants .. "])" .. zabar .. ye3, "%1" .. AI .. "")
text = gsub(text, "([" .. consonants .. "])" .. ye .. "", "%1े")
text = gsub(text, "([" .. consonants .. "])" .. zer .. ye, "%1" .. diri .. "")
-- Vao
text = gsub(text, '([' .. consonants .. '])' .. zabar .. vao .. alif, "%1वा")
text = gsub(text, '([' .. consonants .. '])' .. zabar .. vao .. zabar .. alif, "%1वा")
text = gsub(text, vao .. vao , "वो")
text = gsub(text, vao .. alif , "वा")
text = gsub(text, vao .. zer .. ye .. '([' .. consonants .. '])', "वी%1")
text = gsub(text, vao .. '([' .. ZZP .. '])', "व%1")
--VAO alone
text = gsub(text, " و ", " ओ ")
-- Fatha Majhool --
text = gsub(text, "([" .. consonants .. "])" .. zabar .. he .. jazm .. "([" .. ZZP .. "])" , "%1ह%2")
-- Initial alif
text = gsub(text, "" .. alif .. '([' .. consonantS .. '])', "अ%1")
text = gsub(text, alif .. '([' .. consonantS .. '])', "अ%1")
text = gsub(text, alif .. zabar .. '([' .. consonantS .. '])', "अ%1")
text = gsub(text, alif .. zabar .. vao .. '([' .. consonants .. '])', "औ%1")
text = gsub(text, alif .. vao .. '([' .. consonants .. '])', "ओ%1")
text = gsub(text, alif .. ye .. '([' .. consonants .. '])', "ए%1")
text = gsub(text, alif .. zabar .. ye .. '([' .. consonants .. '])', "ऐ%1")
text = gsub(text, alif .. pesh .. '([' .. consonantS .. '])', "उ%1")
text = gsub(text, alif .. pesh .. vao .. '([' .. consonantS .. '])', "" .. diru2 .. "%1")
text = gsub(text, alif .. zer .. '([' .. consonants .. '])', "इ%1")
text = gsub(text, pesh .. vao, "ू")
text = gsub(text, alif .. zer .. ye.. '([' .. consonants .. '])', "ई%1")
text = gsub(text, alif .. ye3, "" .. E2 .. "")
--- aspirate
text = gsub(text, "(ک)" .. "([" .. ZZP .. "])" .. aspirate, "ख%2")
text = gsub(text, "(گ)" .. "([" .. ZZP .. "])" .. aspirate, "घ%2")
text = gsub(text, "(چ)" .. "([" .. ZZP .. "])" .. aspirate, "छ%2")
text = gsub(text, "(ج)" .. "([" .. ZZP .. "])" .. aspirate, "झ%2")
text = gsub(text, "(ٹ)" .. "([" .. ZZP .. "])" .. aspirate, "ठ%2")
text = gsub(text, "(ڈ)" .. "([" .. ZZP .. "])" .. aspirate, "ढ%2")
text = gsub(text, "(ت)" .. "([" .. ZZP .. "])" .. aspirate, "थ%2")
text = gsub(text, "(د)" .. "([" .. ZZP .. "])" .. aspirate, "ध%2")
text = gsub(text, "(پ)" .. "([" .. ZZP .. "])" .. aspirate, "फ%2")
text = gsub(text, "(ب)" .. "([" .. ZZP .. "])" .. aspirate, "भ%2")
text = gsub(text, "(ڑ)" .. "([" .. ZZP .. "])" .. aspirate, "ढ़%2")
text = gsub(text, "(م)" .. "([" .. ZZP .. "])" .. aspirate, "म्ह%2")
text = gsub(text, "(ن)" .. "([" .. ZZP .. "])" .. aspirate, "न्ह%2")
text = gsub(text, "(ل)" .. "([" .. ZZP .. "])" .. aspirate, "ल्ह%2")
-- final he + short vowel disregards the he and transliterates the vowel
text = gsub(text, "([" .. consonants .. "])" .. he , "%1ह")
text = gsub(text, zabar .. he .. "([" .. ZZP .. "])" , "ह%1")
text = gsub(text, '([' .. zabar .. '])' .. he, "ा")
text = gsub(text, '([' .. consonants .. '])' .. zer .. he .. jazm .. "", "%1िह्") --affects tehvaar
text = gsub(text, '([' .. zer .. '])' .. he, "ि") --affects tehvaar
text = gsub(text, '([' .. zabar .. '])' .. he2 .. " ", "ा-ए-")
text = gsub(text, zabar .. he .. alif , "हा")
text = gsub(text, '([' .. zer .. '])' .. he .. alif .. '([' .. consonants .. '])' , "%1हा%2")
text = gsub(text, he .. alif , "हा")
text = gsub(text, ye .. he .. jazm , "यह")
--
-- vowel hamza's as nouns (issues when in combination with prolonged vowels)
text = gsub(text, '([' .. vao2 .. ye2 .. '])' .. zabar, "अ")
text = gsub(text, '([' .. vao2 .. ye2 .. '])' .. zer, "इ")
text = gsub(text, '([' .. vao2 .. ye2 .. '])' .. pesh, "उ")
text = gsub(text, jazm .. '([' .. vao2 .. ye2 .. '])' .. zabar, "")
text = gsub(text, jazm .. '([' .. vao2 .. ye2 .. '])' .. zer, "ि")
text = gsub(text, jazm .. '([' .. vao2 .. ye2 .. '])' .. pesh, "ु")
--
text = gsub(text, "ۂ ", "-ए-")
text = gsub(text, "ۓ ", "-ये-")
text = gsub(text, "ࣇ", "ळ")
text = gsub(text, "شؕ", "ष")
text = gsub(text, "ڃ", "ञ")
text = gsub(text, "کھ", "ख")
text = gsub(text, "گھ", "घ")
text = gsub(text, "چھ", "छ")
text = gsub(text, "جھ", "झ")
text = gsub(text, "ٹھ", "ठ")
text = gsub(text, "ڈھ", "ढ")
text = gsub(text, "تھ", "थ")
text = gsub(text, 'دھ', "ध")
text = gsub(text, "پھ", "फ")
text = gsub(text, "بھ", "भ")
text = gsub(text, "ڑھ", "ढ़")
text = gsub(text, "مھ", "म्ह")
text = gsub(text, "نھ", "न्ह")
text = gsub(text, "لھ", "ल्ह")
text = gsub(text, "ۂ", "-ए")
text = gsub(text, "ے", "े")
text = gsub(text, '.', mapping)
text = gsub(text, "ललह", "ल्लाह")
text = gsub(text, 'ोा', "वा")
text = gsub(text, 'ौा', "वा")
text = gsub(text, 'ोا', "वा")
text = gsub(text, 'व॑ا', "वा")
text = gsub(text, 'ɔ̄ا', "वा")
-- Changed these to 'iy(*)', because they will be used for with ی, which are normally written as 'iy'
text = gsub(text, 'ी॑ा', "िया")
text = gsub(text, 'ी॑', "िय")
--
text = gsub(text, 'اे', "ए")
text = gsub(text, 'ीا', "िया")
text = gsub(text, 'यا', "या")
-- vao as a medial consonant
text = gsub(text, "ूू॑", "ुुव")
text = gsub(text, "ौ([॑िु])", "व%1")
-- Final corrections
text = gsub(text, "्अ", "") -- related to سَمْعی
text = gsub(text, "अ॑ا", "आ")
text = gsub(text, "ا", "अ") -- to avoid error
text = gsub(text, '॑ि', "इ")
text = gsub(text, '॑े', "ै")
text = gsub(text, '॑ो', "ौ")
text = gsub(text, '्यअ', "्या")
text = gsub(text, "आ॑", "आ")
text = gsub(text, "॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑॑", "आ")
text = gsub(text, "āā", "आ")
text = gsub(text, "aa", "आ")
text = gsub(text, "ë", "ए")
text = gsub(text, "ï", "ई") text = gsub(text, '॑', "")
text = gsub(text, "ीा", "िया")
text = gsub(text, "ाि", "ाइ")
text = gsub(text, "आि", "आइ")
text = gsub(text, 'ुो', "ू")
text = gsub(text, 'िे', "ी")
text = gsub(text, 'ोا', "वा")
text = gsub(text, 'ौا', "वा")
text = gsub(text, 'ौा', "वा")
text = gsub(text, 'ोा', "वा")
text = gsub(text, 'अै', "ऐ")
text = gsub(text, 'ीआ', "िया")
text = gsub(text, 'ीअ', "िय")
text = gsub(text, '+', "")
text = gsub(text, 'اिय', "ई")
text = gsub(text, 'अै', "ऐ")
text = gsub(text, 'अा', "आ")
text = gsub(text, 'अौ', "औ")
text = gsub(text, 'ूा', "ुआ")
return text
end
return export
1px679wfclcykbl93gmiu9qppe7tsys
Modul:pa-Aran-Guru-translit
828
145827
375877
2026-09-25T13:00:31Z
Hakimi97
2668
Mencipta laman baru dengan kandungan 'local U = require("Module:string/char") local gsub = mw.ustring.gsub local ugmatch = mw.ustring.gmatch local export = {} local zabar = U(0x64E) local zer = U(0x650) local pesh = U(0x64F) local tashdid = U(0x651) -- also called shadda local jazm = "ْ" local he = "ہ" local vao2 = "ؤ" local ghunna = U(0x658) local zwnj = U(0x200C) -- Is this even used? Why was it included in the previous version? local highhmz = U(0x654) local dagger_alif = U(0x670)...'
375877
Scribunto
text/plain
local U = require("Module:string/char")
local gsub = mw.ustring.gsub
local ugmatch = mw.ustring.gmatch
local export = {}
local zabar = U(0x64E)
local zer = U(0x650)
local pesh = U(0x64F)
local tashdid = U(0x651) -- also called shadda
local jazm = "ْ"
local he = "ہ"
local vao2 = "ؤ"
local ghunna = U(0x658)
local zwnj = U(0x200C) -- Is this even used? Why was it included in the previous version?
local highhmz = U(0x654)
local dagger_alif = U(0x670)
local consonants = "ببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨوہھٹڈںڑشؕ"
local consonantS = "ببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨہھٹڈںڑشؕ"
local consonantS2 = "یببپتثجچحخدذرزژسشصضطظعغفقکگلࣇمنݨںوہھٹڈڑشؕ"
local sun = "تثصشسزرذدنلطظض"
local punctuation = "%-:%(%)%[%]*&٫؛؟،ـ«\".\'!»٪؉۔"
local diacritics = "َُِّْٰ"
local ZZP = "َُِ"
local ZZPJ = "َُِْ"
local sih = "ਿ"
local aun = "ੁ"
local addhak = "ੱ"
local nvowel = "ں"
local semivowel = "یو"
local vowels = "āایئےۓوؤ"
local indvowels = "آایےوؤ"
local hes = "ہح"
local lrm = U(0x200e) -- left-to-right mark
local rlm = U(0x200f) -- right-to-left mark
local numbers = "۱۲۳۴۵۶۷۸۹۰"
local initGurVowl = "ਔਐਆਈਊਉਏਓ"
local consonants_needing_vowels = "ببپتثجچحخدذرزژسشصضطظعغفقکڷگلࣇمنںݨہئٹڈڑءﷲ"
local rconsonants = consonants_needing_vowels .. "ویآ" -- consonants on the right side; includes alif madda
local lconsonants = consonants_needing_vowels -- consonants on the left side; does not include alif madda
local space_like = "%s'" .. '"'
local space_like_class = "[" .. space_like .. "]"
local ain = "ع"
local khzab = "ٰ"
local alif = "ا"
local madda = "آ"
local ye = "ی"
local ye2 = "ئ"
local ye3 = "ے"
local vao = "و"
local ye4 = "ۓ"
local he2 = "ۂ"
local aspirate = "ھ"
local lam = "ل"
local noon = "ن"
local gunDia = "٘"
local bvow = "ای"
local nghun = "ن٘"
local mapping = {
["آ"] = "ਆ", ["ب"] = "ਬ", ["پ"] = "ਪ",
["ت"] = "ਤ", ["ٹ"] = "ਟ", ["ث"] = "ਸ",
["ج"] = "ਜ", ["چ"] = "ਚ", ["ح"] = "ਹ",
["خ"] = "ਖ਼", ["د"] = "ਦ", ["ڈ"] = "ਡ",
["ذ"] = "ਜ਼", ["ر"] = "ਰ", ["ڑ"] = "ੜ",
["ز"] = "ਜ਼", ["ژ"] = "ਝ਼", ["س"] = "ਸ",
["ش"] = "ਸ਼", ["ص"] = "ਸ", ["ض"] = "ਜ਼",
["ط"] = "ਤ", ["ظ"] = "ਜ਼", ["غ"] = "ਗ਼",
["ف"] = "ਫ਼", ["ق"] = "ਕ਼", ["ک"] = "ਕ", ["ك"] = "ਕ",
["گ"] = "ਗ", ["ل"] = "ਲ", ["ࣇ"] = "ਲ਼", ["م"] = "ਮ",
["ن"] = "ਨ", ["ݨ"] = "ਣ", ["و"] = "ਵ", ["ہ"] = "ਹ", ["ۃ"] = "ਤ", ["ی"] = "ਯ", ["ں"] = "ਂ",
["ع"] = "ਅ",
["ء"] = "",
["ؤ"] = "ਓ",
["أ"] = "",
-- diacritics
[zabar] = "",
[zer] = sih,
[pesh] = aun,
-- [jazm] = halant,
[jazm] = "",
[U(0x200C)] = "-", -- ZWNJ (zero-width non-joiner)
-- ligatures
["ﻻ"] = "ਲਾ",
["ﷲ"] = "ਅੱਲਾਹ",
-- kashida
["ـ"] = "-", -- kashida, no sound
-- numerals
["١"] = "1", ["٢"] = "2", ["٣"] = "3", ["٤"] = "4", ["٥"] = "5",
["٦"] = "6", ["٧"] = "7", ["٨"] = "8", ["٩"] = "9", ["٠"] = "0",
-- punctuation
["۔"] = "।",
["؟"] = "?",
["،"] = ",",
["؛"] = ";",
["«"] = "“",
["»"] = "”",
["٪"] = "%",
["؉"] = "‰",
["٫"] = ".",
["٬"] = ",",
["ۓ"] = "-ਯੇ",
["ۂ"] = "-ਏ", -- he ye (in ezâfe)
}
local asp = {
["ک"] = "ਖ",
["گ"] = "ਘ",
["چ"] = "ਛ",
["ج"] = "ਝ",
["ٹ"] = "ਠ",
["ڈ"] = "ਢ",
["ت"] = "ਥ",
["د"] = "ਧ",
["پ"] = "ਫ",
["ب"] = "ਭ",
["ڑ"] = "ੜ੍ਹ",
["م"] = "ਮ੍ਹ",
["ن"] = "ਨ੍ਹ",
["ل"] = "ਲ੍ਹ",
["ݨ"] = "ਣ੍ਹ",
["ࣇ"] = "ਲ਼੍ਹ"
}
local asp_vowel_rules = {
{pesh .. aspirate .. vao, "ੂ"},
{aspirate .. vao, "ੋ"},
{aspirate .. ye3, "ੇ"},
{zabar .. aspirate .. ye3, "ੈ"},
{zabar .. aspirate .. vao, "ੌ"},
{zabar .. aspirate .. alif, "ਾ"},
{aspirate .. alif, "ਾ"},
{zer .. aspirate .. ye, "ੀ"},
{aspirate .. ye .. "#", "ੀ"},
}
local has_diacritics_subs = {
-- remove arabic ye (ruins conversions)
{"لل" .. he, ""},
{"لل" .. tashdid .. he, ""},
{"لل" .. tashdid .. dagger_alif .. he, ""},
{"ۃ", ""},
-- aspirated consonants should cound as 1 consonant not two
{"([" .. consonants .. "][" .. ZZP .. diacritics .. "?])" .. aspirate, "%1"},
{"([" .. consonants .. "])" .. aspirate, "%1"},
{aspirate, ""},
-- remove punctuation and tashdid
{"[" .. punctuation .. tashdid .. highhmz .. zwnj .. numbers .. "]", ""},
-- noon gunna and silent consonants can be removed
{".. [" .. ZZP .. indvowels .. diacritics .. "?] .. ([" .. consonantS2 .. "])" .. "([" .. ghunna .. jazm .. "])" .. "([" .. consonantS2 .. "])", ""},
{"([" .. consonants .. "])" .. ghunna, ""},
{"([" .. consonantS2 .. "])" .. jazm, ""},
{"([" .. consonantS2 .. "])" .. "یٰ", ""},
-- must go before removing final consonants
{"[" .. ZZP .. diacritics .. "]" .. alif, alif},
{fatHataan, ""},
{"([" .. consonantS2 .. "])" .. "[" .. ZZP .. diacritics .. indvowels .. "?]" .. "([ںۓۂۂ])", ""},
{"([ںۓۂۂ])", ""},
{"([" .. ye .. alif .. "])" .. dagger_alif, alif},
{dagger_alif .. ye, alif},
{alif .. "[" .. ZZP .. diacritics .. "]", ""},
{"[" .. ZZP .. diacritics .. "]" .. alif, alif},
{dagger_alif .. "([" .. ye .. alif .. "])", alif},
-- Remove consonants at end of word or utterance, so that we're OK with
-- words lacking iʿrāb (must go before removing other consonants).
-- If you want to catch places without iʿrāb, comment out the next two lines.
{"[" .. lconsonants .. "]$", ""},
-- closed consonants
{"([" .. consonantS2 .. "])[" .. indvowels .. ZZP .. "]", ""},
-- remove consonants (or alif) when followed by diacritics
-- must go after removing tashdid
-- do not remove the diacritics yet because we need them to handle
}
local function apply_rules(text, rules)
for _, rule in ipairs(rules) do
text = gsub(text, rule[1], rule[2])
end
return text
end
local function mark_word_boundaries(text)
text = gsub(text, "#", "HASHTAG")
text = gsub(text, " | ", "# | #")
text = gsub(text, "\n", "#\n#")
text = gsub(text, "([" .. punctuation .. "])", "#%1#")
text = "##" .. gsub(text, " ", "# #") .. "##"
text = gsub(text, zwnj, "#" .. zwnj .. "#")
return text
end
local function unmark_word_boundaries(text)
text = gsub(text, "#", "")
text = gsub(text, "HASHTAG", "#")
return text
end
local reformatting_rules = {
{"ۂ", he .. highhmz},
{highhmz, "#" .. highhmz .. "#"},
}
local exception_rules = {
{"کِہ" .. "#", "ਕਿ"},
}
local nasalisation_rules = {
{"([" .. bvow .. "])" .. nghun .. "ہہ", "%1ਂਹ"},
{"([" .. vao .. "])" .. nghun .. "ہہ", "%1ੰਹ"},
{"آن٘([کگجچٹڈتدن])", "ਆਂ%1"},
{"ن٘([ہو])", "ੰ%1"},
{"نْ([کگجچٹڈتدن])", "ੰ%1"},
{"ن٘([کگجچٹڈتدن])", "ੰ%1"},
{"مْ([بپمو])", "ੰ%1"},
{"ں" .. "#", "ੰ"},
{"ہہ", "ਹ"},
{ye .. jazm .. alif, "ਿਆ"},
}
local tashdid_rules = {
{"([" .. consonants .. "])" .. tashdid, addhak .. "%1"},
{"([" .. ZZP .. "])" .. ye .. pesh .. tashdid .. vao, "%1ੱਯੂ"}, -- qayyum
{"([" .. ZZP .. "])" .. ye .. tashdid .. vao, "%1ੱਯੋ"}, -- qayyom
{"([" .. ZZP .. "])" .. ye .. "([" .. ZZP .. "])" .. tashdid, "%1ੱਯ%2"},
{"([" .. ZZP .. "])" .. ye .. "([" .. zer .. zabar .. "])" .. tashdid, "%1ੱਯ%2"},
-- For some reason the tashdeed gets pushed after the other diacritics, so this line is necessary for tashdeed to work with other diacritics
{"([" .. consonants .. "])" .. "([" .. ZZP .. "])" .. tashdid, addhak .. "%1%2"},
}
local vowel_as_consonant_rules = {
{"([" .. ZZP .. "])" .. tashdid .. vao, "%1ੱੰਵ"},
{vao .. zabar .. alif, "ਵਾ"},
{vao .. "([" .. ZZP .. "])", "ਵ%1"},
{"([" .. consonants .. "])" .. zer .. ye .. zabar .. vao, "%1ਿਯੌ"},
{"([" .. consonants .. "])" .. zer .. ye .. vao, "%1ੀਓ"},
{"([" .. consonants .. "])" .. zer .. ye .. pesh .. vao, "%1ਿਊ"},
{"([" .. consonants .. "])" .. ye .. vao, "%1ਿਓ"},
{"([" .. consonants .. "])" .. ye .. pesh .. vao, "%1ਿਊ"},
{ye .. pesh .. vao, "ਯੂ"},
{ye .. zabar .. alif, "ਯਾ"},
{ye .. zabar, "ਯ"},
}
local function apply_aspirates(text)
for c, gur in pairs(asp) do
for _, rule in ipairs(asp_vowel_rules) do
text = gsub(text, c .. rule[1], gur .. rule[2])
end
-- short vowel mark after c + aspirate
text = gsub(text, c .. "([" .. ZZPJ .. "])" .. aspirate, gur .. "%1")
-- plain c + aspirate
text = gsub(text, c .. aspirate, gur)
end
return text
end
local function apply_al_article(text)
-- Only treat alif + lam as the Arabic definite article if:
-- 1. lam has jazm: الْ
-- 2. the following sun letter has tashdid: السَّلام / الشَّمْس
--
-- Do not allow zabar on alif here. This prevents words like اَلفاظ
-- from being treated as Arabic definite-article forms.
local article_base = alif .. lam
local article_with_jazm = article_base .. jazm
-- Sun-letter article:
-- Match both possible mark orders after the sun letter:
-- سَّ = c + tashdid + vowel mark
-- شَّ = c + vowel mark + tashdid
for c in ugmatch(sun, ".") do
local gur = mapping[c]
if gur then
-- word-initial: السَّلام / الشَّمْس
text = gsub(
text,
"#" .. article_base .. c .. tashdid .. "([" .. ZZP .. "])",
"#ਅ" .. gur .. "-" .. c .. "%1"
)
text = gsub(
text,
"#" .. article_base .. c .. "([" .. ZZP .. "])" .. tashdid,
"#ਅ" .. gur .. "-" .. c .. "%1"
)
text = gsub(
text,
"#" .. article_base .. c .. tashdid,
"#ਅ" .. gur .. "-" .. c
)
-- after pesh before a space: بَیتُ السَّلام
text = gsub(
text,
pesh .. "# #" .. article_base .. c .. tashdid .. "([" .. ZZP .. "])",
"-ਉ" .. gur .. "-" .. c .. "%1"
)
text = gsub(
text,
pesh .. "# #" .. article_base .. c .. "([" .. ZZP .. "])" .. tashdid,
"-ਉ" .. gur .. "-" .. c .. "%1"
)
text = gsub(
text,
pesh .. "# #" .. article_base .. c .. tashdid,
"-ਉ" .. gur .. "-" .. c
)
end
end
-- Non-sun / explicit-lam article:
-- only if lam has jazm: الْمُقَدَّس
text = gsub(
text,
"#" .. article_with_jazm .. "([" .. consonants .. "])",
"#ਅਲ-%1"
)
text = gsub(
text,
pesh .. "# #" .. article_with_jazm .. "([" .. consonants .. "])",
"-ਉਲ-%1"
)
return text
end
local initial_alif_rules = {
{"#" .. "آ", "ਆ"},
{"#" .. alif .. zabar .. ye3, "ਐ"},
{"#" .. alif .. zabar .. ye, "ਐ"},
{"#" .. alif .. zabar .. vao, "ਔ"},
{"#" .. alif .. pesh .. vao, "ਊ"},
{"#" .. alif .. zabar, "ਅ"},
{"#" .. alif .. zer .. ye, "ਈ"},
{"#" .. alif .. zer, "ਇ"},
{"#" .. alif .. pesh, "ਉ"},
{"#" .. alif .. ye .. "#", "ਈ"},
{"#" .. alif .. ye, "ਏ"},
{"#" .. alif .. ye3, "ਏ"},
{"#" .. alif .. vao, "ਓ"},
}
local alif_rules = {
{"([" .. consonants .. "])" .. zabar .. alif, "%1ਾ"},
{"([" .. consonantS2 .. "])" .. alif, "%1ਾ"},
{"(" .. ghunna .. ")" .. alif, "%1ਾ"},
{"([" .. diacritics .. "])" .. alif, "%1"},
{"([" .. ZZP .. "])" .. alif, "%1"},
}
local ain_rules = {
{"#" .. ain .. alif, "ਆ"},
{ain .. zer .. ye, "ਈ"},
{ain .. zabar .. vao, "ਔ"},
{ain .. pesh .. vao, "ਊ"},
{ain .. zabar .. ye, "ਐ"},
{"#" .. ain .. zabar, "ਅ"},
{"#" .. ain .. zer, "ਇ"},
{"#" .. ain .. pesh, "ਉ"},
{"#" .. ain .. vao, "ਓ"},
}
local tanween_rules = {
{"([" .. consonants .. "])ً" .. alif, "%1ਨ"},
{alif .. "ً", "ਨ"},
{"([" .. consonants .. "])ً", "%1ਨ"},
}
local khari_zabar_rules = {
-- consonant + jazm + succeeding vowel + khari zabar
{"([" .. consonants .. "])" .. jazm .. "([" .. indvowels .. ye .. vao .. ye3 .. "])" .. khzab, "%1ਾ"},
-- existing khari zabar rules
{"([" .. consonants .. "])" .. khzab .. "([" .. ye .. vao .. "])", "%1ਾ"},
{"([" .. consonants .. "])" .. khzab, "%1ਾ"},
{"([" .. vowels .. "])" .. khzab, "ਾ"},
}
local medial_final_rules = {
{"([" .. consonants .. "])" .. ye .. "#", "%1ੀ"},
{"([" .. consonants .. "])" .. zer .. ye, "%1ੀ"},
{"([" .. consonants .. "])" .. zabar .. ye3, "%1ੈ"},
{"([" .. consonants .. "])" .. ye3, "%1ੇ"},
{"([" .. consonants .. "])" .. vao, "%1ੋ"},
{"([" .. consonants .. "])" .. zabar .. vao, "%1ੌ"},
{"([" .. consonants .. "])" .. pesh .. vao, "%1ੂ"},
}
local medial_ye_rules = {
{zabar .. ye, "ੈ"},
{"([" .. consonants .. "])" .. ye, "%1ੇ"},
}
local hamza_ye_rules = {
{ye2 .. zer .. ye .. ye3, "ਈਏ"},
{ye2 .. ye3, "ਏ"},
{ye2 .. zer .. ye, "ਈ"},
{ye2 .. zer .. ye .. "#", "ਇ"},
{ye2 .. ye, "ਈ"},
}
local final_he_rules = {
{zabar .. he .. jazm .. "#", "ਹ"},
{zabar .. he .. "#", "ਾ"},
}
local pre_mapping_cleanup_rules = {
{"ࣇ", "ਲ਼"},
{aspirate, "੍ਹ"},
}
local final_correction_rules = {
{"ੱਨ", "ੰਨ"}, -- double n in guru
{"([" .. initGurVowl .. "])ੰ", "%1ਂ"},
{"ੇਾ", "ਿਆ"},
{"ੀਾ", "ੀਆ"},
{"ੋੰ", "ੋਂ"},
{"ੇੰ", "ੇਂ"},
{"ੌੰ", "ੌਂ"},
{"ੈੰ", "ੈਂ"},
{"ਾੰ", "ਾਂ"},
{"ਆੰ", "ਆਂ"},
{"ੈਾ", "ਯਾ"},
{"ਈਾ", "ਈਆ"},
}
function export.tr(text, lang, sc)
text = mark_word_boundaries(text)
-- character reformatting
-- to make an exceptions for a word, put hashtags on both sides
text = apply_rules(text, reformatting_rules)
text = apply_rules(text, exception_rules)
-- SSH / nasalisation
text = apply_rules(text, nasalisation_rules)
-- al-/ul- article handling
text = apply_al_article(text)
-- fathan
text = gsub(text, "([" .. consonants .. "])" .. alif .. "ً", "%1ਨ")
-- tashdid
text = apply_rules(text, tashdid_rules)
-- e, instead of i
-- text = gsub(text, jazm .. "([" .. consonants .. "])" .. zer .. "([" .. consonants .. "])", "੍%1" .. E .. "%2")
-- vowels as cons
text = apply_rules(text, vowel_as_consonant_rules)
-- aspirate: intentionally before the general medial/final vowel rules
text = apply_aspirates(text)
-- initial alif
text = apply_rules(text, initial_alif_rules)
text = apply_rules(text, alif_rules)
-- ain
text = apply_rules(text, ain_rules)
-- tanween diacritic
text = apply_rules(text, tanween_rules)
-- Zammah Majhool --
-- text = gsub(text, "([" .. consonants .. "])" .. pesh .. he, "%1ੋ") -- affects voh
-- khari zabar
text = apply_rules(text, khari_zabar_rules)
-- medial/final endings
text = apply_rules(text, medial_final_rules)
-- medial ye
text = apply_rules(text, medial_ye_rules)
-- hamza ye
text = apply_rules(text, hamza_ye_rules)
-- final he
text = apply_rules(text, final_he_rules)
text = apply_rules(text, pre_mapping_cleanup_rules)
-- Everything above this line works mostly on source-script letters.
text = gsub(text, ".", mapping)
-- Everything below this line works on the output-script text.
-- final corrections
text = apply_rules(text, final_correction_rules)
text = unmark_word_boundaries(text)
return text
end
return export
j8vjn07lkdo6h3rv1z8cswikgpet5ln
Kategori:en:Kawasan di Asia
14
145828
375886
2026-09-25T13:35:32Z
Hakimi97
2668
Hakimi97 telah memindahkan laman [[Kategori:en:Kawasan di Asia]] ke [[Kategori:en:Tempat di Asia]]: Tajuk salah eja
375886
wikitext
text/x-wiki
#LENCONG [[:Kategori:en:Tempat di Asia]]
4vzo2vwcot3otk6eql0b3j04x6zg6hs
Rekonstruksi:Bahasa Jermanik Purba/fuhsaz
110
145829
375901
2026-09-26T07:13:44Z
SNN95
2113
Mencipta laman baru dengan kandungan '{{reconstructed}} ==Bahasa Jermanik Purba== ===Etimologi=== {{etymon|gem-pro|id=Q8331|:inh|ine-pro:*púḱsos<id:?>}} Daripada {{inh|gem-pro|ine-pro|*púḱsos||yang berekor}}. Kognat dengan{cog|sa|पुच्छ|tr=púccha|t=ekor, batang}},<ref name="EDPG">{{R:gem:EDPG|pages=157-8|head=*fuhsa-}}</ref> {{cog|ae|𐬞𐬎𐬯𐬀}}. ===Sebutan=== * {{IPA|gem-pro|/ˈɸux.sɑz/}} ===Kata nama=== {{gem-noun|m}}<ref name="EDPG" />{{tlb|gem-pro|Jermanik B...'
375901
wikitext
text/x-wiki
{{reconstructed}}
==Bahasa Jermanik Purba==
===Etimologi===
{{etymon|gem-pro|id=Q8331|:inh|ine-pro:*púḱsos<id:?>}}
Daripada {{inh|gem-pro|ine-pro|*púḱsos||yang berekor}}. Kognat dengan{cog|sa|पुच्छ|tr=púccha|t=ekor, batang}},<ref name="EDPG">{{R:gem:EDPG|pages=157-8|head=*fuhsa-}}</ref> {{cog|ae|𐬞𐬎𐬯𐬀}}.
===Sebutan===
* {{IPA|gem-pro|/ˈɸux.sɑz/}}
===Kata nama===
{{gem-noun|m}}<ref name="EDPG" />{{tlb|gem-pro|Jermanik Barat}}
# [[musang]]
====Infleksi====
{{gem-decl-noun}}
====Perkataan berkaitan====
* {{l|gem-pro|*fuhsinī|gloss=vixen}}
* {{l|gem-pro|*fuhǭ|gloss=vixen}}
====Turunan====
* {{desctree|gmw-pro|*fuhs}}
===Lihat juga===
* {{l+|gmq-pro|*rebaʀ|t=fox}}
===Rujukan===
{{reflist}}
{{C|gem-pro|Musang}}
sc6ry8r5dy56gv6hrm8zn4wols2632p
375902
375901
2026-09-26T07:14:13Z
SNN95
2113
375902
wikitext
text/x-wiki
{{reconstructed}}
==Bahasa Jermanik Purba==
===Etimologi===
{{etymon|gem-pro|id=Q8331|:inh|ine-pro:*púḱsos<id:?>}}
Daripada {{inh|gem-pro|ine-pro|*púḱsos||yang berekor}}. Kognat dengan {{cog|sa|पुच्छ|tr=púccha|t=ekor, batang}},<ref name="EDPG">{{R:gem:EDPG|pages=157-8|head=*fuhsa-}}</ref> {{cog|ae|𐬞𐬎𐬯𐬀}}.
===Sebutan===
* {{IPA|gem-pro|/ˈɸux.sɑz/}}
===Kata nama===
{{gem-noun|m}}<ref name="EDPG" />{{tlb|gem-pro|Jermanik Barat}}
# [[musang]]
====Infleksi====
{{gem-decl-noun}}
====Perkataan berkaitan====
* {{l|gem-pro|*fuhsinī|gloss=vixen}}
* {{l|gem-pro|*fuhǭ|gloss=vixen}}
====Turunan====
* {{desctree|gmw-pro|*fuhs}}
===Lihat juga===
* {{l+|gmq-pro|*rebaʀ|t=fox}}
===Rujukan===
{{reflist}}
{{C|gem-pro|Musang}}
k1e901g1qe43a5dnub6dpbb8oe0nqwe
telayang
0
145830
375903
2026-09-26T07:19:09Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} tertidur sebentar krn rasa kantuk yg tak tertahankan<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Dio telayang sekojap di mantoka.|dia tertidur sebentar di mobil.}}'
375903
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} tertidur sebentar krn rasa kantuk yg tak tertahankan<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Dio telayang sekojap di mantoka.|dia tertidur sebentar di mobil.}}
7ar2xwoowoj3akk51dgr7ccpd5t081j
luncek
0
145831
375907
2026-09-26T07:35:27Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Luncek=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hulu}} Lompat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|moh kito luncek sesamo.|ayo kita loncat bersama-sama.}}'
375907
wikitext
text/x-wiki
==Bahasa Melayu==
===Luncek===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} Lompat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|moh kito luncek sesamo.|ayo kita loncat bersama-sama.}}
0vo5s4tr8n2brnalrnovacplfxaoucb
tobeh
0
145832
375908
2026-09-26T07:38:01Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Tobeh=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hullu}} tebas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku nak tobeh somak tu.|aku mau menebas semak itu.}}'
375908
wikitext
text/x-wiki
==Bahasa Melayu==
===Tobeh===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hullu}} tebas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku nak tobeh somak tu.|aku mau menebas semak itu.}}
lv71xwv63p3ts2ldp6o98g6aeqanugs
somak
0
145833
375909
2026-09-26T07:39:54Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===somak=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hulu}} semak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|awas mauk somak tu.|awas masuk semak itu.}}'
375909
wikitext
text/x-wiki
==Bahasa Melayu==
===somak===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} semak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|awas mauk somak tu.|awas masuk semak itu.}}
domwq107ibe9lnqnzwycbhgss14efke
Modul:gem-headword
828
145834
375910
2026-09-26T07:41:01Z
SNN95
2113
Mencipta laman baru dengan kandungan 'local export = {} local lang = require("Module:languages").getByCode("gem-pro") -- The main entry point. -- This is the only function that can be invoked from a template. function export.show(frame) local args = frame:getParent().args SUBPAGENAME = mw.loadData("Module:headword/data").pagename local head = args["head"]; if head == "" then head = nil end -- The part of speech. This is also the name of the category that -- entries go in. Howeve...'
375910
Scribunto
text/plain
local export = {}
local lang = require("Module:languages").getByCode("gem-pro")
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local args = frame:getParent().args
SUBPAGENAME = mw.loadData("Module:headword/data").pagename
local head = args["head"]; if head == "" then head = nil end
-- The part of speech. This is also the name of the category that
-- entries go in. However, the two are separate (the "cat" parameter)
-- because you sometimes want something to behave as an adjective without
-- putting it in the adjectives category.
local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
local postype = args["type"]; if postype == "" then postype = nil end
local data = {lang = lang, pos_category = (postype and postype .. " " or "") .. poscat, categories = {}, heads = {head}, genders = {}, inflections = {}}
if poscat == "kata sifat" then
if SUBPAGENAME:find("^-") then
data.pos_category = "akhiran"
data.categories = {"Akhiran pembentuk kata adjektif bahasa Jermanik Purba"}
end
adjective(args, data)
elseif poscat == "kata adverba" then
if SUBPAGENAME:find("^-") then
data.pos_category = "akhiran"
data.categories = {"Akhiran pembentuk kata adverba bahasa Jermanik Purba"}
end
adverb(args, data)
elseif poscat == "kata penunjuk" then
adjective(args, data)
elseif poscat == "kata nama" then
if SUBPAGENAME:find("^-") then
data.pos_category = "akhiran"
data.categories = {"Akhiran pembentuk kata nama bahasa Jermanik Purba"}
end
noun_gender(args, data)
elseif poscat == "kata nama khas" then
noun_gender(args, data)
elseif poscat == "kata kerja" then
if SUBPAGENAME:find("^-") then
data.pos_category = "akhiran"
data.categories = {"Akhiran pembentuk kata kerja bahasa Jermanik Purba"}
end
end
return require("Module:headword").full_headword(data)
end
-- Display information for a noun's gender
-- This is separate so that it can also be used for proper nouns
function noun_gender(args, data)
local valid_genders = {
["m"] = true,
["f"] = true,
["n"] = true,
["m-p"] = true,
["f-p"] = true,
["n-p"] = true}
-- Iterate over all gn parameters (g2, g3 and so on) until one is empty
local g = args[1] or ""; if g == "" then g = "?" end
local i = 2
while g ~= "" do
if not valid_genders[g] then
g = "?"
end
-- If any of the specifications is a "?", add the entry
-- to a cleanup category.
if g == "?" then
table.insert(data.categories, "Permintaan untuk jantina dalam lema bahasa Jermanik Purba")
elseif g == "m-p" or g == "f-p" or g == "n-p" then
table.insert(data.categories, "pluralia tantum bahasa Jermanik Purba")
end
table.insert(data.genders, g)
g = args["g" .. i] or ""
i = i + 1
end
end
function adjective(args, data)
local adverb = args["adv"]; if adverb == "" then adverb = nil end
local comparative = args[1]; if comparative == "" then comparative = nil end
local superlative = args[2]; if superlative == "" then superlative = nil end
if adverb then
table.insert(data.inflections, {label = "kata adverba", adverb})
end
if comparative then
table.insert(data.inflections, {label = "bentuk perbandingan", comparative})
end
if superlative then
table.insert(data.inflections, {label = "bentuk superlatif", superlative})
end
end
function adverb(args, data)
local adjective = args["adj"]; if adjective == "" then adjective = nil end
local comparative = args[1]; if comparative == "" then comparative = nil end
local superlative = args[2]; if superlative == "" then superlative = nil end
if adjective then
table.insert(data.inflections, {label = "kata adjektif", adjective})
end
if comparative then
table.insert(data.inflections, {label = "bentuk perbandingan", comparative})
end
if superlative then
table.insert(data.inflections, {label = "bentuk superlatif", superlative})
end
end
return export
7c5jq3vqw5w118vang71k3hvzxra1qy
hontam
0
145835
375915
2026-09-26T07:52:13Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===hontam=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hulu}} hantam <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku hontam bang ko.|ku hantam kau nanti.}}'
375915
wikitext
text/x-wiki
==Bahasa Melayu==
===hontam===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} hantam <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku hontam bang ko.|ku hantam kau nanti.}}
7250sz60iakht6b4rp8sb0bu3isd6aa
celoteh
0
145836
375918
2026-09-26T07:55:41Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Dumai}} Celoteh <!--menggerutuk--> #: {{cp|ms|tak penat celoteh?.|kamu tidak capek menggerutuk terus?.}}'
375918
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Dumai}} Celoteh <!--menggerutuk-->
#: {{cp|ms|tak penat celoteh?.|kamu tidak capek menggerutuk terus?.}}
3wxhyvp2e0f87h66tnyf5eafaf0ol52
kondiok
0
145837
375919
2026-09-26T07:56:57Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===kondiok=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hulu}} babi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tengok tu ado kondiok.|lihat tuh ada babi.}}'
375919
wikitext
text/x-wiki
==Bahasa Melayu==
===kondiok===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} babi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tengok tu ado kondiok.|lihat tuh ada babi.}}
rxmjjeow3ent591p4le2ilzkio6ehsn
telungkup
0
145838
375920
2026-09-26T07:59:17Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}}telungkup<!--terjatuh--> #: {{cp|ms|budak ni telungkup kat kamar mandi?.|anak itu terjatuh di kamar mandi.}}'
375920
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}}telungkup<!--terjatuh-->
#: {{cp|ms|budak ni telungkup kat kamar mandi?.|anak itu terjatuh di kamar mandi.}}
k5tcu02abuplwsb0okwjnp5hmff5q64
tejungkang
0
145839
375921
2026-09-26T07:59:44Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Dumai}} Tejungkang <!--terjatuh--> #: {{cp|ms| ngapo budak tu tejungkang?.|kenapa anak itu terjatuh?.}}'
375921
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Dumai}} Tejungkang <!--terjatuh-->
#: {{cp|ms| ngapo budak tu tejungkang?.|kenapa anak itu terjatuh?.}}
1d1frhhdhz37mur1t0ixwk97wywfsx9
madak
0
145840
375925
2026-09-26T08:02:39Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===madak=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan hulu}} bodoh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu madak.|orang itu bodoh.}}'
375925
wikitext
text/x-wiki
==Bahasa Melayu==
===madak===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan hulu}} bodoh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu madak.|orang itu bodoh.}}
a1ey5zipml85ftow8oabb0l4ev704i9
Templat:gem-noun
10
145841
375926
2026-09-26T08:03:27Z
SNN95
2113
Mencipta laman baru dengan kandungan '{{#invoke:gem-headword|show|kata nama}}<!-- --><noinclude>{{documentation}}</noinclude>'
375926
wikitext
text/x-wiki
{{#invoke:gem-headword|show|kata nama}}<!--
--><noinclude>{{documentation}}</noinclude>
2mwjbc4hcuy46kgen2r4kcsvu9asrw7
tumpou
0
145842
375927
2026-09-26T08:04:01Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Dumai}} Tumpuo <!--hancur lebur--> #: {{cp|ms|tumpuo lah baghang tu!.|hancur lebur lah barang itu.}}'
375927
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Dumai}} Tumpuo <!--hancur lebur-->
#: {{cp|ms|tumpuo lah baghang tu!.|hancur lebur lah barang itu.}}
32jfmynwvdri1ai6c0yi1yci2mepgc2
mengayau
0
145843
375928
2026-09-26T08:04:47Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} Mengayau <!--Keluyuran--> #: {{cp|ms|aku nak mengayau.|aku mau keluyuran.}}'
375928
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} Mengayau <!--Keluyuran-->
#: {{cp|ms|aku nak mengayau.|aku mau keluyuran.}}
72dvg4yzj3hv5szcbxophrexl03j40h
376113
375928
2026-09-26T09:01:33Z
Robiyatuladawiyah05
11514
/* Kata Kerja */
376113
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} Keluyuran <!--Keluyuran-->
#: {{cp|ms|aku nak mengayau.|aku mau keluyuran.}}
jisoqkdftlp7rhehtk8kedfxeeynuyh
soak
0
145844
375929
2026-09-26T08:04:58Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Bengkalis}} soak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|baju aku soak.|baju aku sobek?.}}'
375929
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Bengkalis}} soak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|baju aku soak.|baju aku sobek?.}}
tskzgbpaue4jbendhp3z6l01spd5z68
kusal
0
145845
375931
2026-09-26T08:06:33Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===kusal=== {{lb|ms|kata benda}} # {{lb|ms|Bengkalis}} kayu bakau <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu menebang kusal.|orang itu menebang kayu bakau.}}'
375931
wikitext
text/x-wiki
==Bahasa Melayu==
===kusal===
{{lb|ms|kata benda}}
# {{lb|ms|Bengkalis}} kayu bakau <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu menebang kusal.|orang itu menebang kayu bakau.}}
ccnt8o8m9teii09zu1resg0lznm7qdg
kayat
0
145846
375932
2026-09-26T08:07:43Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Kampar}} kayat <!--nyanyian tradisional--> #: {{cp|ms|malin suguhkan kayat?.|malin menampilkan kayat?.}}'
375932
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Kampar}} kayat <!--nyanyian tradisional-->
#: {{cp|ms|malin suguhkan kayat?.|malin menampilkan kayat?.}}
idh4hn3jfd3hbs4tmjq0r4weuwrq7lq
mengkek
0
145847
375933
2026-09-26T08:08:52Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}}mengkek<!--manja--> #: {{cp|ms|mengkek betul jam ini semuo?.|manja sekali sekarang juga.}}'
375933
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}}mengkek<!--manja-->
#: {{cp|ms|mengkek betul jam ini semuo?.|manja sekali sekarang juga.}}
ac302l81d64ifwdr3mdz2afuohlhvox
kedekot
0
145848
375934
2026-09-26T08:10:22Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} kedekot <!--pelit--> #: {{cp|ms|ughang tu kedekot betol.|orang itu pelit sekali.}}'
375934
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} kedekot <!--pelit-->
#: {{cp|ms|ughang tu kedekot betol.|orang itu pelit sekali.}}
33h8tglwptput92nsop35saoim0ni95
melou
0
145849
375935
2026-09-26T08:11:06Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Kerja=== {{lb|ms|kata Kerja}} # {{lb|ms|Dumai}} Melou <!--Mada--> #: {{cp|ms|budak ni melou betul.|anak ini mada sekali.}}'
375935
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Kerja===
{{lb|ms|kata Kerja}}
# {{lb|ms|Dumai}} Melou <!--Mada-->
#: {{cp|ms|budak ni melou betul.|anak ini mada sekali.}}
qk0w4x8ahcbv3s4079v0v9g68vl0vk6
gedau
0
145850
375936
2026-09-26T08:11:14Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} gedau <!--gatal--> #: {{cp|ms|budak tuitu gedau kali.|anak itu gatal sekali.}}'
375936
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} gedau <!--gatal-->
#: {{cp|ms|budak tuitu gedau kali.|anak itu gatal sekali.}}
2kzw2c56ifzjnc6ipfgaeouom0r6e85
debo
0
145851
375937
2026-09-26T08:11:17Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|mb|kata sifat}} # {{lb|mb|Bengkalis}} debo <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku bedebo?.|aku berdebar.}}'
375937
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|mb|kata sifat}}
# {{lb|mb|Bengkalis}} debo <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku bedebo?.|aku berdebar.}}
ricklbyahr0990umccnyeuxed5ciz1r
375943
375937
2026-09-26T08:14:05Z
Elvaretta Vito
11512
/* Kata sifat */
375943
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Bengkalis}} debo <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku bedebo.|aku berdebar.}}
2a8noa9rurwqb17vbl9mxtuqnw2d8js
guyir
0
145852
375938
2026-09-26T08:11:18Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} guyir <!—-mudah rapuh--> #: {{cp|ms|kayu tu dah guyir.|kayu sudah rapuh.}}'
375938
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} guyir <!—-mudah rapuh-->
#: {{cp|ms|kayu tu dah guyir.|kayu sudah rapuh.}}
9k65h8lvbk9fy1ye2qendwa9xnxuq19
375942
375938
2026-09-26T08:12:16Z
Yosi fadila
11515
/* Kata sifat */
375942
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} guyir <!—-mudah rapuh-->
#: {{cp|ms|malin awas, kayu tu dah guyir.|awas malin kayu sudah rapuh.}}
8ckiqeqx3ryy4wkn2u6rsptcexmh6ag
gopuak
0
145853
375939
2026-09-26T08:11:21Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} hontam <!--hantam--> #:{{cp|ms|jan dihontam jo le.|jangan dihantam juga lagi.}}'
375939
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} hontam <!--hantam-->
#:{{cp|ms|jan dihontam jo le.|jangan dihantam juga lagi.}}
q7x1367g3ucoz0x94smh5npe67lnkk2
375947
375939
2026-09-26T08:14:58Z
SY Reski
10853
375947
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|Kata Sifat}}
#{{lb|ms|Kampar}} gopuak <!--gendut-->
#:{{cp|ms|jan makan jo le, gopuak kau beko|sudah lah makannya, nanti kamu gendut.}}
qvnl0thdg0cvrii6o2viyz8tdm3hx15
aco
0
145854
375940
2026-09-26T08:11:44Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} acar (makanan bercuka dr irisan buah mentimun, wortel, bawang, cabai, nanas, bengkuang atau daun sawi, biasa dimakan bersama nasi)'
375940
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} acar (makanan bercuka dr irisan buah mentimun, wortel, bawang, cabai, nanas, bengkuang atau daun sawi, biasa dimakan bersama nasi)
tbl1yapiy5wfscwnmu0rw6i57fa3k1w
Nyanyuk
0
145855
375941
2026-09-26T08:12:12Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} Nyanyuk <!--Pelupa--> #: {{cp|ms|nyanyuk kau ni.|pelupa kamu ni.}}'
375941
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} Nyanyuk <!--Pelupa-->
#: {{cp|ms|nyanyuk kau ni.|pelupa kamu ni.}}
q5s91o7tovjoxhvhbzeryxisrrq45mt
376118
375941
2026-09-26T09:02:32Z
Robiyatuladawiyah05
11514
/* Kata Sifat */
376118
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} Pelupa <!--Pelupa-->
#: {{cp|ms|nyanyuk kau ni.|pelupa kamu ni.}}
329efhhu6omg1nvy6ypculbllux1cnq
potui
0
145856
375944
2026-09-26T08:14:06Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} petir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|banyak potui hujan kini ko.|banyak petir hujan sekarang.}}'
375944
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} petir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|banyak potui hujan kini ko.|banyak petir hujan sekarang.}}
d8yqw09i68ngk55ejmoyl536eszmitv
375946
375944
2026-09-26T08:14:26Z
Muhammad Abdi Ramadhan
9873
/* Kata benda */
375946
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} petir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|banyak potui hujan kini ko.|banyak petir hujan sekarang.}}
j0kks4um4alaalmrkltbro0mq6hvsb9
letey
0
145857
375945
2026-09-26T08:14:12Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Dumai}} Letey <!--lambat respon--> #: {{cp|ms|letey betol dikau wah.|lambat respon sekali kamu.}}'
375945
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Dumai}} Letey <!--lambat respon-->
#: {{cp|ms|letey betol dikau wah.|lambat respon sekali kamu.}}
49taeslxmii4t2wicpt7tm2bowr8lbj
basaw
0
145858
375948
2026-09-26T08:15:00Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===basaw=== {{lb|ms|kata benda}} # {{lb|ms|Bengkalis}} isi buah kelapa <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu makan basaw.|orang itu mau makan isi kelapa.}}'
375948
wikitext
text/x-wiki
==Bahasa Melayu==
===basaw===
{{lb|ms|kata benda}}
# {{lb|ms|Bengkalis}} isi buah kelapa <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu makan basaw.|orang itu mau makan isi kelapa.}}
138lgvumus37070gvl3eqdgif8rys9r
malam buto
0
145859
375949
2026-09-26T08:15:12Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata waktu=== {{lb|ms|kata waktu}} # {{lb|ms|Siak}} malam buto <!--tengah malam--> #: {{cp|ms|malam buto ni jugo nak pegi?.|tengah malam juga mau pergi?.}}'
375949
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Siak}} malam buto <!--tengah malam-->
#: {{cp|ms|malam buto ni jugo nak pegi?.|tengah malam juga mau pergi?.}}
o8t9qouyu4yrzkcm3pg9czlax65ky6h
kaghang
0
145860
375951
2026-09-26T08:16:22Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata waktu=== {{lb|ms|kata waktu}} # {{lb|ms|Dumai}} kaghang <!--kaghang--> #: {{cp|ms|kaghang aku kesano?.|Nanti saya kesana.}}'
375951
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Dumai}} kaghang <!--kaghang-->
#: {{cp|ms|kaghang aku kesano?.|Nanti saya kesana.}}
rhxg2h4x33nethrgsv74z977lls7uvb
375952
375951
2026-09-26T08:16:54Z
Devi Armanda Nasution
11513
375952
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Dumai}} kaghang <!--kaghang-->
#: {{cp|ms|kaghang aku kesano.|Nanti saya kesana.}}
nozcgt9zw7so9sm2vptl9hlon8hcy7q
375964
375952
2026-09-26T08:21:36Z
HafizahNurainii
11023
375964
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Dumai}} kaghang <!--kaghang-->
#: {{cp|ms|kaghang aku kesano.|Nanti saya kesana.}}
==Bahasa Melayu Siak==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Siak}} nanti
#: {{cp|ms|kaghang kito kejokan.|nanti kita kerjakan.}}
i5nmi73454gczgq6fsdtwx1na9h9zqi
mak long
0
145861
375953
2026-09-26T08:17:38Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata ganti=== {{lb|ms|kata ganti}} # {{lb|ms|Siak}} mak long <!--tente--> #: {{cp|ms|mak long ni dekat mane?.|tente sedang ada di mana?.}}'
375953
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata ganti===
{{lb|ms|kata ganti}}
# {{lb|ms|Siak}} mak long <!--tente-->
#: {{cp|ms|mak long ni dekat mane?.|tente sedang ada di mana?.}}
ahmbwx0to26std53zfxni6b5rq5jfuj
baniu
0
145862
375954
2026-09-26T08:18:06Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} baniu <!--akar yang muncul di permukaan tanah--> #: {{cp|ms|malin tesangkut baniu ?.|malin tersandung akar itu?.}}'
375954
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} baniu <!--akar yang muncul di permukaan tanah-->
#: {{cp|ms|malin tesangkut baniu ?.|malin tersandung akar itu?.}}
g5q0o1dvu8f0qbik1gdxmgrl6jylecm
menjengah
0
145863
375955
2026-09-26T08:18:28Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu pelalawan== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} melihat<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Adik menjengah kat luo.|Adik melihat ke luar sebentar}}'
375955
wikitext
text/x-wiki
==Bahasa Melayu pelalawan==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} melihat<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Adik menjengah kat luo.|Adik melihat ke luar sebentar}}
qw0hyl7rgi2kwt6x0b45r8j6yxilhf0
selemak
0
145864
375956
2026-09-26T08:18:56Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Bengkalis}} selemak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kau selemak.|kau tak terurus.}}'
375956
wikitext
text/x-wiki
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Bengkalis}} selemak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kau selemak.|kau tak terurus.}}
0zl0vmkwbac08fll9r3ti9fwqdx5lhw
coban
0
145865
375957
2026-09-26T08:19:12Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===coban=== {{lb|ms|kata benda}} # {{lb|ms|Bengkalis}} jarum perjahi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu mencai coban.|orang itu mencari jarum jahit.}}'
375957
wikitext
text/x-wiki
==Bahasa Melayu==
===coban===
{{lb|ms|kata benda}}
# {{lb|ms|Bengkalis}} jarum perjahi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu mencai coban.|orang itu mencari jarum jahit.}}
53ktihycokoo4xkjd3rr4mrg8xz7uca
mempelai
0
145866
375958
2026-09-26T08:19:34Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} Mempelai <!--pengantin--> #: {{cp|ms|bilo sampai mempelai tu, wah?.|kapan sampai pengantin, dek?.}}'
375958
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} Mempelai <!--pengantin-->
#: {{cp|ms|bilo sampai mempelai tu, wah?.|kapan sampai pengantin, dek?.}}
81e9fnywvcfxc8imsv47ow3j6sbtwfv
menyamun
0
145867
375959
2026-09-26T08:19:36Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} menyamun <!--mencuri--> #: {{cp|ms|dio tertangkap sedang menyamun.dia tertangkap sedang mencuri.}}'
375959
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} menyamun <!--mencuri-->
#: {{cp|ms|dio tertangkap sedang menyamun.dia tertangkap sedang mencuri.}}
7qf0igmom2617e53z7dypprrgavepu6
jauoh
0
145868
375960
2026-09-26T08:19:39Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hulu}} jauh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu jauoh.|orang itu jauh.}}'
375960
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} jauh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu jauoh.|orang itu jauh.}}
cmqtki64p6bz5gf4daz9h13jg5tkfxd
pelite
0
145869
375961
2026-09-26T08:20:02Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} lampu tradisional #: {{cp|ms|Umah dikau ade pelite?.|rumah kamu ada lampu?.}}'
375961
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} lampu tradisional
#: {{cp|ms|Umah dikau ade pelite?.|rumah kamu ada lampu?.}}
iwunu2ct3ucjs8bq2dx2goozsvfa15b
kojou
0
145870
375962
2026-09-26T08:20:40Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hulu}} kejar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu nak kojou aku?.|orang itu mau kejar aku?.}}'
375962
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} kejar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu nak kojou aku?.|orang itu mau kejar aku?.}}
rtk86h2wfgaw6y1uec88v6phqci3rvq
mempelam
0
145871
375963
2026-09-26T08:20:59Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} mempelam <!--mangga--> #: {{cp|ms|sedap betullah mempelam tu!.|enak sekali mangga itu!.}}'
375963
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} mempelam <!--mangga-->
#: {{cp|ms|sedap betullah mempelam tu!.|enak sekali mangga itu!.}}
qnujg5i5vhroewoa3gx9s6dahljm5ev
onda
0
145872
375965
2026-09-26T08:21:41Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===onda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} sepeda motor <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|onda awak tu.|sepeda motor kami itu.}}'
375965
wikitext
text/x-wiki
==Bahasa Melayu==
===onda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} sepeda motor <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|onda awak tu.|sepeda motor kami itu.}}
rtvcnirruqn9h4ho5xjg7lrg34yzhhe
375969
375965
2026-09-26T08:22:37Z
Thurama
11516
/* Bahasa Melayu */
375969
wikitext
text/x-wiki
==Bahasa Melayu==
===onda===
{{lb|ms|kata benda}}
# {{lb|ms|Pekanbaru}} sepeda motor <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|onda awak tu.|sepeda motor kami itu.}}
36f3ppcaxtg4z3gbw821neyzenyrtk1
kace mate
0
145873
375968
2026-09-26T08:22:02Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} kace mate <!--kace mate--> #: {{cp|ms|mane kace mate budak ni?.|dimana kacamata anak ni ?.}}'
375968
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} kace mate <!--kace mate-->
#: {{cp|ms|mane kace mate budak ni?.|dimana kacamata anak ni ?.}}
ca5u190k06jng8pbhs3lvcu0p3738qb
kongak
0
145874
375970
2026-09-26T08:22:47Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hulu}} kerak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kuali tu ba kongak.|kuali itu berkerak.}}'
375970
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} kerak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kuali tu ba kongak.|kuali itu berkerak.}}
9kdjg849t3z7n5rzgv7z8xwf5e156ix
hogo
0
145875
375971
2026-09-26T08:23:06Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Benda=== {{lb|ms|kata benda}} # {{lb|ms|rokan hilir}} Hogo <!--Harga--> #: {{cp|ms|bapo hogo baju kau tu?.|berapa harga baju kamu?.}}'
375971
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Benda===
{{lb|ms|kata benda}}
# {{lb|ms|rokan hilir}} Hogo <!--Harga-->
#: {{cp|ms|bapo hogo baju kau tu?.|berapa harga baju kamu?.}}
a3l903dyv2haga6nodqlarpzz6x0tk7
376127
375971
2026-09-26T09:04:43Z
Robiyatuladawiyah05
11514
/* Kata Benda */
376127
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Benda===
{{lb|ms|kata benda}}
# {{lb|ms|rokan hilir}} Harga <!--Harga-->
#: {{cp|ms|bapo hogo baju kau tu?.|berapa harga baju kamu?.}}
4ecumnj72h2pqprdw2rb1cgrveyr46k
beseloroh
0
145876
375972
2026-09-26T08:23:34Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Budak itu besoloroh.|Anak itu bergurau.}}'
375972
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Budak itu besoloroh.|Anak itu bergurau.}}
sqha1gsgd14tmn1swclbcwfcnkor2e8
alao
0
145877
375973
2026-09-26T08:23:36Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} alao <!--serangga pemakan padi--> #: {{cp|ms|boreh malin kene makan alao .|beras malin kenak makan serangga?.}}'
375973
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} alao <!--serangga pemakan padi-->
#: {{cp|ms|boreh malin kene makan alao .|beras malin kenak makan serangga?.}}
djjma7351v4elp9qu65dnep13a581si
joleh
0
145878
375975
2026-09-26T08:24:21Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} Cerewet #: {{cp|ms|Joleh betul dikau ni.|cerewet banget kamu ini.}}'
375975
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} Cerewet
#: {{cp|ms|Joleh betul dikau ni.|cerewet banget kamu ini.}}
9vry0xdbm5yiwn5d3l6naz1pajgzu1a
butei
0
145879
375976
2026-09-26T08:24:39Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Dumai}} Butei <!--butir--> #: {{cp|ms|berapo butei telou dikau ambek?.|berapa butir telur kamu ambil?.}}'
375976
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Dumai}} Butei <!--butir-->
#: {{cp|ms|berapo butei telou dikau ambek?.|berapa butir telur kamu ambil?.}}
5jow3bsl8vwqikpe9n0n23drdb50q0k
perabu
0
145880
375977
2026-09-26T08:24:58Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|kampar}} perabu <!--pemarah--> #: {{cp|ms|malin perabu.|malin pemarah?.}}'
375977
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|kampar}} perabu <!--pemarah-->
#: {{cp|ms|malin perabu.|malin pemarah?.}}
m4cc97q7jdmu1qbyhplhebovrggprfx
beno
0
145881
375980
2026-09-26T08:26:15Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===beno=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu becakap beno.|orang itu berbicara yang benar.}}'
375980
wikitext
text/x-wiki
==Bahasa Melayu==
===beno===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu becakap beno.|orang itu berbicara yang benar.}}
7vvb8uj6mhq0zalfd9hhhqv5vjn1nle
bonau
0
145882
375981
2026-09-26T08:26:17Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hulu}} benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu bonau.|orang itu benar.}}'
375981
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu bonau.|orang itu benar.}}
kknxxsrok5lrwc77lejcx2hchpaipbg
melepak
0
145883
375982
2026-09-26T08:26:24Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} melepak <!--duduk dimana saja--> #: {{cp|ms|melepak kat danau yok.|duduk dimana saja di danau yok.}}'
375982
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} melepak <!--duduk dimana saja-->
#: {{cp|ms|melepak kat danau yok.|duduk dimana saja di danau yok.}}
4m9fp8v7ldhic7waub755wk6nobdqnz
santap
0
145884
375983
2026-09-26T08:26:29Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mari santap dulu.|mari makan dulu.}}'
375983
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mari santap dulu.|mari makan dulu.}}
5d613vkzkt4kiv5i0j9wnf21jtuceaj
dapou
0
145885
375984
2026-09-26T08:26:49Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} dapou <!--dapur--> #: {{cp|ms|dio kat dapou tu.|dia di dapur itu.}}'
375984
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} dapou <!--dapur-->
#: {{cp|ms|dio kat dapou tu.|dia di dapur itu.}}
qxk5d9bqfvzom4sa9tkj9lxtl6cmkke
bengek
0
145886
375985
2026-09-26T08:27:27Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|bengkalis}} bengek <!--sesak napas--> #: {{cp|ms|malin lagri sampai bengek.|malin lari sampai sesak napas?.}}'
375985
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|bengkalis}} bengek <!--sesak napas-->
#: {{cp|ms|malin lagri sampai bengek.|malin lari sampai sesak napas?.}}
ggkcnmf3g9asjigxllbi7vy8kn72364
MAANTAU
0
145887
375986
2026-09-26T08:28:00Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} maantau <!--merantau--> #:{{cp|ms|Inyo poi maantau ka Pekanbaru.|Dia pergi merantau ke Pekanbaru.}}'
375986
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} maantau <!--merantau-->
#:{{cp|ms|Inyo poi maantau ka Pekanbaru.|Dia pergi merantau ke Pekanbaru.}}
t8e4eyuwjdur68sozv0kw8xwdvzdjzm
goleh
0
145888
375987
2026-09-26T08:28:26Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hulu}} gelas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mano goleh ang?.|mana gelas kau?.}}'
375987
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} gelas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mano goleh ang?.|mana gelas kau?.}}
9xix6u70ynbq4ydusxfw69as64lyspv
adondak
0
145889
375988
2026-09-26T08:28:49Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} ada atau tidak (pertanyaan yg menanyakan tt keberadaan seseorang atau suatu benda, yg jawabannya ada atau tidak)'
375988
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} ada atau tidak (pertanyaan yg menanyakan tt keberadaan seseorang atau suatu benda, yg jawabannya ada atau tidak)
rbxozki10zph0um1feqknxzl4uqmx42
menyengat
0
145890
375989
2026-09-26T08:29:36Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|bau dikau menyengat betul.|bau kamu menyengat banget.}}'
375989
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|bau dikau menyengat betul.|bau kamu menyengat banget.}}
tlk9kn9drn7tfaba8142ngoaeinn7x3
noreh
0
145891
375990
2026-09-26T08:29:37Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} noreh <!--motong karet--> #: {{cp|ms|omak pegi noreh yo.|ibu pergi memotong karet dulu ya.}}'
375990
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} noreh <!--motong karet-->
#: {{cp|ms|omak pegi noreh yo.|ibu pergi memotong karet dulu ya.}}
s372k1voebuhukmjao5j7iam9h8mrrg
subei
0
145892
375991
2026-09-26T08:29:38Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat= {{lb|ms|kata sifat}} # {{lb|ms|Siak}} subai <!--kaki bengkak dibagian jempol--> #: {{cp|ms|jempol malin subai.|jempol kaki malin bengkak.}}'
375991
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat=
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} subai <!--kaki bengkak dibagian jempol-->
#: {{cp|ms|jempol malin subai.|jempol kaki malin bengkak.}}
peq0vs120nhc0srrjh3rvxubus19ijp
konai
0
145893
375992
2026-09-26T08:29:38Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan hulu}} kena <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|konai hati den.|kena hati aku.}}'
375992
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan hulu}} kena <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|konai hati den.|kena hati aku.}}
88vr2gf4xhk5g4by7wf9c036bnfk2kt
ledah
0
145894
375993
2026-09-26T08:29:38Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} jorok #: {{cp|ms|ledah dikau ni.|jorok kamu ini.}}'
375993
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} jorok
#: {{cp|ms|ledah dikau ni.|jorok kamu ini.}}
cvn7ywmm7uatewb8o2btcqw249vs8cx
kojap
0
145895
375994
2026-09-26T08:30:21Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Keterangan=== {{lb|ms|kata keterangan}} # {{lb|ms|Rokan Hilir}} Kojap <!--Bentar--> #: {{cp|ms|aku makan kojap.|aku makan bentar.}}'
375994
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Kojap <!--Bentar-->
#: {{cp|ms|aku makan kojap.|aku makan bentar.}}
2of8j9of1tdsk1g1zyqtb20q6fwz2in
sedagho
0
145896
375995
2026-09-26T08:30:32Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} sedagho <!--saudara--> #: {{cp|ms|sedagho sayo datang.|saudara saya datang.}}'
375995
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} sedagho <!--saudara-->
#: {{cp|ms|sedagho sayo datang.|saudara saya datang.}}
qxdfjp3t0oo6zrc7w9rzlrnoqp0ln9g
mengempu
0
145897
375996
2026-09-26T08:30:33Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} mengempu <!--duduk saja--> #: {{cp|ms|mengempu ajo lah kejo budak ni.|duduk saja kera kamu ini.}}'
375996
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} mengempu <!--duduk saja-->
#: {{cp|ms|mengempu ajo lah kejo budak ni.|duduk saja kera kamu ini.}}
mcaiweds58q5x7v35rpnudhg0ihniy5
teragak
0
145898
375997
2026-09-26T08:30:48Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata tugas=== {{lb|ms|kata tugas}} # {{lb|ms|Dumai}} teragak <!--ingin--> #: {{cp|ms|teragak pulak nak makan sate di tepi pantai.|ingin sekali makan sate di tepi pantai.}}'
375997
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata tugas===
{{lb|ms|kata tugas}}
# {{lb|ms|Dumai}} teragak <!--ingin-->
#: {{cp|ms|teragak pulak nak makan sate di tepi pantai.|ingin sekali makan sate di tepi pantai.}}
e4i8eyp5ex6e9rpe2z3mqm673qjvee9
terenang
0
145899
375998
2026-09-26T08:30:58Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} terenang <!--mangkok besar dari porselen--> #: {{cp|ms|malin dapat terenang.|malin beli mangkok.}}'
375998
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} terenang <!--mangkok besar dari porselen-->
#: {{cp|ms|malin dapat terenang.|malin beli mangkok.}}
49044y8otu17pmjgsglcngopc5f8y3h
tumbuok
0
145900
375999
2026-09-26T08:31:27Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hulu}} tumbuk <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku tumbuok bang ko.|aku tumbuk kau nanti.}}'
375999
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} tumbuk <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku tumbuok bang ko.|aku tumbuk kau nanti.}}
hn1srcek0th8bjukzh2rmo0zoulg47j
anyiu
0
145901
376000
2026-09-26T08:32:36Z
Muhammad Abdi Ramadhan
9873
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hulu}} anyir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|anyiu baun ang ma|anyir bau kau.}}'
376000
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hulu}} anyir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|anyiu baun ang ma|anyir bau kau.}}
avypqps3wxow1pq5t6ihp12ip4gtmsr
gebo
0
145902
376001
2026-09-26T08:32:42Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} gebo <!--selimut besar--> #: {{cp|ms|ambikkan gebo tu.|ambilkan selimut besar itu.}}'
376001
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} gebo <!--selimut besar-->
#: {{cp|ms|ambikkan gebo tu.|ambilkan selimut besar itu.}}
h4o4ba1usztiwq4b04ah6gqcqewgam8
amboi
0
145903
376002
2026-09-26T08:32:53Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Bengkalis}} amboi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Amboi, Nakalnye.|Aduhai, Nakal sekali.}}'
376002
wikitext
text/x-wiki
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Bengkalis}} amboi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Amboi, Nakalnye.|Aduhai, Nakal sekali.}}
dzdlyt2h8qq9gm9lsyf057eqz0e81tu
pelak
0
145904
376003
2026-09-26T08:33:10Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===pelak=== {{lb|ms|sifat}} # {{lb|ms|Siak}} gerah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|awak tongah pelak.|saya sedang gerah.}}'
376003
wikitext
text/x-wiki
==Bahasa Melayu==
===pelak===
{{lb|ms|sifat}}
# {{lb|ms|Siak}} gerah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|awak tongah pelak.|saya sedang gerah.}}
8std2sv0u7p8vcd5lri1htxp4rnyir6
MAMBUTUIK
0
145905
376004
2026-09-26T08:33:21Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|Kata Sifat}} #{{lb|ms|Kampar}} mambutuik <!--cemberut--> #:{{cp|ms|Bak po kau mambutuik jo?|Kenapa kamu cemberut saja?}}'
376004
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|Kata Sifat}}
#{{lb|ms|Kampar}} mambutuik <!--cemberut-->
#:{{cp|ms|Bak po kau mambutuik jo?|Kenapa kamu cemberut saja?}}
my17tt33lr5y07qfkcwu6rlzaq6iwuh
kepughun
0
145906
376005
2026-09-26T08:33:23Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} Kepughun <!--papeda--> #: {{cp|ms|teragak nak makan kepughun.|ingin sekali makan papeda.}}'
376005
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} Kepughun <!--papeda-->
#: {{cp|ms|teragak nak makan kepughun.|ingin sekali makan papeda.}}
cjf39x0jiriky4ovahg37535hjuatgw
sikodik
0
145907
376006
2026-09-26T08:33:40Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} sikodik <!--makhluk halus--> #: {{cp|ms|malin tetengok sikodik.|malin lihat hantu.}}'
376006
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} sikodik <!--makhluk halus-->
#: {{cp|ms|malin tetengok sikodik.|malin lihat hantu.}}
ix1asefm2q94fs8u0mm5s8tbmw8n7ur
abes
0
145908
376007
2026-09-26T08:34:27Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===abes=== {{lb|ms|sifat}} # {{lb|ms|Siak}} habis <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|abeslah budak tu.|habislah anak itu.}}'
376007
wikitext
text/x-wiki
==Bahasa Melayu==
===abes===
{{lb|ms|sifat}}
# {{lb|ms|Siak}} habis <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|abeslah budak tu.|habislah anak itu.}}
872c62qub4ymjqusgu2fevhalgg772u
sememeh
0
145909
376008
2026-09-26T08:34:31Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|budak itu sememeh betul.|anak itu berantakan kali.}}'
376008
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|budak itu sememeh betul.|anak itu berantakan kali.}}
068b3ijkdq5t2rfsxu2k9c118yisnn4
merepet
0
145910
376010
2026-09-26T08:34:59Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata merepet=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} merepet <!--berbicara terus menerus--> #: {{cp|ms|merepet teghus budak tu?.|berbicara terus menerus anak itu?.}}'
376010
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata merepet===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} merepet <!--berbicara terus menerus-->
#: {{cp|ms|merepet teghus budak tu?.|berbicara terus menerus anak itu?.}}
9fhm6m7vp2zhao1v0fhiidqu1jsd2o0
sepilis
0
145911
376011
2026-09-26T08:35:08Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} sepilis <!--langgit langgit rumah--> #: {{cp|ms|malin ganti selipis rumah die.|malin perbaiki langit langit rumahnya.}}'
376011
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} sepilis <!--langgit langgit rumah-->
#: {{cp|ms|malin ganti selipis rumah die.|malin perbaiki langit langit rumahnya.}}
sy8wzqs6q6miv080i7nnjld85xexmzm
pemantang
0
145912
376012
2026-09-26T08:35:11Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} Larangan #: {{cp|ms|Pemantang aku ni.|larangan aku ni.}}'
376012
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} Larangan
#: {{cp|ms|Pemantang aku ni.|larangan aku ni.}}
5lh2yqpj3smykdv2eiu8zfvy40n40fa
mengepeik
0
145913
376013
2026-09-26T08:35:26Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} mengepik <!--meribut--> #: {{cp|ms|budak tu mengepik betul.|anak tu meribut sekali.}}'
376013
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} mengepik <!--meribut-->
#: {{cp|ms|budak tu mengepik betul.|anak tu meribut sekali.}}
agj457fp0pmq4s7sj9n8apllzzqv0lz
pokah
0
145914
376015
2026-09-26T08:36:46Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} Rusak #: {{cp|ms|dikau ni suke pokah bende.|kamu ini suka rusak barang.}}'
376015
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} Rusak
#: {{cp|ms|dikau ni suke pokah bende.|kamu ini suka rusak barang.}}
k7e9h9ox02n1rihp24o9a9wter79yko
pokak
0
145915
376016
2026-09-26T08:36:49Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} Pokak <!--Tuli--> #: {{cp|ms|kau pokak betol.|kamu tuli sekali (tidak dengar).}}'
376016
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} Pokak <!--Tuli-->
#: {{cp|ms|kau pokak betol.|kamu tuli sekali (tidak dengar).}}
k545hau3k0w6p2xsbw8r48ohjns67fx
menyeloghok
0
145916
376017
2026-09-26T08:36:50Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} menyeloghok<!--nyeleneh--> #: {{cp|ms|menyeloghok betul pulak.|menyeloghok betul.}}'
376017
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} menyeloghok<!--nyeleneh-->
#: {{cp|ms|menyeloghok betul pulak.|menyeloghok betul.}}
8yxk7by7n2ihmpc1i6goynfpbpz9pw1
salibu
0
145917
376018
2026-09-26T08:37:00Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} salibu <!--tunas padi--> #: {{cp|ms|salibu sawah malin dah tumbuh.|tunas padi di sawah malin sudah tumbuh.}}'
376018
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} salibu <!--tunas padi-->
#: {{cp|ms|salibu sawah malin dah tumbuh.|tunas padi di sawah malin sudah tumbuh.}}
cbc4dwu496owaj9j70czzq7726x0ncw
sombuh
0
145918
376020
2026-09-26T08:37:27Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kawan dikau dah sembuh?.|teman kamu udh sembuh?.}}'
376020
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kawan dikau dah sembuh?.|teman kamu udh sembuh?.}}
ivb13gkul56xl6i2k552g3xp6bl6ss9
kemaruk
0
145919
376021
2026-09-26T08:37:50Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} kemaruk <!--rakus--> #: {{cp|ms|miko ni kemaruk betul.|kalian ni rakus sekali .}}'
376021
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} kemaruk <!--rakus-->
#: {{cp|ms|miko ni kemaruk betul.|kalian ni rakus sekali .}}
kx1u3ezhjkjkctyn2bj9rpd83144z9r
muncung
0
145920
376022
2026-09-26T08:37:52Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} muncung <!--mulut--> #: {{cp|ms|muncung miko ni megha betol.|mulut kamu merah sekali.}}'
376022
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} muncung <!--mulut-->
#: {{cp|ms|muncung miko ni megha betol.|mulut kamu merah sekali.}}
9je610tn5tays8r6p56eaq958f96g1b
akhei
0
145921
376023
2026-09-26T08:37:59Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} akhir ; belakang; kemudian; yg belakang sekali, penghabisan dsb'
376023
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} akhir ; belakang; kemudian; yg belakang sekali, penghabisan dsb
k6s6e4n6qfdanzdkfksdi3efkd9dgj4
seekou
0
145922
376024
2026-09-26T08:38:05Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Dumai}} Seekou <!--Seekor--> #: {{cp|ms|beghapo seekou halo ayam tu, Cik?.|berapa harga seekor Ayam tu, buk?.}}'
376024
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Dumai}} Seekou <!--Seekor-->
#: {{cp|ms|beghapo seekou halo ayam tu, Cik?.|berapa harga seekor Ayam tu, buk?.}}
sxox1i2uurzr2dzn1stt979r2gbpxig
tecekik
0
145923
376025
2026-09-26T08:38:16Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} tecekik <!--tersedak--> #: {{cp|ms|malin tecekik tulang.|malin tersedak tulang.}}'
376025
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} tecekik <!--tersedak-->
#: {{cp|ms|malin tecekik tulang.|malin tersedak tulang.}}
q2alb4kn4v2k5vjhgeu0e4ocxspohna
gelonyo
0
145924
376027
2026-09-26T08:39:29Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===gelenyo=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} genit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|betino tu gelenyo.|perempuan itu genit.}}'
376027
wikitext
text/x-wiki
==Bahasa Melayu==
===gelenyo===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} genit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|betino tu gelenyo.|perempuan itu genit.}}
lf103nv2qq3e1w8cri6x5ts2ci2ni7l
houk
0
145925
376028
2026-09-26T08:39:48Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} Houk <!--Berisik--> #: {{cp|ms|houk betol.|berisik sekali.}}'
376028
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} Houk <!--Berisik-->
#: {{cp|ms|houk betol.|berisik sekali.}}
dzanua4p7lks6g46p67p0esmhn90ln7
376041
376028
2026-09-26T08:42:27Z
Robiyatuladawiyah05
11514
/* Kata Sifat */
376041
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} Berisik <!--Berisik-->
#: {{cp|ms|houk betol.|berisik sekali.}}
0h7d53icdglmqpiscg4ag0l4f3us283
OGHAK
0
145926
376029
2026-09-26T08:40:05Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|Kata Sifat}} #{{lb|ms|Kampar}} oghak <!--rusak--> #:{{cp|ms|lah oghak umah ko dek ang.|rumah ini jadi rusak sama kamu.}}'
376029
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|Kata Sifat}}
#{{lb|ms|Kampar}} oghak <!--rusak-->
#:{{cp|ms|lah oghak umah ko dek ang.|rumah ini jadi rusak sama kamu.}}
jvjdah1rmmfoj3ujnlrs23h3l5rrjmz
bingong
0
145927
376030
2026-09-26T08:40:10Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} bingong <!--bodoh--> #: {{cp|ms|padek bingong nyo.|parah bodohnyo.}}'
376030
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} bingong <!--bodoh-->
#: {{cp|ms|padek bingong nyo.|parah bodohnyo.}}
hkh637kwjfnvsc52hr7c5sxt6cb3xxq
hinggap
0
145928
376031
2026-09-26T08:40:19Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Dumai}} Hinggap <!--singgah--> #: {{cp|ms|Comelnyo bughong tu hinggap ke bilik.|lucunya burung tu singgah ke kamar .}}'
376031
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Dumai}} Hinggap <!--singgah-->
#: {{cp|ms|Comelnyo bughong tu hinggap ke bilik.|lucunya burung tu singgah ke kamar .}}
sv2tth9aerjco0vp4aesqexesgtrb4d
biseng
0
145929
376032
2026-09-26T08:40:32Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} Berisik #: {{cp|ms|biseng beno mike ni?.|berisik banget kalian ni.}}'
376032
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} Berisik
#: {{cp|ms|biseng beno mike ni?.|berisik banget kalian ni.}}
r7kj4knk5x10x195qzje8c8nq92dfti
piowan
0
145930
376033
2026-09-26T08:40:34Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|kampar}} piowan <!--perempuan matang belum menikah--> #: {{cp|ms|ainul masih piowan.|ainul belum menikah.}}'
376033
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|kampar}} piowan <!--perempuan matang belum menikah-->
#: {{cp|ms|ainul masih piowan.|ainul belum menikah.}}
j88svkhv2d3lb8s0bwblx9jps57iae4
lambek
0
145931
376035
2026-09-26T08:41:24Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|jangan lambek betul dikau tibe kat sekolah.|jangan lambat kali kamu datang ke sekolah.}}'
376035
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|jangan lambek betul dikau tibe kat sekolah.|jangan lambat kali kamu datang ke sekolah.}}
faghfoyofewj4eyocfjbdn3w10sc1hq
megha
0
145932
376036
2026-09-26T08:41:29Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} megha <!--merah--> #: {{cp|ms|megha betol muncung miko.|merah sekali mulut kamu .}}'
376036
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} megha <!--merah-->
#: {{cp|ms|megha betol muncung miko.|merah sekali mulut kamu
.}}
nysuspesvg8bz1czmmrib42ztc7hvae
padek
0
145933
376038
2026-09-26T08:41:45Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak} padek <!--parah--> #: {{cp|ms|padek teh kau ni.|parah kali kamu ini.}}'
376038
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak} padek <!--parah-->
#: {{cp|ms|padek teh kau ni.|parah kali kamu ini.}}
siyegkfoarcgibkn7y8k21ftv07378d
ako
0
145934
376039
2026-09-26T08:42:05Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} akar; bagian tumbuhan yg biasanya tertanam di dl tanah sbg penguat dan pengisap air serta zat makanan;'
376039
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} akar; bagian tumbuhan yg biasanya tertanam di dl tanah sbg penguat dan pengisap air serta zat makanan;
5hqczw3h137i7zcsglvbrm63zniizrp
tak payah
0
145935
376040
2026-09-26T08:42:26Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===tak payah=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} tidak perlu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tak payah beaduh.|tidak perlu berisik.}}'
376040
wikitext
text/x-wiki
==Bahasa Melayu==
===tak payah===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} tidak perlu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tak payah beaduh.|tidak perlu berisik.}}
bkwshaqg4mb84vosssvqpnllakuet7i
dukuh
0
145936
376042
2026-09-26T08:42:31Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|kampar}} dukuh <!--anak tunggal--> #: {{cp|ms|malin dukuh.|malin anak tunggal.}}'
376042
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|kampar}} dukuh <!--anak tunggal-->
#: {{cp|ms|malin dukuh.|malin anak tunggal.}}
r9hzkc022nmi4jh71rommahupo351sx
bodak
0
145937
376044
2026-09-26T08:42:53Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} bodak <!--bedak--> #: {{cp|ms|bodak miko apo?.|bedak kamu apa?.}}'
376044
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} bodak <!--bedak-->
#: {{cp|ms|bodak miko apo?.|bedak kamu apa?.}}
dnyfy5ms5turgn4mp0gg10ausxm10iu
loye
0
145938
376045
2026-09-26T08:43:36Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} Mual #: {{cp|ms|loye aku nengok dikau.|mual aku lihat kamu.}}'
376045
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} Mual
#: {{cp|ms|loye aku nengok dikau.|mual aku lihat kamu.}}
kr17felvpt4rrrpu3fdyup5lz13z9gq
isuk
0
145939
376046
2026-09-26T08:44:08Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Keterangan=== {{lb|ms|kata keterangan}} # {{lb|ms|Rokan Hilir}} Besok <!--Besok--> #: {{cp|ms|poi isuk.|pergi besok.}}'
376046
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Besok <!--Besok-->
#: {{cp|ms|poi isuk.|pergi besok.}}
23u3xxa9cml5wdqxy3ie9876pvmjmyz
kumih
0
145940
376047
2026-09-26T08:44:11Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kumih ayah dan panjang betul.|kumis ayah udah panjang kali.}}'
376047
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kumih ayah dan panjang betul.|kumis ayah udah panjang kali.}}
hoegz19yw74ug6a47xq643xqbrsbwx9
suntai
0
145941
376048
2026-09-26T08:44:23Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hilir}} suntai<!--Robek--> #: {{cp|ms|Suntailah baju aku.|Robeklah baju aku.}}'
376048
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} suntai<!--Robek-->
#: {{cp|ms|Suntailah baju aku.|Robeklah baju aku.}}
2j0fyg4hs6teai0e3310d5irkg4uxev
ojol
0
145942
376049
2026-09-26T08:44:50Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} ojol <!--Getah karet yang membeku--> #: {{cp|ms|ojol getah karet tu |getah karet itu membeku.}}'
376049
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} ojol <!--Getah karet yang membeku-->
#: {{cp|ms|ojol getah karet tu |getah karet itu membeku.}}
d0kqw3sawly0bpl5s4ek13b0mynypr1
oghang
0
145943
376050
2026-09-26T08:44:50Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} oghang <!--orang--> #: {{cp|ms|oghang tu tengah membaco buku.|orang itu sedang membaca buku.}}'
376050
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} oghang <!--orang-->
#: {{cp|ms|oghang tu tengah membaco buku.|orang itu sedang membaca buku.}}
pf2nxv167up39w2ei2xc5y0rqj9uxjk
anting
0
145944
376051
2026-09-26T08:45:01Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} anting-anting; giwang; perhisan wanita yg dipakai ditelinga dng cara ditindik dan digantungkan;'
376051
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} anting-anting; giwang; perhisan wanita yg dipakai ditelinga dng cara ditindik dan digantungkan;
saz56rrw8zukok8ahvhipcmwt0zt2he
tak betul
0
145945
376053
2026-09-26T08:45:32Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Tak Betul=== {{lb|ms|kata kerja}} # {{lb|ms|pekanbaru}} tidak benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|macam tak betul budak tu?.|seperti ada yang tidak benar dengan anak itu?.}}'
376053
wikitext
text/x-wiki
==Bahasa Melayu==
===Tak Betul===
{{lb|ms|kata kerja}}
# {{lb|ms|pekanbaru}} tidak benar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|macam tak betul budak tu?.|seperti ada yang tidak benar dengan anak itu?.}}
8smqb5fbjzj069u3g22e2lj3jkqsitv
ghamai
0
145946
376054
2026-09-26T08:45:59Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} ghamai <!--Ramai #: {{cp|ms|ghamai betul tempat ni.|ramai sekali tempat ini.}}'
376054
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} ghamai <!--Ramai
#: {{cp|ms|ghamai betul tempat ni.|ramai sekali tempat ini.}}
nk2flwgfs3493ywpa9ahkwam6mlaqu9
gampo
0
145947
376055
2026-09-26T08:46:00Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} gampo <!--tampar--> #: {{cp|ms|miko gampo budak tu tadi?.|kamu tampar anak itu tadi?.}}'
376055
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} gampo <!--tampar-->
#: {{cp|ms|miko gampo budak tu tadi?.|kamu tampar anak itu tadi?.}}
3b6njy3ug0gy6n2irrxz5zvx6wqlbst
ceracak
0
145948
376057
2026-09-26T08:46:18Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===ceracak=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} pancang kayu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang mengabek ceracak.|orang itu mengambil pancang kayu.}}'
376057
wikitext
text/x-wiki
==Bahasa Melayu==
===ceracak===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} pancang kayu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang mengabek ceracak.|orang itu mengambil pancang kayu.}}
0b27sdisx5ru57jh208qmx0dti4angf
cabak
0
145949
376058
2026-09-26T08:46:21Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} cabak <!--cangkul kecil--> #: {{cp|ms|kamarikan cabak tu.|bawak kembali cangkul itu.}}'
376058
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} cabak <!--cangkul kecil-->
#: {{cp|ms|kamarikan cabak tu.|bawak kembali cangkul itu.}}
ge3khq8mhn5inymp6xukwo9k7hoxm0p
lokik
0
145950
376059
2026-09-26T08:46:21Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} Pelit #: {{cp|ms|Pelit beno jadi oang.|Pelit betul jadi orang.}}'
376059
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} Pelit
#: {{cp|ms|Pelit beno jadi oang.|Pelit betul jadi orang.}}
gxmf291tj7s1m3opasnx67u5szaduoo
gonduik
0
145951
376061
2026-09-26T08:46:33Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mak menyisir gonduik adik.|ibu menyisir rambut adik.}}'
376061
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mak menyisir gonduik adik.|ibu menyisir rambut adik.}}
hooygeumor8bfkopv3x1xl4hrz9tuwz
nampo
0
145952
376062
2026-09-26T08:46:41Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} nampo <!--tampar--> #: {{cp|ms|aku tampo budak tu tadi.|saya tampar anak itu tadi.}}'
376062
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} nampo <!--tampar-->
#: {{cp|ms|aku tampo budak tu tadi.|saya tampar anak itu tadi.}}
py0osy6o2vnd7v160md5fm4kflptves
tetegou
0
145953
376063
2026-09-26T08:46:56Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Dumai}} Tetegou <!--tetegur--> #: {{cp|ms|siannyo budak tu tetegou .|kasihan anak itu tetegur.}}'
376063
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Dumai}} Tetegou <!--tetegur-->
#: {{cp|ms|siannyo budak tu tetegou .|kasihan anak itu tetegur.}}
mssq19vz39zmjh4yye54s6n9nrrihdf
beleseng
0
145954
376064
2026-09-26T08:47:34Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} beleseng <!--bercerita--> #: {{cp|ms|beleseng lah tu.|berceritalah itu.}}'
376064
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} beleseng <!--bercerita-->
#: {{cp|ms|beleseng lah tu.|berceritalah itu.}}
9zz6pyumtf8iqpcgctappad3v2m7dh0
boroh
0
145955
376067
2026-09-26T08:48:54Z
~2026-51734-64
11520
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} boroh<!—-mukak bengkak disengat lebah--> #: {{cp|ms|mukak malin boroh.|wajah malin bengkak.}}'
376067
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} boroh<!—-mukak bengkak disengat lebah-->
#: {{cp|ms|mukak malin boroh.|wajah malin bengkak.}}
jndi04xgub8q78kcq7h1fwj03xj6n2f
lenyak
0
145956
376068
2026-09-26T08:49:07Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Bengkalis}} lenyak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|lenyak ketawo.|kuat ketawa.}}'
376068
wikitext
text/x-wiki
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Bengkalis}} lenyak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|lenyak ketawo.|kuat ketawa.}}
r49kqkvogza2zsq0axzg0p3tgpofwiv
pelabu
0
145957
376070
2026-09-26T08:49:58Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} pelabu <!--pembohong--> #: {{cp|ms|cakap kau ni pelabu.|biacara kamu ini bohong.}}'
376070
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} pelabu <!--pembohong-->
#: {{cp|ms|cakap kau ni pelabu.|biacara kamu ini bohong.}}
twagsogwxvos4ny3l05vd9uhts9mw1q
antagho
0
145958
376072
2026-09-26T08:50:32Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} jarak (ruang, jauh) di sela-sela dua benda #: {{cp|ms|bola tu letaknyo di antagho lemari samo meja .|bola itu letaknya di antara lemari sama meja.}}'
376072
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} jarak (ruang, jauh) di sela-sela dua benda
#: {{cp|ms|bola tu letaknyo di antagho lemari samo meja .|bola itu letaknya di antara lemari sama meja.}}
0n0c8sutt8ylutinc0hn29pj7yozho0
baputau
0
145959
376073
2026-09-26T08:50:36Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kincir tu baputau di tiup angin.|kincir itu berputar tertiup angin.}}'
376073
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kincir tu baputau di tiup angin.|kincir itu berputar tertiup angin.}}
jxwmai0stm4vag4cx0ficmfzfjctych
ghambut
0
145960
376074
2026-09-26T08:50:45Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} ghambut <!--rambut--> #: {{cp|ms|ghambut engkau cantek betol.|rambut kamu cantik sekali.}}'
376074
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} ghambut <!--rambut-->
#: {{cp|ms|ghambut engkau cantek betol.|rambut kamu cantik sekali.}}
2hwhar61j2p1hsg3qaavdxy8eb5rp6g
tabayak
0
145961
376076
2026-09-26T08:51:13Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} tabayak<!--tumpah--> #:{{cp|ms|tabayak aiu tu kan.|jadi tumpah air itu }}'
376076
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} tabayak<!--tumpah-->
#:{{cp|ms|tabayak aiu tu kan.|jadi tumpah air itu }}
hw7wrduje2r91qa5f8o4tf1j4szr095
376158
376076
2026-09-26T09:15:40Z
SY Reski
10853
376158
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} tumpah <!--tumpah-->
#:{{cp|ms|tabayak aiu tu kan.|jadi tumpah air itu }}
tc9z16i50fd24797m2czh4s46mfnmps
keneng
0
145962
376077
2026-09-26T08:51:20Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===keneng=== {{lb|ms|kata benda}} # {{lb|ms|Pekanbaru}} dahi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|keneng budak tu bekeut.|dahi anak itu berkerut.}}'
376077
wikitext
text/x-wiki
==Bahasa Melayu==
===keneng===
{{lb|ms|kata benda}}
# {{lb|ms|Pekanbaru}} dahi <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|keneng budak tu bekeut.|dahi anak itu berkerut.}}
fr17y4pwb4xr8iy3dsj2p5gtgbk330z
membeghi
0
145963
376078
2026-09-26T08:51:22Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} membeghi <!--memberi--> #: {{cp|ms|mak dio membengi makan kucing.|ibu dia memberi makan kucing.}}'
376078
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} membeghi <!--memberi-->
#: {{cp|ms|mak dio membengi makan kucing.|ibu dia memberi makan kucing.}}
grlezbxsvch7ef1nlak7lxrusmndtdh
teghajang
0
145964
376079
2026-09-26T08:51:24Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Dumai}} Teghajang <!--tendang --> #: {{cp|ms|aku teghajang dikau kang!.|saya tendang kamu nanti.}}'
376079
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Dumai}} Teghajang <!--tendang -->
#: {{cp|ms|aku teghajang dikau kang!.|saya tendang kamu nanti.}}
cua2pp1y2splyuv12nmcx7nc00gwiab
kaedah
0
145965
376080
2026-09-26T08:51:56Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} kaedah<!--misalnya--> #: {{cp|ms|kaedahnyo lah tu.| misalnya lah tu.}}'
376080
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} kaedah<!--misalnya-->
#: {{cp|ms|kaedahnyo lah tu.| misalnya lah tu.}}
p0svnb9d3e6loeu8geffkxrnzijb699
joloh
0
145966
376082
2026-09-26T08:52:36Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} bodoh #: {{cp|ms|jolohnye budak ni.|bodohnya anak ni.}}'
376082
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} bodoh
#: {{cp|ms|jolohnye budak ni.|bodohnya anak ni.}}
pbp9oz4373bgjui0qbunwvwcwot434u
mendidio
0
145967
376083
2026-09-26T08:52:58Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Aek tu sedang mendidio.|air itu sedang mendidih.}}'
376083
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Aek tu sedang mendidio.|air itu sedang mendidih.}}
looobp072n1jtcn5ibtzubcmi3ppwb2
ghisau
0
145968
376084
2026-09-26T08:53:06Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} ghisau <!--cemas--> #: {{cp|ms|ghisau betul aku.|cemas sekali aku.}}'
376084
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} ghisau <!--cemas-->
#: {{cp|ms|ghisau betul aku.|cemas sekali aku.}}
6ng08wwxbvgougkbr4vi3v7ob8nohi4
caruk
0
145969
376085
2026-09-26T08:53:37Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kata benda}} caruk<!--Gelas pengukur beras dari kaleng--> #: {{cp|ms|due caruk beras.|dua gelas beras.}}'
376085
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kata benda}} caruk<!--Gelas pengukur beras dari kaleng-->
#: {{cp|ms|due caruk beras.|dua gelas beras.}}
son8niqoybfl5vh71c8sjhphxr0kgl4
suke
0
145970
376086
2026-09-26T08:53:59Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} suke <!--suka--> #: {{cp|ms|suke betol dengan miko ni.|suka sekali aku dengan kamu ini.}}'
376086
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} suke <!--suka-->
#: {{cp|ms|suke betol dengan miko ni.|suka sekali aku dengan kamu ini.}}
3whp6sq3atfg3rc9hr9zt5h9h46whyf
cekau
0
145971
376087
2026-09-26T08:54:02Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan 'Bahasa Melayu =Kata kerja= {{lb|ms|kata kerja}} {{lb|ms|Bengkalis}} Cekau. #: {{cp|ms|Burung helang tu mencekau anak ayam di laman.|Burung elang itu mencengkeram anak ayam di halaman.}}'
376087
wikitext
text/x-wiki
Bahasa Melayu
=Kata kerja=
{{lb|ms|kata kerja}}
{{lb|ms|Bengkalis}} Cekau.
#: {{cp|ms|Burung helang tu mencekau anak ayam di laman.|Burung elang itu mencengkeram anak ayam di halaman.}}
2jrilia9m6fbbzrtv5tt4xsehmpcmn3
tungkek
0
145972
376089
2026-09-26T08:54:28Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} tungkek <!--tongkat--> #:{{cp|ms|tolong ambiakkan tungkek Amak tu dih!|tolong ambilkan tongkat Ibu nak(pr)!}}'
376089
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} tungkek <!--tongkat-->
#:{{cp|ms|tolong ambiakkan tungkek Amak tu dih!|tolong ambilkan tongkat Ibu nak(pr)!}}
bwem2jdp001wgb8y7qihnpe95es03vz
tehempas
0
145973
376090
2026-09-26T08:54:37Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} tehempas <!--terdorong--> #: {{cp|ms|tehempas pintu tu a.|terdorong pintu itu.}}'
376090
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} tehempas <!--terdorong-->
#: {{cp|ms|tehempas pintu tu a.|terdorong pintu itu.}}
mdi49wovrumesnl5hsefwic3m1msdz9
tekong
0
145974
376091
2026-09-26T08:54:50Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} Tekong <!--ukuran beras--> #: {{cp|ms|beghapo tekong beras nak dimasak ni?.|berapa banyak beras yang mau dimasak ini?.}}'
376091
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} Tekong <!--ukuran beras-->
#: {{cp|ms|beghapo tekong beras nak dimasak ni?.|berapa banyak beras yang mau dimasak ini?.}}
eoek2klxsjrsjwk12hi32ymt3oznnrk
cinte
0
145975
376093
2026-09-26T08:55:36Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} cinte <!--cinta--> #: {{cp|ms|cinte engkau dengan die?.|cinta kamu sama dia?.}}'
376093
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} cinte <!--cinta-->
#: {{cp|ms|cinte engkau dengan die?.|cinta kamu sama dia?.}}
kgzhus0gzngfd4j3a2emyg1tdbg81um
teghang
0
145976
376094
2026-09-26T08:55:46Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata waktu=== {{lb|ms|kata waktu}} # {{lb|ms|Siak}} teghang <!--terang--> #: {{cp|ms|teghang betul lampu tu.|terang sekali lampu itu.}}'
376094
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata waktu===
{{lb|ms|kata waktu}}
# {{lb|ms|Siak}} teghang <!--terang-->
#: {{cp|ms|teghang betul lampu tu.|terang sekali lampu itu.}}
s4xo61p6empp1p4peykkvd9evon96p7
ketapang
0
145977
376095
2026-09-26T08:55:47Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} ketapang <!--ampas kelapa--> #: {{cp|ms|keringkan ketapang tu .|menjemur ampas kelapa.}}'
376095
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} ketapang <!--ampas kelapa-->
#: {{cp|ms|keringkan ketapang tu .|menjemur ampas kelapa.}}
91ipxf5l97bwexzpkp1k3slzimlba5c
lempo
0
145978
376096
2026-09-26T08:55:54Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Meranti}} Lempar #: {{cp|ms|Lempo bende tu kemari.|lempar benda tu kesini.}}'
376096
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Meranti}} Lempar
#: {{cp|ms|Lempo bende tu kemari.|lempar benda tu kesini.}}
kj9rpeugs5th2dwnejdjfxh4daotjqh
tampuong
0
145979
376097
2026-09-26T08:56:07Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tampuong aek hujan tu dalam.|tampung air hujan itu di dalam.}}'
376097
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tampuong aek hujan tu dalam.|tampung air hujan itu di dalam.}}
5vyhxnaxfe4crvt5hwmhd9pm8td3djf
basuh
0
145980
376100
2026-09-26T08:57:38Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} Basuh <!--Cuci--> #: {{cp|ms|Basuh muko tu lagi, cik.|Cuci muka tu lagi, nte.}}'
376100
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} Basuh <!--Cuci-->
#: {{cp|ms|Basuh muko tu lagi, cik.|Cuci muka tu lagi, nte.}}
6hq5z9eb3vmm4w3xlc89qzptt5adbnb
rumbuk
0
145981
376101
2026-09-26T08:58:09Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} rumbuk <!--alat pancing udang--> #: {{cp|ms|malin pasang rumbuk kat sungai.|malin menaruh alat pancing udang di sungai.}}'
376101
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} rumbuk <!--alat pancing udang-->
#: {{cp|ms|malin pasang rumbuk kat sungai.|malin menaruh alat pancing udang di sungai.}}
c2abz9pixn1kxeokssfl0hzbtb8mzvc
ketego
0
145982
376102
2026-09-26T08:58:40Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} ketego <!--tertegur--> #: {{cp|ms|dio ketego hantu.|dia tertegur hantu.}}'
376102
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} ketego <!--tertegur-->
#: {{cp|ms|dio ketego hantu.|dia tertegur hantu.}}
lfyynaa7il1bwzhkbg898q4u8tdbqvc
hangek
0
145983
376103
2026-09-26T08:58:54Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} Panas <!--Panas--> #: {{cp|ms|hangek betol.|panas sekali.}}'
376103
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} Panas <!--Panas-->
#: {{cp|ms|hangek betol.|panas sekali.}}
nzd6t6266hxzgzukqheux8lt0mtb74v
selopa
0
145984
376104
2026-09-26T08:59:21Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} selopah <!--sendal--> #: {{cp|ms|cantik selopah miko.|cantik sendal kamu.}}'
376104
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} selopah <!--sendal-->
#: {{cp|ms|cantik selopah miko.|cantik sendal kamu.}}
sq3gzkjwwf7gjnd6fwzdlub27fbu4gw
timbe
0
145985
376105
2026-09-26T08:59:40Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} Ember #: {{cp|ms|Pecah timbe tu kang.|Rusak ember tu nanti.}}'
376105
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} Ember
#: {{cp|ms|Pecah timbe tu kang.|Rusak ember tu nanti.}}
7hapgbne93bvs617acp7x8zr2prenjg
sanggung
0
145986
376107
2026-09-26T09:00:04Z
Yosi fadila
11515
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|kampar}} sanggung <!--alat penggusir serangga di sawah--> #: {{cp|ms|ambikkan sanggung tu.|ambilkan alat pengusir serangga itu.}}'
376107
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|kampar}} sanggung <!--alat penggusir serangga di sawah-->
#: {{cp|ms|ambikkan sanggung tu.|ambilkan alat pengusir serangga itu.}}
4y7kpcsc12iuy2u2ubkfed3399hvzyt
usah
0
145987
376108
2026-09-26T09:00:07Z
Robiyatuladawiyah05
11514
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Keterangan=== {{lb|ms|kata keterangan}} # {{lb|ms|Rokan Hilir}} Jangan <!--Jangan--> #: {{cp|ms|usah makan.|jangan makan.}}'
376108
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Keterangan===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} Jangan <!--Jangan-->
#: {{cp|ms|usah makan.|jangan makan.}}
mrg3954k13ahxentgtxi1r3r3eoe1li
bingal
0
145988
376110
2026-09-26T09:00:31Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===bingal=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} bandel <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|budak tu bingal betul.|anak tuh bandel sekali.}}'
376110
wikitext
text/x-wiki
==Bahasa Melayu==
===bingal===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} bandel <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|budak tu bingal betul.|anak tuh bandel sekali.}}
he6eg86c7se3iuu6bmq7zng0zre77g9
paso
0
145989
376111
2026-09-26T09:00:48Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} paso <!--pasar--> #: {{cp|ms|mak pegi ke paso.|ibu pergi ke pasar.}}'
376111
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} paso <!--pasar-->
#: {{cp|ms|mak pegi ke paso.|ibu pergi ke pasar.}}
aodlssuctb5uyqnhckrmq7m3b0upzpv
376114
376111
2026-09-26T09:01:37Z
Ressyaanggunapr
11519
376114
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} paso <!--pasar-->
#: {{cp|ms|mak pegi ke paso.|ibu pergi ke pasar.}}
ek6yqq13ywpd493gi54xghvjfzzdvte
aghus
0
145990
376112
2026-09-26T09:01:29Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} arus; gerak air yg mengalir;'
376112
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} arus; gerak air yg mengalir;
fmx5sarytg3wzxwa25qdnlkns3wah1d
menyughok
0
145991
376115
2026-09-26T09:01:37Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mak menyughok bunga di halaman.|ibu menyiram bunga di halaman.}}'
376115
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mak menyughok bunga di halaman.|ibu menyiram bunga di halaman.}}
ku9pvzfl7hv2qi2topoqgy9objdlbxp
meje
0
145992
376117
2026-09-26T09:02:19Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} meje <!--meja--> #: {{cp|ms|maje tu elok la.|meja itu bagus la.}}'
376117
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} meje <!--meja-->
#: {{cp|ms|maje tu elok la.|meja itu bagus la.}}
16xb5ft3582rzk3sbhaq3dzmbvfdkmf
ughang
0
145993
376119
2026-09-26T09:02:43Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|Kata benda}} #{{lb|ms|Kampar}} ughang <!--orang--> #:{{cp|ms|ughang tu poi ka sungai.|orang-orang pergi ke sungai.}}'
376119
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|Kata benda}}
#{{lb|ms|Kampar}} ughang <!--orang-->
#:{{cp|ms|ughang tu poi ka sungai.|orang-orang pergi ke sungai.}}
b4zo68typrh17vu0mvsvpew940exlwh
semabow
0
145994
376120
2026-09-26T09:03:02Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} semabow <!--tidak tentu--> #: {{cp|ms|semabow betul budak itu.|tidak tentu kamu ini.}}'
376120
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} semabow <!--tidak tentu-->
#: {{cp|ms|semabow betul budak itu.|tidak tentu kamu ini.}}
nqzaxlkgidb2dwld6sn0v563r0ij1cv
bayo
0
145995
376121
2026-09-26T09:03:03Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku nak bayo makanan ni.|aku mau membayar makanan ini.}}'
376121
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku nak bayo makanan ni.|aku mau membayar makanan ini.}}
k4qocyqyqg7eiovuwcq4iosqaq5sxsz
kobeh
0
145996
376122
2026-09-26T09:03:32Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===kobeh=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} kebas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kobeh kaki awak.| kakiku kebas.}}'
376122
wikitext
text/x-wiki
==Bahasa Melayu==
===kobeh===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} kebas <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kobeh kaki awak.| kakiku kebas.}}
n4s0s8mnp62s45c3wj47hhen2e36aui
Sengkelit
0
145997
376123
2026-09-26T09:03:48Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Sengkelit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Panglimo tu menyengkelit keris bertahta emas.|Panglima itu menyelipkan keris bertahta emas.}}'
376123
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Sengkelit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Panglimo tu menyengkelit keris bertahta emas.|Panglima itu menyelipkan keris bertahta emas.}}
1lvyp3j7mytagzky98spdpoysyy2kre
ikan biang
0
145998
376124
2026-09-26T09:04:09Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} Ikan Biang <!--Ikan llisha--> #: {{cp|ms|sedapnyo ikan biang tu .|nikmatnya ikan llisha tu ?.}}'
376124
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} Ikan Biang <!--Ikan llisha-->
#: {{cp|ms|sedapnyo ikan biang tu .|nikmatnya ikan llisha tu ?.}}
isum2rgsa50y6t7lmwnw1kh526mapd1
beso
0
145999
376125
2026-09-26T09:04:32Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} beso <!--besar--> #: {{cp|ms|umah tu beso betul.|rumah itu besar sekali.}}'
376125
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} beso <!--besar-->
#: {{cp|ms|umah tu beso betul.|rumah itu besar sekali.}}
manllso9hjkf6t1jlsgemv0cur8br2z
hanye
0
146000
376126
2026-09-26T09:04:33Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} hanye<!--amis--> #: {{cp|ms| hanye ikan itu.|amis ikan itu.}}'
376126
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} hanye<!--amis-->
#: {{cp|ms| hanye ikan itu.|amis ikan itu.}}
qqa3b7mm6j46xppeg7regbtui6zfr4h
aghah
0
146001
376128
2026-09-26T09:05:25Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} arah; jurusan; tujuan #: {{cp|ms|kemano aghah nyo ko?.|kemana arahnya ini?.}}'
376128
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} arah; jurusan; tujuan
#: {{cp|ms|kemano aghah nyo ko?.|kemana arahnya ini?.}}
rcf4gisssn906n3n1ovrengn5ev4zr6
membako
0
146002
376129
2026-09-26T09:05:27Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ayah membako sampah kat luo.|ayah membakar sampah di luar.}}'
376129
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ayah membako sampah kat luo.|ayah membakar sampah di luar.}}
l4vhltqi6n0m8uztf7siebtocof7c37
ruah
0
146003
376130
2026-09-26T09:05:32Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Ruah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Dah penat atok meruah kau balek ke ruma.|udah lelah kakek memanggilmu pulang ke rumah.}}'
376130
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Ruah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Dah penat atok meruah kau balek ke ruma.|udah lelah kakek memanggilmu pulang ke rumah.}}
mftbmg5g6bx5006v46k35ew59kjpwlv
belende
0
146004
376131
2026-09-26T09:06:05Z
ElsaDwiyanti
9890
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} belende <!--belendir--> #: {{cp|ms|temapat itu belende.|tempat itu belendir.}}'
376131
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} belende <!--belendir-->
#: {{cp|ms|temapat itu belende.|tempat itu belendir.}}
6at0dcf01cnatn7zdfkvt63k4rxxk6c
rinai
0
146005
376132
2026-09-26T09:06:18Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===kata benda=== {{lb|ms|kata benda}} # {{lb|ms|}} hujan <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376132
wikitext
text/x-wiki
==Bahasa Melayu==
===kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|}} hujan <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
0qkkyqhjdferopgouol659v4suucut1
376138
376132
2026-09-26T09:07:28Z
Thurama
11516
/* kata benda */
376138
wikitext
text/x-wiki
==Bahasa Melayu==
===kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|pekanbaru}} hujan <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
teuv7eev93p5s4wk54u60y486d5wi9t
dayu
0
146006
376133
2026-09-26T09:06:28Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===dayu=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} mengayun <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|miko becakap mendayu beno.|kamu berbicara telalu mengayun.}}'
376133
wikitext
text/x-wiki
==Bahasa Melayu==
===dayu===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} mengayun <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|miko becakap mendayu beno.|kamu berbicara telalu mengayun.}}
sag5t31mrh736tk9ewirk33mdi4p2bo
dio
0
146007
376134
2026-09-26T09:07:10Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} dio <!--dia--> #: {{cp|ms|dio di belajang umah.|dia di belakang rumah.}}'
376134
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} dio <!--dia-->
#: {{cp|ms|dio di belajang umah.|dia di belakang rumah.}}
gjlw72r6a97wccxpqhwmjaq1fkzqpaj
membongak
0
146008
376135
2026-09-26T09:07:12Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|jangan membongak dengan uwang tuo.|jangan berbohong kepada orang tua.}}'
376135
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|jangan membongak dengan uwang tuo.|jangan berbohong kepada orang tua.}}
adn1ve89awtlxzlctli0juunx139e0k
ikan lomek
0
146009
376136
2026-09-26T09:07:22Z
Devi Armanda Nasution
11513
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Dumai}} ikan lomek <!--ikan Harpodon--> #: {{cp|ms|sedap betullah ikan lomek tu!.|enak sekali ikan Harpodon itu!.}}'
376136
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Dumai}} ikan lomek <!--ikan Harpodon-->
#: {{cp|ms|sedap betullah ikan lomek tu!.|enak sekali ikan Harpodon itu!.}}
8zde7uwzeig9vs56wdrtenc012y29ad
ngantuak
0
146010
376139
2026-09-26T09:07:51Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} ngantuak <!--ngantuk--> #:{{cp|ms|ngantuak den a.|saya mengantuk.}}'
376139
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} ngantuak <!--ngantuk-->
#:{{cp|ms|ngantuak den a.|saya mengantuk.}}
emkhrgyoml98dfqr9g6gtyc0et3ta55
anak jilbab
0
146011
376140
2026-09-26T09:08:29Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} anak jilbab <!--ciput--> #: {{cp|ms|anak jilbab engkau baghu?.|ciput kamu baru?.}}'
376140
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} anak jilbab <!--ciput-->
#: {{cp|ms|anak jilbab engkau baghu?.|ciput kamu baru?.}}
4f6xwuttcwnh1ouwz5bh3dgpbvrs8x2
alou
0
146012
376141
2026-09-26T09:08:35Z
Taufik Hadris
9879
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} alur; bekas parit lama; #: {{cp|ms| apak tu membuek alou.|bapak itu membuat parit.}}'
376141
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} alur; bekas parit lama;
#: {{cp|ms| apak tu membuek alou.|bapak itu membuat parit.}}
gjjw2qyijz263hszud2lt6zgutdo1d0
tejopik
0
146013
376142
2026-09-26T09:08:50Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===tejopik=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hulu}} terjepit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tejopik tangan aku.|tangan aku terjepit.}}'
376142
wikitext
text/x-wiki
==Bahasa Melayu==
===tejopik===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hulu}} terjepit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tejopik tangan aku.|tangan aku terjepit.}}
bb8j6hfrmj07or29la18ckx2394vigu
recah
0
146014
376143
2026-09-26T09:09:20Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Recah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Terpakso kito merecah payo nak ke kebun.|Terpaksa kita menerjang rawa genangan air untuk pergi ke kebun.}}'
376143
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Recah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Terpakso kito merecah payo nak ke kebun.|Terpaksa kita menerjang rawa genangan air untuk pergi ke kebun.}}
amsfe0ktq0461klmhsr92bpbv4r1vj3
loyo
0
146015
376144
2026-09-26T09:11:15Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===loyo=== {{lb|ms|kata sifat}} # {{lb|ms|Pelalawan} lemah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|diaku ni loyo betul.|kamu ini lemah sekali.}}'
376144
wikitext
text/x-wiki
==Bahasa Melayu==
===loyo===
{{lb|ms|kata sifat}}
# {{lb|ms|Pelalawan} lemah <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|diaku ni loyo betul.|kamu ini lemah sekali.}}
me8qm9anyc1jgmjqq6tm92tastmr0u7
baghu
0
146016
376145
2026-09-26T09:11:27Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} baghu <!--baru--> #: {{cp|ms|baghu baju miko?.|baru baju kamu?.}}'
376145
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} baghu <!--baru-->
#: {{cp|ms|baghu baju miko?.|baru baju kamu?.}}
g07z9137caarduymvh2kpkc2tu6eat8
anak sedare
0
146017
376146
2026-09-26T09:11:39Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|anak sedare aku datang kerumah.|keponakan saya datang kerumah.}}'
376146
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|anak sedare aku datang kerumah.|keponakan saya datang kerumah.}}
rmv7ufor4pg2z6iuzcafd0pb2o7nnkq
SENTO
0
146018
376148
2026-09-26T09:12:12Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} sento <!--kusen--> #: {{cp|ms|bersihkan sento tu.|bersihkan kusen tu.}}'
376148
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} sento <!--kusen-->
#: {{cp|ms|bersihkan sento tu.|bersihkan kusen tu.}}
4j018jirbflptvwfz8hwxhoieujjbuj
sayou
0
146019
376149
2026-09-26T09:12:12Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} sayou <!--sayur--> #: {{cp|ms|dio beli sayou.|dia beli sayur.}}'
376149
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} sayou <!--sayur-->
#: {{cp|ms|dio beli sayou.|dia beli sayur.}}
66k2o8nab5zl12imw09k5uuzgldt2ms
potai
0
146020
376150
2026-09-26T09:12:44Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===potai=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hulu}} buah petai <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|awak nio potai tu.|aku mau buah petai itu.}}'
376150
wikitext
text/x-wiki
==Bahasa Melayu==
===potai===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hulu}} buah petai <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|awak nio potai tu.|aku mau buah petai itu.}}
b44cd9wrx9cur00dg87jdo0ou5qcx19
nyosa
0
146021
376151
2026-09-26T09:12:47Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} mencuci <!--mencuci-> #:{{cp|ms|sudah menyosa den tadi.|saya baru selesai mencuci pakaian.}}'
376151
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} mencuci <!--mencuci->
#:{{cp|ms|sudah menyosa den tadi.|saya baru selesai mencuci pakaian.}}
ddysz7zf75ygbda0417nzr48ig3rgm3
buaye
0
146022
376154
2026-09-26T09:14:17Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|buaye tu ade kat sungai.|buaya itu ada di sungai.}}'
376154
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|buaye tu ade kat sungai.|buaya itu ada di sungai.}}
mmhltrj4mz3actjpt9zzxe6icugzu9g
putio
0
146023
376155
2026-09-26T09:14:33Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===putio=== {{lb|ms|kata siifat}} # {{lb|ms|Rokan Hulu}} putih <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|baju aku warna putio.|bajuku warna putih.}}'
376155
wikitext
text/x-wiki
==Bahasa Melayu==
===putio===
{{lb|ms|kata siifat}}
# {{lb|ms|Rokan Hulu}} putih <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|baju aku warna putio.|bajuku warna putih.}}
4hya1paku04rb4v2jlhtj01gvogkvuf
lembik
0
146024
376156
2026-09-26T09:14:52Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} lembik <!--lembut--> #: {{cp|ms|dah lembik daging tu?.|udah lembut daging itu?.}}'
376156
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} lembik <!--lembut-->
#: {{cp|ms|dah lembik daging tu?.|udah lembut daging itu?.}}
49haxwlv68256s67hj7xyx1989blgpv
soghang
0
146025
376157
2026-09-26T09:15:08Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} soghang <!--sendiri--> #: {{cp|ms|dio pegi soghang.|dia pergi sendiri.}}'
376157
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} soghang <!--sendiri-->
#: {{cp|ms|dio pegi soghang.|dia pergi sendiri.}}
pyy5x4invfzdlfj4088yc6ml96jud5i
surih
0
146026
376159
2026-09-26T09:15:49Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Surih <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Payah nak menyurih parit batas tanah ni.|Susah menelusuri parit batas tanah ini.}}'
376159
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Surih <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Payah nak menyurih parit batas tanah ni.|Susah menelusuri parit batas tanah ini.}}
oa2ht798iigaakcu1vwtba2rixzpb1i
mak sedare
0
146027
376160
2026-09-26T09:15:50Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mak sedare datang kat umah.|bibi datang kerumah.}}'
376160
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mak sedare datang kat umah.|bibi datang kerumah.}}
c9im2kkeruzdyuaz6ay009g5pzvedny
seronok
0
146028
376161
2026-09-26T09:16:15Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} seru <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|seronok kali.|seru banget.}}'
376161
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} seru <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|seronok kali.|seru banget.}}
2k4ir9tusyi573x7nka6043u2c14535
takuik
0
146029
376162
2026-09-26T09:16:46Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===takuik=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} takut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|aku takuit.|aku takut.}}'
376162
wikitext
text/x-wiki
==Bahasa Melayu==
===takuik===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} takut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|aku takuit.|aku takut.}}
hg35ervs9rhym10pxj7g8gd0cyp9dpf
gune
0
146030
376163
2026-09-26T09:16:46Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} gune <!--manfaat--> #: {{cp|ms|tak ade gune.|tidak bermanfaat.}}'
376163
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} gune <!--manfaat-->
#: {{cp|ms|tak ade gune.|tidak bermanfaat.}}
qy3r8jk30plftkb3or0ox5dfac6b156
gule
0
146031
376165
2026-09-26T09:17:22Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|mak beli gule kat kedai.|ibu membeli gula di kedai.}}'
376165
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|mak beli gule kat kedai.|ibu membeli gula di kedai.}}
rpzi530dpfq51kjq5n0667uaewwpnbb
376169
376165
2026-09-26T09:19:15Z
Ressyaanggunapr
11519
376169
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} gula
#: {{cp|ms|mak beli gule kat kedai.|ibu membeli gula di kedai.}}
n43fc7zj74p5ddtmd757acx9g4aljtn
nondak
0
146032
376166
2026-09-26T09:17:30Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|Kata Kerja}} #{{lb|ms|Kampar}} ingin <!--nondak--> #:{{cp|ms|nondak duyan den.|saya ingin durian.}}'
376166
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|Kata Kerja}}
#{{lb|ms|Kampar}} ingin <!--nondak-->
#:{{cp|ms|nondak duyan den.|saya ingin durian.}}
hdauseeqhh2hjjtj150i049fh69sgdn
lokang
0
146033
376167
2026-09-26T09:18:08Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===lokang=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} lekang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|lokang sepatu aku.|lekang sepatu aku .}}'
376167
wikitext
text/x-wiki
==Bahasa Melayu==
===lokang===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} lekang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|lokang sepatu aku.|lekang sepatu aku .}}
o64ue7psd8v1ovrcldxe5enaws70uje
embut
0
146034
376168
2026-09-26T09:19:05Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Embut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Tinggal mengembut je nyalo pelito tu.|Tinggal redup kembang-kempis saja nyala pelita itu.}}'
376168
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Embut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Tinggal mengembut je nyalo pelito tu.|Tinggal redup kembang-kempis saja nyala pelita itu.}}
d6qas8t2vopw8lfkoqe05lpx8jhedfb
tekonang
0
146035
376170
2026-09-26T09:19:19Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===tekonang=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} teringat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tekonang budak tu.|terkenang anak itu.}}'
376170
wikitext
text/x-wiki
==Bahasa Melayu==
===tekonang===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} teringat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tekonang budak tu.|terkenang anak itu.}}
q8h76275gwnv4x8yx71er1mba33ym4i
mengapo
0
146036
376171
2026-09-26T09:19:26Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata keterangan tanya=== {{lb|ms|kata keterangan tanya}} # {{lb|ms|Siak}} mengapo <!--mengapa--> #: {{cp|ms|mengapo budak tu?.|mengapa anak itu?.}}'
376171
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata keterangan tanya===
{{lb|ms|kata keterangan tanya}}
# {{lb|ms|Siak}} mengapo <!--mengapa-->
#: {{cp|ms|mengapo budak tu?.|mengapa anak itu?.}}
ntuzjwxp1gbg9fdyma3v37cvzyaj34b
sunting
0
146037
376172
2026-09-26T09:20:05Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Kandis Siak}} potong; memotong <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376172
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Kandis Siak}} potong; memotong <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
pg0tmtaon4bf2e1i3w3dr0efp79h906
bewok
0
146038
376173
2026-09-26T09:20:22Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} bewok <!--jenggot--> #: {{cp|ms|panjang betol bewok miko.|panjang sekali janggut kamu.}}'
376173
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} bewok <!--jenggot-->
#: {{cp|ms|panjang betol bewok miko.|panjang sekali janggut kamu.}}
gpofl9ojf7r1igefhrhennebxb30i2y
batuok
0
146039
376174
2026-09-26T09:20:41Z
Adya cantika
11518
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Adik batuok sejak pagi tadi.|adik batuk sejak tadi pagi.}}'
376174
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Adik batuok sejak pagi tadi.|adik batuk sejak tadi pagi.}}
3ms8n2d988832qlglwbboocq4avqigm
Selingar
0
146040
376175
2026-09-26T09:20:50Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Selingar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Menyelingar dio tekejut dengar suaro guruh.|Terkesiap dia terkejut mendengar suara guntur.}}'
376175
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Selingar <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Menyelingar dio tekejut dengar suaro guruh.|Terkesiap dia terkejut mendengar suara guntur.}}
5kwxznaqojxiynnau5eybqr1g5spqjp
koncang
0
146041
376176
2026-09-26T09:21:17Z
Siswanto Unilak
11022
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===koncang=== {{lb|ms|kata sifat}} # {{lb|ms|Rokan Hilir}} cepat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|koncang lai budak tu.|cepat lari anak itu.}}'
376176
wikitext
text/x-wiki
==Bahasa Melayu==
===koncang===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} cepat <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|koncang lai budak tu.|cepat lari anak itu.}}
b83i6bq8ywujx53s5yt1oqohlagzjip
ringas
0
146042
376177
2026-09-26T09:21:25Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} risih #: {{cp|ms|ringas aku dekat sini.|risih aku dekat sini.}}'
376177
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} risih
#: {{cp|ms|ringas aku dekat sini.|risih aku dekat sini.}}
dfd93u8hxlza07qcdokjno3z9ahcwxc
mate ae
0
146043
376179
2026-09-26T09:23:17Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} Mata air #: {{cp|ms|Disane ade mate ae dak?.|Disana ada mata air tak?.}}'
376179
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} Mata air
#: {{cp|ms|Disane ade mate ae dak?.|Disana ada mata air tak?.}}
84yhpe9kgfx1shwz0lh9ohmc8p1c7di
sosoh
0
146044
376180
2026-09-26T09:23:25Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Sosoh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Mak tengah menyosoh boreh di dapur.|Ibu sedang menumbuk putih beras di dapur.}}'
376180
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Sosoh <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Mak tengah menyosoh boreh di dapur.|Ibu sedang menumbuk putih beras di dapur.}}
h0tnw6cpfvjariwks9fh99m3e88n8tn
geledur
0
146045
376184
2026-09-26T09:26:20Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Geledur <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Kerjo kau asyik menggeledur je dari pagi.|Kerjamu asyik berbaring bermalas-malasan saja dari pagi.}}'
376184
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Geledur <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Kerjo kau asyik menggeledur je dari pagi.|Kerjamu asyik berbaring bermalas-malasan saja dari pagi.}}
9ib5mq4fbkh57ztruezx8y17otyylp1
sempet
0
146046
376185
2026-09-26T09:26:32Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} Sempit #: {{cp|ms|sempet beno tempat ni.|sempit betul tempat ini.}}'
376185
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} Sempit
#: {{cp|ms|sempet beno tempat ni.|sempit betul tempat ini.}}
02ijlw2h9r6q0w3ugdu73plouv5fw1f
tebarai
0
146047
376186
2026-09-26T09:27:54Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} tebarai <!--terlepas--> #: {{cp|ms|papan tu tebarai dari dinding.|papan itu terlepas dari dinding.}}'
376186
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} tebarai <!--terlepas-->
#: {{cp|ms|papan tu tebarai dari dinding.|papan itu terlepas dari dinding.}}
qw5hbvymjgmfs7tjt9tz0q7mb24r1k7
negow
0
146048
376187
2026-09-26T09:28:38Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata Sifat=== {{lb|ms|kata Sifat}} # {{lb|ms|Meranti}} tegur #: {{cp|ms|dikau tak negow aku tadi.|kamu ga negur aku tadi.}}'
376187
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata Sifat===
{{lb|ms|kata Sifat}}
# {{lb|ms|Meranti}} tegur
#: {{cp|ms|dikau tak negow aku tadi.|kamu ga negur aku tadi.}}
4baaeilannjuv3jcuoudew6gae8c82s
jelepok
0
146049
376188
2026-09-26T09:28:49Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Jelepok <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Menjelepok pakcik tu penat bejalan jauh.|Jatuh terduduk paman itu lelah berjalan jauh..}}'
376188
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Jelepok <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Menjelepok pakcik tu penat bejalan jauh.|Jatuh terduduk paman itu lelah berjalan jauh..}}
s3lknw9wsmdxncvq7wtd0oowbwkxw2e
celote
0
146050
376189
2026-09-26T09:29:12Z
Rabiyatun Adawiyah
11517
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} celote <!--ngomong terus--> #: {{cp|ms|celote betol engkau ni.|ngomong terus kamu ni.}}'
376189
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} celote <!--ngomong terus-->
#: {{cp|ms|celote betol engkau ni.|ngomong terus kamu ni.}}
lfc6h44qg730jyfcb0ch76wxwqh4dzt
ceme'eh
0
146051
376190
2026-09-26T09:31:15Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} ejekan, mengejek, cemoohan kepada orang lain <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376190
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} ejekan, mengejek, cemoohan kepada orang lain <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
evqu9nuagvsv8zvbsid00unoz2vgc7s
tangge
0
146052
376191
2026-09-26T09:31:25Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} tangga #: {{cp|ms|aku lewat tangge dekat situ.|aku lewat tangga disana.}}'
376191
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} tangga
#: {{cp|ms|aku lewat tangge dekat situ.|aku lewat tangga disana.}}
93hq7cerk9mgw94174tvl4xrcqwoakm
beghangkat
0
146053
376193
2026-09-26T09:31:48Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} beghangkat <!--berangkat--> #: {{cp|ms|dio dah beghangkat.|dia sudah berangkat.}}'
376193
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} beghangkat <!--berangkat-->
#: {{cp|ms|dio dah beghangkat.|dia sudah berangkat.}}
ngz6iegpbbtxpfvnjeyq7dptoir7j1r
bibei
0
146054
376195
2026-09-26T09:32:51Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} bibir #: {{cp|ms|bibei dikau ade lade.|bibir kamu ada cabe.}}'
376195
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} bibir
#: {{cp|ms|bibei dikau ade lade.|bibir kamu ada cabe.}}
8af6mun0o9ufn8g3tkh3rgqokn1gr4h
bom bon
0
146055
376196
2026-09-26T09:32:58Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|pekanbaru}} permen <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376196
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|pekanbaru}} permen <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
0xhtud8s69jxbr191ksyqfj9i3b9d26
ghimau
0
146056
376198
2026-09-26T09:34:42Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} ghimau <!--harimau--> #: {{cp|ms|ghimau tu dah mati kat sano.|harimau itu sudah mati di sana.}}'
376198
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} ghimau <!--harimau-->
#: {{cp|ms|ghimau tu dah mati kat sano.|harimau itu sudah mati di sana.}}
5e3223zvhas30gub0x3zubpzh74wrsx
kubou
0
146057
376199
2026-09-26T09:36:00Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Meranti}} kubur #: {{cp|ms|aku abis dari kubou|aku habis dari kubur.}}'
376199
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Meranti}} kubur
#: {{cp|ms|aku abis dari kubou|aku habis dari kubur.}}
ojvqk0d5vlzhs9h6igbkcho2krzqljn
keluo
0
146058
376200
2026-09-26T09:36:52Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} keluo <!--keluar--> #: {{cp|ms|dah keluo duit tu.|sudah keluar duit itu.}}'
376200
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} keluo <!--keluar-->
#: {{cp|ms|dah keluo duit tu.|sudah keluar duit itu.}}
s7wqnon0zqqjllz218b2jo8nuatouqh
Langut
0
146059
376201
2026-09-26T09:37:44Z
Elvaretta Vito
11512
Mencipta laman baru dengan kandungan '===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Bengkalis}} Langut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|Apo yang kau tengok melangut di muko pintu tu?|Apa yang kamu lihat melamun di depan pintu itu?.}}'
376201
wikitext
text/x-wiki
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Bengkalis}} Langut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|Apo yang kau tengok melangut di muko pintu tu?|Apa yang kamu lihat melamun di depan pintu itu?.}}
16egqxis7qd3euny8m6ainowddb24r1
bepikei
0
146060
376202
2026-09-26T09:38:45Z
HafizahNurainii
11023
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata kerja=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} bepikei <!--berfikir--> #: {{cp|ms|dio tengah bepikei.|dio sedang berfikir.}}'
376202
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata kerja===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} bepikei <!--berfikir-->
#: {{cp|ms|dio tengah bepikei.|dio sedang berfikir.}}
r2ac76mwo04710jepe8y7lv16e969tx
seloroh
0
146061
376203
2026-09-26T09:39:24Z
Ressyaanggunapr
11519
Mencipta laman baru dengan kandungan '==Bahasa Melayu Siak== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Meranti}} bercanda #: {{cp|ms|seloroh terus dikau ni.|bercanda terus kamu ni.}}'
376203
wikitext
text/x-wiki
==Bahasa Melayu Siak==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Meranti}} bercanda
#: {{cp|ms|seloroh terus dikau ni.|bercanda terus kamu ni.}}
2o2obwaemrk3iitum0mdnbomlgxs26w
kojai
0
146062
376208
2026-09-26T09:45:24Z
SY Reski
10853
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|Kata Benda}} #{{lb|ms|Kampar}} karet gelang <!--kojai--> #:{{cp|ms|ambiokkan kojai tu yung.|tolong ambilkan karet gelang tu nak (lk).}}'
376208
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|Kata Benda}}
#{{lb|ms|Kampar}} karet gelang <!--kojai-->
#:{{cp|ms|ambiokkan kojai tu yung.|tolong ambilkan karet gelang tu nak (lk).}}
hiskcwd8u5jeoyakcq0bz8a2bugk9n7
lokeh
0
146063
376211
2026-09-26T09:49:05Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===lokeh=== {{lb|ms|kata keterangan}} # {{lb|ms|Rokan Hilir}} segara <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|lokeh sombuh ya kawan.|segera sembuh ya teman.}}'
376211
wikitext
text/x-wiki
==Bahasa Melayu==
===lokeh===
{{lb|ms|kata keterangan}}
# {{lb|ms|Rokan Hilir}} segara <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|lokeh sombuh ya kawan.|segera sembuh ya teman.}}
m1ukiqnxgkno1fidmtkaiol1ir42e88
sompik
0
146064
376212
2026-09-26T09:53:28Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===sompik=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|dah sompik celana aku dah.|sudah sempit celana aku dah.}}'
376212
wikitext
text/x-wiki
==Bahasa Melayu==
===sompik===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|dah sompik celana aku dah.|sudah sempit celana aku dah.}}
5nvoxthit8t9qz933rmkbhigomt3nvd
376213
376212
2026-09-26T09:54:10Z
Andrian Ramadani
9891
/* sompik */
376213
wikitext
text/x-wiki
==Bahasa Melayu==
===sompik===
{{lb|ms|kata sifat}}
# {{lb|ms|Rokan Hilir}} sempit<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|dah sompik celana aku dah.|sudah sempit celana aku dah.}}
8r602docfcok64roopx80nuv8h9ezxb
colak
0
146065
376214
2026-09-26T09:58:22Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===colak=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hilir}} celak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|cantik colak kau.|bagus colak kamu.}}'
376214
wikitext
text/x-wiki
==Bahasa Melayu==
===colak===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hilir}} celak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|cantik colak kau.|bagus colak kamu.}}
fkrx68uks8ca2zsxldlqv1ipy5rlplq
tekile
0
146066
376215
2026-09-26T10:00:47Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Tekili=== {{lb|ms|kata kerja}} # {{lb|ms|Siak}} terkilir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kaki aku tekile.|kaki saya terkilir.}}'
376215
wikitext
text/x-wiki
==Bahasa Melayu==
===Tekili===
{{lb|ms|kata kerja}}
# {{lb|ms|Siak}} terkilir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kaki aku tekile.|kaki saya terkilir.}}
bc8bww84fk3pj5j1fbnhuyu0hcqxycj
376216
376215
2026-09-26T10:01:08Z
Andrian Ramadani
9891
/* Tekili */
376216
wikitext
text/x-wiki
==Bahasa Melayu==
===Tekili===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} terkilir <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kaki aku tekile.|kaki saya terkilir.}}
lveyjsv4mwdk0uco3kei8lf0bix33vq
umpuik
0
146067
376217
2026-09-26T10:03:54Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Umpuik=== {{lb|ms|kata benda}} # {{lb|ms|Rokan Hilir}} Rumput <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|potongkan umpuik dopan umah tu.|potong rumput depan rumah itu.}}'
376217
wikitext
text/x-wiki
==Bahasa Melayu==
===Umpuik===
{{lb|ms|kata benda}}
# {{lb|ms|Rokan Hilir}} Rumput <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|potongkan umpuik dopan umah tu.|potong rumput depan rumah itu.}}
j8iwywbhqsbdrttlcvy0sq4oauyo05i
senso
0
146068
376218
2026-09-26T10:04:24Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|pekanbaru}} chainsaw, alat untuk memotong kagu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376218
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|pekanbaru}} chainsaw, alat untuk memotong kagu <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
m569wd6slfovgw8j2q6vlfblevati93
tokan
0
146069
376219
2026-09-26T10:07:18Z
Andrian Ramadani
9891
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Tokan=== {{lb|ms|kata kerja}} # {{lb|ms|Rokan Hilir}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|tokan pintu tu lai.|tekan lagi pintu itu.}}'
376219
wikitext
text/x-wiki
==Bahasa Melayu==
===Tokan===
{{lb|ms|kata kerja}}
# {{lb|ms|Rokan Hilir}} orang <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|tokan pintu tu lai.|tekan lagi pintu itu.}}
0winmzd25ctvmc3yo9ntkl01g0cwvmc
merajuk
0
146070
376220
2026-09-26T10:12:49Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Siak}} marah, ngambek, sikap menunjukkan rasa tidak senang dengan cara mendiamkan, tidak mau bergaul, atau bersungut-sungut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376220
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Siak}} marah, ngambek, sikap menunjukkan rasa tidak senang dengan cara mendiamkan, tidak mau bergaul, atau bersungut-sungut <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
55xp3i7rq2147tbvgy50kgvbnx60sgf
hangul
0
146071
376221
2026-09-26T11:19:38Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|Pekanbaru}} rasa makanan yang terlalu banyak kunyit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376221
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|Pekanbaru}} rasa makanan yang terlalu banyak kunyit <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
rqhj9ou3ufkgy68ju27yjuxx1giiwms
narosa
0
146072
376223
2026-09-26T11:23:08Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Pekanbaru}} musala kecil di tepian sungai (3-5 orang) <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376223
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Pekanbaru}} musala kecil di tepian sungai (3-5 orang) <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
4dm653pc5odvkewyq4dj4jsb1pwjewm
teh obeng
0
146073
376224
2026-09-26T11:29:10Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|batam}} teh apeng; seduhan teh dengan es kristal. <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376224
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|batam}} teh apeng; seduhan teh dengan es kristal. <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
li3gept6avn70oudm2v7s1kb9ak3egw
gegeh
0
146074
376225
2026-09-26T11:42:48Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|kualo bangko}} merasa mampu padahal tidak mampu; cakap besar<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->'
376225
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|kualo bangko}} merasa mampu padahal tidak mampu; cakap besar<!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
jwv4xx060broexvv7sedgedk533uvud
kuok
0
146075
376228
2026-09-26T11:52:15Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata benda=== {{lb|ms|kata benda}} # {{lb|ms|Siak}} kayu yang mempunyai kesaktian; kayu ini bisa digunakan sebagai alat bajak (kayu kuok); nama daerah di kampar; suara yang terdengar dari kendaraan yang membuat air disekitar berombak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|ughang tu nak kamano?.|orang itu mau kamana?.}}9'
376228
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} kayu yang mempunyai kesaktian; kayu ini bisa digunakan sebagai alat bajak (kayu kuok); nama daerah di kampar; suara yang terdengar dari kendaraan yang membuat air disekitar berombak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|ughang tu nak kamano?.|orang itu mau kamana?.}}9
l1l3bvo1bbhbbzb6p4couzimnlmz2si
376229
376228
2026-09-26T11:52:52Z
Thurama
11516
376229
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata benda===
{{lb|ms|kata benda}}
# {{lb|ms|Siak}} kayu yang mempunyai kesaktian; kayu ini bisa digunakan sebagai alat bajak (kayu kuok); nama daerah di kampar; suara yang terdengar dari kendaraan yang membuat air disekitar berombak <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
gfnh1rx8scazn03ihcn7j9mzgs1ox7y
kacau
0
146076
376231
2026-09-26T11:58:23Z
Thurama
11516
Mencipta laman baru dengan kandungan '==Bahasa Melayu== ===Kata sifat=== {{lb|ms|kata sifat}} # {{lb|ms|pekanbaru}} dikacau; mengaduk-aduk <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai--> #: {{cp|ms|kacau lah minuman ni dulu.|aduklah dulu minuman ini.}}'
376231
wikitext
text/x-wiki
==Bahasa Melayu==
===Kata sifat===
{{lb|ms|kata sifat}}
# {{lb|ms|pekanbaru}} dikacau; mengaduk-aduk <!--Ganti dengan erti kata yang dimasukkan dalam Bahasa Melayu Piawai-->
#: {{cp|ms|kacau lah minuman ni dulu.|aduklah dulu minuman ini.}}
3t3huyida9cykdhrhnk9kkuwsx0tihw