Wiktionary
viwiktionary
https://vi.wiktionary.org/wiki/Wiktionary:Trang_Ch%C3%ADnh
MediaWiki 1.47.0-wmf.24
case-sensitive
Phương tiện
Đặc biệt
Thảo luận
Thành viên
Thảo luận Thành viên
Wiktionary
Thảo luận Wiktionary
Tập tin
Thảo luận Tập tin
MediaWiki
Thảo luận MediaWiki
Bản mẫu
Thảo luận Bản mẫu
Trợ giúp
Thảo luận Trợ giúp
Thể loại
Thảo luận Thể loại
Phụ lục
Thảo luận Phụ lục
TimedText
TimedText talk
Mô đun
Thảo luận Mô đun
Sự kiện
Thảo luận Sự kiện
Wiktionary:Tin tức
4
644
2573047
2572754
2026-10-23T15:54:00Z
Hiyuune
50834
2573047
wikitext
text/x-wiki
__NOTOC__
{{Lưu trữ|
{{*ym|year=2004–2009|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2010–2020|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2021–2023|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2024|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2025|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2026|month=no|base=Wiktionary:Tin tức}}
}}
Trang này dành cho '''tin tức về dự án''' [[Wiktionary]] tiếng Việt nói riêng hay về cộng đồng Wiktionary nói chung. Bạn có biết tin tức mới không? Mời bạn ghi ra đây!
Bạn có thể chọn nút theo dõi trang để cập nhật tin tức tại [[Đặc biệt:Danh sách theo dõi|Danh sách theo dõi]].<!-- Nếu bạn đang cộng thêm một ngày nữa, và nếu đã có năm ngày ở trang này rồi, xin bạn xoá mục cuối cùng và bỏ tin tức mới trên những mục đã có rồi. Rồi, xin bạn thêm tin tức mới vào trang lưu trữ cho tháng năm phù hợp. Cám ơn. -->
== Tháng 10 năm 2026 ==
=== Thứ năm, ngày 22 tháng 10 năm 2026 ===
* {{l|tnc|Ᵽ}} trở thành mục từ tiếng Tanimuca-Retuarã đầu tiên của Wiktionary tiếng Việt.
* {{l|srm|akata}} trở thành mục từ tiếng Saramacca đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 20 tháng 10 năm 2026 ===
* {{l|nbn|wer}} trở thành mục từ tiếng Kuri đầu tiên của Wiktionary tiếng Việt.
* {{l|bls|luton}} trở thành mục từ tiếng Balaesang đầu tiên của Wiktionary tiếng Việt.
* {{l|bot|kii}} đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Bongo và Chickasaw.
* {{l|myz|ࡋࡄࡀࡌࡀ}} trở thành mục từ tiếng Manda cổ điển đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 19 tháng 10 năm 2026 ===
* {{l|hmx-pro|*djuŋᴴ}} trở thành mục từ tiếng H'Mông-Miền nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 18 tháng 10 năm 2026 ===
* {{l|lbk|awak}} trở thành mục từ tiếng Bontoc Trung đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 17 tháng 10 năm 2026 ===
* {{l|ayn|ת}} trở thành mục từ tiếng Ả Rập Sana'a đầu tiên của Wiktionary tiếng Việt.
* {{l|ayk|iraru}} trở thành mục từ tiếng Akuku đầu tiên của Wiktionary tiếng Việt.
* {{l|knb|atod}} trở thành mục từ tiếng Kalinga Lubuagan đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 4 tháng 10 năm 2026 ===
* {{l|shx|ɔŋ⁵³}} trở thành mục từ tiếng Xa đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 14 tháng 10 năm 2026 ===
* {{l|wbp|mula}} trở thành mục từ tiếng Warlpiri đầu tiên của Wiktionary tiếng Việt.
* {{l|aus-pam-pro|*calañ}} trở thành mục từ tiếng Pama-Nyungar nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|wyb|thalay}} trở thành mục từ tiếng Ngiyambaa đầu tiên của Wiktionary tiếng Việt.
* {{l|aus-cww-pro|*balaŋ}} trở thành mục từ tiếng Trung New South Wales nguyên thủy đầu tiên của Wiktionary tiếng Việt.
== Tháng 9 năm 2026 ==
=== Thứ ba, ngày 29 tháng 9 năm 2026 ===
* {{l|svs|kurakurape}} trở thành mục từ tiếng Savosavo đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 23 tháng 9 năm 2026 ===
* {{l|pgl|ᚃᚓᚂᚔᚈᚐᚄ}} trở thành mục từ tiếng Ireland nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 19 tháng 9 năm 2026 ===
* {{l|buq|yaŋ}} trở thành mục từ tiếng Brem đầu tiên của Wiktionary tiếng Việt.
=== Thứ sáu, ngày 18 tháng 9 năm 2026 ===
* {{l|kus|kpan}} trở thành mục từ tiếng Kusaal đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 17 tháng 9 năm 2026 ===
* {{l|nhu|wú}} trở thành mục từ tiếng Noone đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 9 tháng 9 năm 2026 ===
* {{l|inc-ogu|कमल}} trở thành mục từ tiếng Gujarat cổ đầu tiên của Wiktionary tiếng Việt.
* {{l|zpc|Z̃}} trở thành mục từ tiếng Zapotec Choapan đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 8 tháng 9 năm 2026 ===
* {{l|ine-ana-pro|*ʔésti}} trở thành mục từ tiếng Tiểu Á nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|tuw-pro|*ŋōlimi}} trở thành mục từ tiếng Tungus nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 6 tháng 9 năm 2026 ===
* {{l|afa-pro|*waraḳ-}} trở thành mục từ tiếng Phi-Á nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 3 tháng 9 năm 2026 ===
* {{l|cau-drg-pro|*xin}} trở thành mục từ tiếng Dargwa nguyên thủy đầu tiên của Wiktionary tiếng Việt.
== Tháng 8 năm 2026 ==
=== Thứ hai, ngày 31 tháng 8 năm 2026 ===
* {{l|aoa|awa}} trở thành mục từ tiếng Angola đầu tiên của Wiktionary tiếng Việt.
* {{l|chm-pro|*ik}} trở thành mục từ tiếng Mari nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|urj-mdv-pro|*tumə}} trở thành mục từ tiếng Mordvin nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 30 tháng 8 năm 2026 ===
* {{l|ghc|adhaigh}} trở thành mục từ tiếng Gael cổ điển đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 29 tháng 8 năm 2026 ===
* [[kani]] đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Culli và Maia.
* {{l|ngf-pro|*imbi}} trở thành mục từ tiếng Liên New Guinea nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|agm|kaatɨ-́há}} trở thành mục từ tiếng Angaataha đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 26 tháng 8 năm 2026 ===
* {{l|vls|bieë}} trở thành mục từ tiếng Flemish Tây đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 24 tháng 8 năm 2026 ===
* {{l|sdc|rui}} trở thành mục từ tiếng Sassari đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 23 tháng 8 năm 2026 ===
* {{l|mis-xbi|啊干|tr=*aqa(n)}} trở thành mục từ tiếng Tiên Ti đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 2 tháng 8 năm 2026 ===
* {{l|iro-nor-pro|*-nõhs-}} trở thành mục từ tiếng Bắc Iroquois nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 3 tháng 8 năm 2026 ===
* {{l|sem-wes-pro|*baḥr-}} trở thành mục từ tiếng Semit Tây nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|qfa-cka-pro|*'iməl}} trở thành mục từ tiếng Chukotka-Kamchatka nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|aql-pro|*le·kʔawe}} trở thành mục từ tiếng Algic nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 4 tháng 8 năm 2026 ===
* {{l|owl|carrecc}} trở thành mục từ tiếng Wales cổ đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 5 tháng 8 năm 2026 ===
* {{l|grk-pro|*pʰernā́}} trở thành mục từ tiếng Hellen nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 6 tháng 8 năm 2026 ===
* {{l|tfn|esbay}} trở thành mục từ tiếng Dena'ina đầu tiên của Wiktionary tiếng Việt.
* {{l|gmq-mno|dammr}} trở thành mục từ tiếng Na Uy trung đại đầu tiên của Wiktionary tiếng Việt.
* {{l|tbq-lob-pro|*b-ləy²}} trở thành mục từ tiếng Lô Lô-Miến nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ sáu, ngày 7 tháng 8 năm 2026 ===
* {{l|smw|asu}} đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Sumbawa và Alune.
=== Thứ ba, ngày 11 tháng 8 năm 2026 ===
* {{l|cau-nec-pro|*u̯aran}} trở thành mục từ tiếng Đông Bắc Kavkaz nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 13 tháng 8 năm 2026 ===
* {{l|mge|Ɔ̰}} trở thành mục từ tiếng Mango đầu tiên của Wiktionary tiếng Việt.
== Xem thêm ==
*[[Thành viên:WikimediaNotifier/notifications|Thời sự Wikimedia]]
*[[m:Tin tức về Wikimedia|Tin tức Wikimedia]]
[[Thể loại:Tin tức Wiktionary| ]]
[[Thể loại:Cộng đồng Wiktionary|{{PAGENAME}}]]
tg2sql9ktt4kjflkkpf7c34pmlv1u20
2573048
2573047
2026-10-23T15:54:22Z
Hiyuune
50834
2573048
wikitext
text/x-wiki
__NOTOC__
{{Lưu trữ|
{{*ym|year=2004–2009|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2010–2020|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2021–2023|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2024|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2025|month=no|base=Wiktionary:Tin tức}}
{{*ym|year=2026|month=no|base=Wiktionary:Tin tức}}
}}
Trang này dành cho '''tin tức về dự án''' [[Wiktionary]] tiếng Việt nói riêng hay về cộng đồng Wiktionary nói chung. Bạn có biết tin tức mới không? Mời bạn ghi ra đây!
Bạn có thể chọn nút theo dõi trang để cập nhật tin tức tại [[Đặc biệt:Danh sách theo dõi|Danh sách theo dõi]].<!-- Nếu bạn đang cộng thêm một ngày nữa, và nếu đã có năm ngày ở trang này rồi, xin bạn xoá mục cuối cùng và bỏ tin tức mới trên những mục đã có rồi. Rồi, xin bạn thêm tin tức mới vào trang lưu trữ cho tháng năm phù hợp. Cám ơn. -->
== Tháng 10 năm 2026 ==
=== Thứ sáu, ngày 23 tháng 10 năm 2026 ===
* {{l|srm|akata}} trở thành mục từ tiếng Saramacca đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 22 tháng 10 năm 2026 ===
* {{l|tnc|Ᵽ}} trở thành mục từ tiếng Tanimuca-Retuarã đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 20 tháng 10 năm 2026 ===
* {{l|nbn|wer}} trở thành mục từ tiếng Kuri đầu tiên của Wiktionary tiếng Việt.
* {{l|bls|luton}} trở thành mục từ tiếng Balaesang đầu tiên của Wiktionary tiếng Việt.
* {{l|bot|kii}} đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Bongo và Chickasaw.
* {{l|myz|ࡋࡄࡀࡌࡀ}} trở thành mục từ tiếng Manda cổ điển đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 19 tháng 10 năm 2026 ===
* {{l|hmx-pro|*djuŋᴴ}} trở thành mục từ tiếng H'Mông-Miền nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 18 tháng 10 năm 2026 ===
* {{l|lbk|awak}} trở thành mục từ tiếng Bontoc Trung đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 17 tháng 10 năm 2026 ===
* {{l|ayn|ת}} trở thành mục từ tiếng Ả Rập Sana'a đầu tiên của Wiktionary tiếng Việt.
* {{l|ayk|iraru}} trở thành mục từ tiếng Akuku đầu tiên của Wiktionary tiếng Việt.
* {{l|knb|atod}} trở thành mục từ tiếng Kalinga Lubuagan đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 4 tháng 10 năm 2026 ===
* {{l|shx|ɔŋ⁵³}} trở thành mục từ tiếng Xa đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 14 tháng 10 năm 2026 ===
* {{l|wbp|mula}} trở thành mục từ tiếng Warlpiri đầu tiên của Wiktionary tiếng Việt.
* {{l|aus-pam-pro|*calañ}} trở thành mục từ tiếng Pama-Nyungar nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|wyb|thalay}} trở thành mục từ tiếng Ngiyambaa đầu tiên của Wiktionary tiếng Việt.
* {{l|aus-cww-pro|*balaŋ}} trở thành mục từ tiếng Trung New South Wales nguyên thủy đầu tiên của Wiktionary tiếng Việt.
== Tháng 9 năm 2026 ==
=== Thứ ba, ngày 29 tháng 9 năm 2026 ===
* {{l|svs|kurakurape}} trở thành mục từ tiếng Savosavo đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 23 tháng 9 năm 2026 ===
* {{l|pgl|ᚃᚓᚂᚔᚈᚐᚄ}} trở thành mục từ tiếng Ireland nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 19 tháng 9 năm 2026 ===
* {{l|buq|yaŋ}} trở thành mục từ tiếng Brem đầu tiên của Wiktionary tiếng Việt.
=== Thứ sáu, ngày 18 tháng 9 năm 2026 ===
* {{l|kus|kpan}} trở thành mục từ tiếng Kusaal đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 17 tháng 9 năm 2026 ===
* {{l|nhu|wú}} trở thành mục từ tiếng Noone đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 9 tháng 9 năm 2026 ===
* {{l|inc-ogu|कमल}} trở thành mục từ tiếng Gujarat cổ đầu tiên của Wiktionary tiếng Việt.
* {{l|zpc|Z̃}} trở thành mục từ tiếng Zapotec Choapan đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 8 tháng 9 năm 2026 ===
* {{l|ine-ana-pro|*ʔésti}} trở thành mục từ tiếng Tiểu Á nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|tuw-pro|*ŋōlimi}} trở thành mục từ tiếng Tungus nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 6 tháng 9 năm 2026 ===
* {{l|afa-pro|*waraḳ-}} trở thành mục từ tiếng Phi-Á nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 3 tháng 9 năm 2026 ===
* {{l|cau-drg-pro|*xin}} trở thành mục từ tiếng Dargwa nguyên thủy đầu tiên của Wiktionary tiếng Việt.
== Tháng 8 năm 2026 ==
=== Thứ hai, ngày 31 tháng 8 năm 2026 ===
* {{l|aoa|awa}} trở thành mục từ tiếng Angola đầu tiên của Wiktionary tiếng Việt.
* {{l|chm-pro|*ik}} trở thành mục từ tiếng Mari nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|urj-mdv-pro|*tumə}} trở thành mục từ tiếng Mordvin nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 30 tháng 8 năm 2026 ===
* {{l|ghc|adhaigh}} trở thành mục từ tiếng Gael cổ điển đầu tiên của Wiktionary tiếng Việt.
=== Thứ bảy, ngày 29 tháng 8 năm 2026 ===
* [[kani]] đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Culli và Maia.
* {{l|ngf-pro|*imbi}} trở thành mục từ tiếng Liên New Guinea nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|agm|kaatɨ-́há}} trở thành mục từ tiếng Angaataha đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 26 tháng 8 năm 2026 ===
* {{l|vls|bieë}} trở thành mục từ tiếng Flemish Tây đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 24 tháng 8 năm 2026 ===
* {{l|sdc|rui}} trở thành mục từ tiếng Sassari đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 23 tháng 8 năm 2026 ===
* {{l|mis-xbi|啊干|tr=*aqa(n)}} trở thành mục từ tiếng Tiên Ti đầu tiên của Wiktionary tiếng Việt.
=== Chủ nhật, ngày 2 tháng 8 năm 2026 ===
* {{l|iro-nor-pro|*-nõhs-}} trở thành mục từ tiếng Bắc Iroquois nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ hai, ngày 3 tháng 8 năm 2026 ===
* {{l|sem-wes-pro|*baḥr-}} trở thành mục từ tiếng Semit Tây nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|qfa-cka-pro|*'iməl}} trở thành mục từ tiếng Chukotka-Kamchatka nguyên thủy đầu tiên của Wiktionary tiếng Việt.
* {{l|aql-pro|*le·kʔawe}} trở thành mục từ tiếng Algic nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ ba, ngày 4 tháng 8 năm 2026 ===
* {{l|owl|carrecc}} trở thành mục từ tiếng Wales cổ đầu tiên của Wiktionary tiếng Việt.
=== Thứ tư, ngày 5 tháng 8 năm 2026 ===
* {{l|grk-pro|*pʰernā́}} trở thành mục từ tiếng Hellen nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 6 tháng 8 năm 2026 ===
* {{l|tfn|esbay}} trở thành mục từ tiếng Dena'ina đầu tiên của Wiktionary tiếng Việt.
* {{l|gmq-mno|dammr}} trở thành mục từ tiếng Na Uy trung đại đầu tiên của Wiktionary tiếng Việt.
* {{l|tbq-lob-pro|*b-ləy²}} trở thành mục từ tiếng Lô Lô-Miến nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ sáu, ngày 7 tháng 8 năm 2026 ===
* {{l|smw|asu}} đồng thời trở thành mục từ đầu tiên của các ngôn ngữ: Sumbawa và Alune.
=== Thứ ba, ngày 11 tháng 8 năm 2026 ===
* {{l|cau-nec-pro|*u̯aran}} trở thành mục từ tiếng Đông Bắc Kavkaz nguyên thủy đầu tiên của Wiktionary tiếng Việt.
=== Thứ năm, ngày 13 tháng 8 năm 2026 ===
* {{l|mge|Ɔ̰}} trở thành mục từ tiếng Mango đầu tiên của Wiktionary tiếng Việt.
== Xem thêm ==
*[[Thành viên:WikimediaNotifier/notifications|Thời sự Wikimedia]]
*[[m:Tin tức về Wikimedia|Tin tức Wikimedia]]
[[Thể loại:Tin tức Wiktionary| ]]
[[Thể loại:Cộng đồng Wiktionary|{{PAGENAME}}]]
t2n2k2zerodqczh84oln2sy39l26jvc
acquiescent
0
6036
2573155
2367960
2026-10-24T07:54:27Z
Hiyuune
50834
2573155
wikitext
text/x-wiki
=={{langname|en}}==
==={{section|etym}}===
{{root|en|ine-pro|*kʷyeh₁-}}
Từ {{der|en|la|acquiescens|pos=phân từ hiện tại của {{m|la|acquiēscō}}}}.
==={{section|pron}}===
* {{IPA|en|/æˈkwi.ɛsn̩t/|a=UK}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-acquiescent.wav|a=Southern England}}
* {{rhymes|en|ɛsənt|s=4}}
==={{section|adj}}===
{{en-adj}}
# [[bằng lòng|Bằng lòng]], [[ưng thuận]], [[đồng ý]]; [[bằng lòng]] [[ngầm]], [[mặc]] [[nhận]].
# [[phục tùng|Phục tùng]].
===={{section|drv}}====
{{col|en|inacquiescent|nonacquiescent|unacquiescent|acquiescently}}
===={{section|rel}}====
{{rootsee|en|ine|kʷyeh₁}}
==={{section|see}}===
* {{l|en|quiescent}}
==={{section|ref}}===
* {{R:FVDP|db=ev}}
* {{R:Webster 1913}}
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=acquiēscent}}
# {{inflection of|la|acquiēscō||indc|futr|actv|ở|3|p}}
=={{langname|fr}}==
==={{section|pron}}===
* {{fr-IPA|pos=v}}
* {{audio|fr|LL-Q150 (fra)-DenisdeShawi-acquiescent.wav|a=Shawinigan}}
==={{section|v}}===
{{head|fr|Biến thể hình thái động từ}}
# {{inflection of|fr|acquiescer||ind//sub|pres|ở|3|p}}
egf9ojnerrzn47az6sv5lojhgqaahjt
incontrôlable
0
9740
2573181
2481823
2026-10-24T08:55:57Z
Hiyuune
50834
2573181
wikitext
text/x-wiki
{{also|incontrolable}}
=={{langname|fr}}==
==={{section|etym}}===
{{ety|fr|:af|in-|contrôlable}}
Từ {{af|fr|in-|contrôlable}}.
==={{section|pron}}===
* {{fr-IPA}}
* {{audio|fr|LL-Q150 (fra)-DSwissK-incontrôlable.wav|a=Valais}}
==={{section|adj}}===
{{fr-adj}}
# [[không thể|Không thể]] [[kiểm tra]] lại, [[không thể]] [[kiểm chứng]].
===={{section|rel}}====
* {{l|fr|contrôler}}
==={{section|ref}}===
* {{R:FVDP|db=fv}}
==={{section|further}}===
* {{R:fr:TLFi}}
lkuc31mkf1htwo733gfdhgigw1kxym1
lam
0
19203
2573127
2416615
2026-10-24T04:43:21Z
WhoAlone
40420
2573127
wikitext
text/x-wiki
{{-vie-}}
{{-pron-}}
{{vi-pron}}
{{-hanviet-}}
{{đầu}}
*[[籃]]: [[lam]]
*[[滥]]: [[lam]], [[lãm]], [[lạm]], [[cãm]], [[hạm]]
*[[襤]]: [[lam]], [[lâm]]
*[[嵐]]: [[lam]]
*[[㞩]]: [[lam]]
*[[壈]]: [[lam]], [[lẫm]]
*[[濫]]: [[lam]], [[lãm]], [[lạm]], [[cãm]], [[hạm]]
*[[婪]]: [[lam]]
*[[藍]]: [[lam]], [[tẫn]]
*[[㲯]]: [[lam]]
*[[篮]]: [[lam]]
{{mid}}
*[[厱]]: [[lam]]
*[[䰐]]: [[lam]]
*[[𨬒]]: [[lam]]
*[[㘕]]: [[lam]], [[hám]]
*[[惏]]: [[lam]], [[lâm]], [[lẫm]]
*[[蓘]]: [[lam]], [[cổn]]
*[[礛]]: [[lam]]
*[[岚]]: [[lam]]
*[[蓝]]: [[lam]]
*[[褴]]: [[lam]]
{{cuối}}
{{-hanviet-t-}}
{{đầu}}
*[[嵐]]: [[lam]]
*[[籃]]: [[lam]]
*[[婪]]: [[lam]]
{{mid}}
*[[藍]]: [[lam]]
*[[襤]]: [[lam]]
{{cuối}}
{{-nôm-}}
{{đầu}}
*[[籃]]: [[làn]], [[lam]], [[xớm]], [[xờm]]
*[[婪]]: [[lam]]
*[[藍]]: [[trôm]], [[rườm]], [[lam]], [[lom]], [[xám]], [[lồm]], [[rôm]], [[chàm]]
*[[𥜓]]: [[lam]]
*[[惏]]: [[lầm]], [[lam]], [[lẫm]], [[lăm]]
*[[篮]]: [[làn]], [[lam]]
*[[嵐]]: [[lam]]
{{mid}}
*[[琳]]: [[lâm]], [[lam]]
*[[褴]]: [[lam]]
*[[糮]]: [[lam]]
*[[礛]]: [[lam]]
*[[岚]]: [[lam]]
*[[蓝]]: [[trôm]], [[lam]]
*[[]]: [[lam]]
{{cuối}}
{{-paro-}}
{{đầu}}
:* [[lâm]]
:* [[lăm]]
:* [[làm]]
:* [[lẩm]]
:* [[lấm]]
{{giữa}}
:* [[lắm]]
:* [[lạm]]
:* [[lầm]]
:* [[lẫm]]
{{cuối}}
{{-noun-}}
'''lam'''
# [[màu|Màu]] [[xanh da trời]] [[thẫm]].
#: ''Áo '''lam'''.''
{{-adj-}}
'''lam'''
# [[nói|Nói]] thứ [[xôi]] [[thổi]] bằng ống [[tre]] hay [[sọ dừa]] [[lùi]] vào [[lửa]].
#: ''Cơm '''lam'''.''
{{-verb-}}
'''lam'''
# {{like-entry|làm}}
#: ''Nhà có một bà hay '''lam''' hay làm ([[w:Nguyễn Khuyến|Nguyễn Khuyến]])''
{{-ref-}}
{{R:FVDP}}
{{R:WinVNKey:Lê Sơn Thanh}}
{{sơ khai}}
[[Thể loại:Danh từ tiếng Việt]]
[[Thể loại:Tính từ tiếng Việt]]
[[Thể loại:Động từ tiếng Anh]]
[[Thể loại:Động từ tiếng Việt]]
{{-eng-}}
{{-pron-}}
* [[Wiktionary:IPA|IPA]]: {{IPA-old|/ˈlæm/}}
{{-verb-}}
'''lam''' {{IPA-old|/ˈlæm/}}
# {{term|Từ lóng}} [[đánh|Đánh]], [[quật]], [[vụt]] (bằng gậy).
#: ''to '''lam''' [into] somebody'' — quật ai, đánh ai
{{-forms-}}
{{eng-verb|base=lam|lam|m|ed}}
{{-intr-verb-}}
'''lam''' ''nội động từ'' {{IPA-old|/ˈlæm/}}
# {{term|từ Mỹ, nghĩa Mỹ}} , (từ lóng) [[trốn tránh]], [[chạy trốn]], [[lẩn trốn]].
{{-ref-}}
{{R:FVDP}}
{{-tyz-}}
{{-pron-}}
{{tyz-IPA}}
{{-noun-}}
{{pn}}
# [[tre]] [[làm]] [[đòn]] [[khiêng]] [[quan tài]].
{{-ref-}}
{{R:Lương Bèn}}
[[Thể loại:Danh từ tiếng Tày]]
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao cạo]].
#:{{ux|sed|tê ăm á môi to '''lam''' kúa xâk mŭm|Bán cho tôi một '''lưỡi dao cạo'''}}
==={{section|ref}}===
* {{R:VOV}}
jp9y7lo0egn5pjrv881o2jtsa6esryy
xế
0
30195
2573111
2419356
2026-10-24T04:32:48Z
WhoAlone
40420
2573111
wikitext
text/x-wiki
{{-vie-}}
{{-pron-}}
{{vi-pron}}
{{-hanviet-}}
{{đầu}}
*[[胔]]: [[tỳ]], [[tý]], [[tì]], [[tí]], [[xế]]
*[[掣]]: [[xiết]], [[xế]], [[sế]]
*[[眥]]: [[tý]], [[tí]], [[trại]], [[xế]], [[xải]]
{{mid}}
*[[淛]]: [[xế]], [[chiết]], [[đắng]]
*[[砌]]: [[xế]], [[thế]], [[thiết]]
{{cuối}}
{{-hanviet-t-}}
{{đầu}}
*[[掣]]: [[xiết]], [[xế]]
{{cuối}}
{{-nôm-}}
{{đầu}}
*[[萆]]: [[tỳ]], [[xế]], [[tích]]
*[[掣]]: [[sế]], [[siết]], [[xía]], [[xế]], [[xiết]]
*[[車]]: [[xe]], [[sa]], [[se]], [[xơ]], [[xa]], [[xê]], [[xè]], [[xế]]
*[[眥]]: [[tý]], [[xế]], [[tí]]
*[[蓖]]: [[bề]], [[xế]]
*[[眦]]: [[xế]]
*[[篦]]: [[bề]], [[bí]], [[xế]]
{{mid}}
*[[]]: [[xế]]
*[[潷]]: [[vụt]], [[xế]], [[vút]], [[vuốt]], [[vọt]]
*[[制]]: [[chơi]], [[choi]], [[xế]], [[chế]], [[xiết]], [[chóe]], [[chới]]
*[[尺]]: [[xệch]], [[xạch]], [[xếch]], [[xịch]], [[xế]], [[sệch]], [[xách]], [[xích]]
*[[㫼]]: [[xế]]
*[[熾]]: [[sí]], [[xi]], [[xé]], [[xí]], [[xế]]
{{cuối}}
{{-paro-}}
:* [[xé]]
:* [[xẻ]]
:* [[Xe]]
{{-verb-}}
'''xế'''
# [[nghiêng|Nghiêng]] về một [[bên]].
#: ''Bóng dâu đã '''xế''' ngang đầu (<u>[[w:Truyện Kiều|Truyện Kiều]]</u>)''
#: ''Vầng trăng bóng '''xế''', khuyết chưa tròn ([[w:Hồ Xuân Hương|Hồ Xuân Hương]])''
{{-ref-}}
{{R:FVDP}}
{{R:WinVNKey:Lê Sơn Thanh}}
[[Thể loại:Động từ tiếng Việt]]
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi câu]].
==={{section|ref}}===
* {{R:VOV}}
bmvd472eyhld5tze5sgm2mbnxc83tcl
съёжиться
0
78926
2573178
2557901
2026-10-24T08:34:00Z
Hiyuune
50834
2573178
wikitext
text/x-wiki
{{also|съежиться}}
=={{langname|ru}}==
==={{section|etym}}===
{{af|ru|с-|ёжиться}}, {{suffix|ru|съёжить|ся}}.
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|съёжиться|pf|impf=ёжиться,съёживаться}}
# [[nhăn]] lại, [[dăn]] lại, [[dăn dúm]], [[quắt]] lại.
# [[co ro]], [[thu lu]], [[co lại]], [[co dúm]] lại, [[co rúm]] lại.
# [[nhăn nheo]], [[dăn deo]].
===={{section|forms}}====
{{ru-conj|pf|4a|съёжиться}}
===={{section|rel}}====
* {{l|ru|ёж}}, {{l|ru|ёжик}}, {{l|ru|ежо́вый}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
p6di6gf8r8kbao6vz1s8gaumuf1pgmx
ёрзать
0
86809
2573159
2558885
2026-10-24T08:03:23Z
Hiyuune
50834
2573159
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|etym}}===
{{inh+|ru|sla-pro|*jьrzati}}, từ {{der|ru|ine-pro|*h₁erǵʰ-}}. Cùng gốc với {{cog|lt|er̃žilas}}, {{m|lt|ar̃žilas}}, {{m|lt|aržùs}}, {{cog|non|argr}}, {{cog|de|arg}}, {{cog|en|eerie}}.
==={{section|pron}}===
* {{ru-IPA}}
* {{audio|ru|LL-Q7737 (rus)-DomesticFrog-ёрзать.wav}}
==={{section|v}}===
{{ru-verb|ёрзать|impf|pf=заёрзать,поёрзать,ёрзнуть}}
# [[ngồi không|Ngồi không]] [[yên]], [[cựa quậy]], [[cựa]] [[cạy]].
#: {{syn|ru|ело́зить}}
===={{section|forms}}====
{{ru-conj|impf-intr|1a|ёрзать}}
===={{section|drv}}====
{{ru-derived verbs
|ёрзнуть/-
|-
|*ёрзать/-
|за
|изъ
|объ
|по
|изъёрзаться/-
}}
* {{l|ru|ёрзание}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
clzpnkkcpwv750538h42lvl3x3hqvcf
ёкать
0
87497
2573170
2558883
2026-10-24T08:19:24Z
Hiyuune
50834
2573170
wikitext
text/x-wiki
{{also|екать}}
=={{langname|ru}}==
==={{section|etym}}===
{{onom|ru}} (xem thêm {{af|ru|-кать}}).
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|ёкать|impf|pf=ёкнуть}}
# {{lb|ru|colloquial}} Phát ra một [[âm thanh]] ngắn, ngắt quãng như tiếng [[nấc]].
===={{section|forms}}====
{{ru-conj|impf-intr|1a|ёкать}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
==={{section|further}}===
* {{R:ru:Dal}}
7258r8a95qkwsbqwxxsdxkerfceoj1u
ёкнуть
0
91434
2573169
2558884
2026-10-24T08:17:46Z
Hiyuune
50834
2573169
wikitext
text/x-wiki
{{also|екнуть}}
=={{langname|ru}}==
==={{section|etym}}===
{{af|ru|ёкать|-нуть}}
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|ёкнуть|pf|impf=ёкать}}
# {{lb|ru|colloquial}} Phát ra một [[âm thanh]] ngắn, ngắt quãng như tiếng [[nấc]].
===={{section|forms}}====
{{ru-conj|pf-intr|3a|ёкнуть}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
s3tteg4bqnoefn8huljfzael6bj8u30
acquiescently
0
155835
2573156
2450089
2026-10-24T07:57:18Z
Hiyuune
50834
2573156
wikitext
text/x-wiki
=={{langname|en}}==
==={{section|etym}}===
{{ety|en|:af|acquiescent|-ly<id:phó từ>|text=+|tree=1}}
==={{section|adv}}===
{{en-adv}}
# Một cách [[phục tùng]], [[cam chịu]], [[ưng thuận]].
==={{section|ref}}===
* {{R:FVDP|db=ev}}
* {{R:Webster 1913}}
j6c2wl9iuynvq03s10dxdakxogu270d
extrapolative
0
175584
2573110
1837795
2026-10-24T04:32:47Z
Hiyuune
50834
2573110
wikitext
text/x-wiki
=={{langname|en}}==
==={{section|etym}}===
Từ {{suffix|en|extrapolate|ive}}.
==={{section|adj}}===
{{en-adj}}
# [[ngoại suy]].
#: {{syn|en|extrapolatory}}
==={{section|ref}}===
* {{R:FVDP|db=ev}}
==={{section|further}}===
* {{R:GNV|extrapolatory, extrapolative}}
ituva4rxdy5zfw4lhluv3sg3btu1qi0
kim cúc
0
193508
2573158
2057642
2026-10-24T08:01:03Z
Hiyuune
50834
2573158
wikitext
text/x-wiki
=={{langname|vi}}==
==={{section|pron}}===
{{vi-pron}}
==={{section|n}}===
{{vi-noun}}
# [[loài|Loài]] [[cúc hoa]] nhỏ và [[vàng]].
==={{section|ref}}===
* {{R:FVDP}}
0xk7zl8imc7abgvtyi5xa6ijv88jwya
ёжиться
0
203095
2573175
2558882
2026-10-24T08:32:06Z
Hiyuune
50834
2573175
wikitext
text/x-wiki
{{also|ежиться}}
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|ёжиться|impf|pf=съёжиться}}
# [[co ro|Co ro]], [[co]] [[người]] lại, [[thu hình]] lại, [[co quắp]] [[mình]] lại.
===={{section|forms}}====
{{ru-conj|impf|4a|ёжиться}}
===={{section|drv}}====
* {{ru-derived verbs
|*ёжиться/ёживаться
|-/вы-
|за-/-
|по
|съ
|довыёживаться/-
}}
** {{col|ru
|выёживание
|поёживание
|съёживание
}}
** {{col|ru
|съёженный
}}
===={{section|rel}}====
* {{l|ru|ёж|g=m}}, {{l|ru|ёжик|g=m}}, {{l|ru|ежо́вый}}
* {{l|ru|ёжить|g=impf}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
* {{R:ru:Vasmer|ежиться}}
07z3vz8obsz4akbhdwlmxxjrssve7pv
2573176
2573175
2026-10-24T08:32:17Z
Hiyuune
50834
2573176
wikitext
text/x-wiki
{{also|ежиться}}
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|ёжиться|impf|pf=съёжиться}}
# [[co ro|Co ro]], [[co]] [[người]] lại, [[thu hình]] lại, [[co quắp]] [[mình]] lại.
===={{section|forms}}====
{{ru-conj|impf|4a|ёжиться}}
===={{section|drv}}====
{{ru-derived verbs
|*ёжиться/ёживаться
|-/вы-
|за-/-
|по
|съ
|довыёживаться/-
}}
** {{col|ru
|выёживание
|поёживание
|съёживание
}}
** {{col|ru
|съёженный
}}
===={{section|rel}}====
* {{l|ru|ёж|g=m}}, {{l|ru|ёжик|g=m}}, {{l|ru|ежо́вый}}
* {{l|ru|ёжить|g=impf}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
* {{R:ru:Vasmer|ежиться}}
6pez5ze081i12r57nkxjfjn4wqzzeyi
2573177
2573176
2026-10-24T08:32:29Z
Hiyuune
50834
2573177
wikitext
text/x-wiki
{{also|ежиться}}
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|ёжиться|impf|pf=съёжиться}}
# [[co ro|Co ro]], [[co]] [[người]] lại, [[thu hình]] lại, [[co quắp]] [[mình]] lại.
===={{section|forms}}====
{{ru-conj|impf|4a|ёжиться}}
===={{section|drv}}====
{{ru-derived verbs
|*ёжиться/ёживаться
|-/вы-
|за-/-
|по
|съ
|довыёживаться/-
}}
{{col|ru
|выёживание
|поёживание
|съёживание
}}
{{col|ru
|съёженный
}}
===={{section|rel}}====
* {{l|ru|ёж|g=m}}, {{l|ru|ёжик|g=m}}, {{l|ru|ежо́вый}}
* {{l|ru|ёжить|g=impf}}
==={{section|ref}}===
* {{R:FVDP|db=rv}}
* {{R:ru:Vasmer|ежиться}}
m16ott4w9g1fv1uli4kmbuejswbfg2e
мозжечок
0
203791
2573010
2446566
2026-10-23T14:53:11Z
Kelly zhrm
58416
2573010
wikitext
text/x-wiki
=={{langname|ru}}==
{{wp|ru:}}
==={{ĐM|etym}}===
Từ {{af|ru|мозг|-ек|-о́к}}; {{calque|ru|la|cerebellum|nocap=1}}.
==={{ĐM|pron}}===
* {{ru-IPA|мозжечо́к}}
* {{audio|ru|Ru-мозжечок.ogg}}
* {{ru-IPA|мозъжечо́к}} {{q|trong cách nói cẩn trọng}}
==={{ĐM|n}}===
{{ru-noun+|b|мозжечо́к|*|adj=мозжечко́вый}}
# {{lb|ru|anatomy}} [[tiểu não|Tiểu não]].
===={{ĐM|decl}}====
{{ru-noun-table|b|мозжечо́к|*}}
==={{ĐM|see}}===
* {{l|ru|головно́й мозг}}
* {{l|ru|коне́чный мозг}}
* {{l|ru|мозг}}
* {{l|ru|мозгово́й ствол}}
* {{l|ru|спинно́й мозг}}
==={{ĐM|ref}}===
{{R:FVDP|db=rv}}
nno5lv7qfcimntha3gfh9csn3ayahcg
Mô đun:languages/data/3/a
828
270567
2573003
2571176
2026-10-23T13:38:43Z
Lcsnes
40261
2573003
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["aaa"] = {
"tiếng Ghotuo",
35463,
"alv-yek",
"Latn",
"Tiếng Ghotuo",
"Ghotuo",
}
m["aab"] = {
"tiếng Alumu-Tesu",
35034,
"nic-alu",
"Latn",
"Tiếng Alumu-Tesu",
"Alumu-Tesu",
}
m["aac"] = {
"tiếng Ari",
1811224,
"paa-pag",
"Latn",
"Tiếng Ari",
"Ari",
}
m["aad"] = {
"tiếng Amal",
56708,
"paa-iwm",
"Latn",
"Tiếng Amal",
"Amal",
}
-- "aae" IS TREATED AS "sq", SEE WT:LT
m["aaf"] = {
"tiếng Aranadan",
3507928,
"dra-mal",
"Mlym",
"Tiếng Aranadan",
"Aranadan",
translit = {Mlym = "ml-translit"},
}
m["aag"] = {
"tiếng Ambrak",
4741706,
"qfa-tor",
"Latn",
"Tiếng Ambrak",
"Ambrak",
}
m["aah"] = {
"Abu' Arapesh",
4670715,
"qfa-tor",
"Latn",
}
m["aai"] = {
"Arifama-Miniafia",
4790560,
"poz-ocw",
"Latn",
}
m["aak"] = {
"tiếng Ankave",
3446690,
"ngf",
"Latn",
"Tiếng Ankave",
"Ankave",
}
m["aal"] = {
"tiếng Afade",
56434,
"cdc-cbm",
"Latn",
"Tiếng Afade",
"Afade",
}
m["aan"] = {
"Anambé",
3507873,
"tup-gua",
"Latn",
}
m["aap"] = {
"Pará Arára",
56807,
"sai-pek",
"Latn",
}
m["aaq"] = {
"tiếng Đông Abenaki",
3515185,
"alg-abp",
"Latn",
"Tiếng Đông Abenaki",
"Đông Abenaki",
}
m["aas"] = {
"tiếng Aasax",
56620,
"cus-sou",
"Latn",
"Tiếng Aasax",
"Aasax",
}
-- "aat" IS TREATED AS "sq", SEE WT:LT
m["aau"] = {
"tiếng Abau",
3073568,
"paa-spk",
"Latn",
"Tiếng Abau",
"Abau",
}
m["aaw"] = {
"tiếng Solong",
7558834,
"poz-ocw",
"Latn",
"Tiếng Solong",
"Solong",
}
m["aax"] = {
"Mandobo Atas",
12636156,
"ngf",
"Latn",
}
m["aaz"] = {
"tiếng Amarasi",
4740192,
"poz-tim",
"Latn",
"Tiếng Amarasi",
"Amarasi",
}
m["aba"] = {
"Abé",
34833,
"alv-lag",
"Latn",
}
m["abb"] = {
"tiếng Bankon",
34860,
"bnt-bsa",
"Latn",
"Tiếng Bankon",
"Bankon",
}
m["abc"] = {
"Ambala Ayta",
3448896,
"phi",
"Latn",
}
m["abd"] = {
"Camarines Norte Agta",
3399682,
"phi",
"Latn",
}
m["abe"] = {
"tiếng Tây Abenaki",
17502788,
"alg-abp",
"Latn",
"Tiếng Tây Abenaki",
"Tây Abenaki",
}
m["abf"] = {
"Abai Sungai",
4663287,
"poz-san",
"Latn",
}
m["abg"] = {
"tiếng Abaga",
3507954,
"paa-kag",
"Latn",
"Tiếng Abaga",
"Abaga",
}
m["abh"] = {
"tiếng Ả Rập Tajikistan",
56833,
"sem-arb",
"Arab",
"Tiếng Ả Rập Tajikistan",
"Ả Rập Tajikistan",
entry_name = "ar-entryname",
}
m["abi"] = {
"tiếng Abidji",
34781,
"alv-lag",
"Latn",
"Tiếng Abidji",
"Abidji",
}
m["abj"] = {
"Aka-Bea",
2356391,
"qfa-ads",
"Latn",
}
m["abl"] = {
"Abung",
49215,
"poz-lgx",
"Latn",
}
m["abm"] = {
"tiếng Abanyom",
7502,
"nic-eko",
"Latn",
"Tiếng Abanyom",
"Abanyom",
}
m["abn"] = {
"Abua",
34835,
"nic-cde",
"Latn",
}
m["abo"] = {
"tiếng Abon",
35121,
"nic-tvn",
"Latn",
"Tiếng Abon",
"Abon",
}
m["abp"] = {
"Abenlen Ayta",
3436621,
"phi",
"Latn",
}
m["abq"] = {
"tiếng Abaza",
27567,
"cau-abz",
"Cyrl, Latn",
"Tiếng Abaza",
"Abaza",
translit = {Cyrl = "abq-translit"},
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {
Cyrl = s["cau-Cyrl-entryname"],
Latn = s["cau-Latn-entryname"],
},
sort_key = {
Cyrl = {
from = {
"гъв", "гъь", "гӏв", "джв", "джь", "къв", "къь", "кӏв", "кӏь", "хъв", "хӏв", "чӏв", -- 3 chars
"гв", "гъ", "гь", "гӏ", "дж", "дз", "ё", "жв", "жь", "кв", "къ", "кь", "кӏ", "ль", "лӏ", "пӏ", "тл", "тш", "тӏ", "фӏ", "хв", "хъ", "хь", "хӏ", "цӏ", "чв", "чӏ", "шв", "шӏ" -- 2 chars
},
to = {
"г" .. p[3], "г" .. p[4], "г" .. p[7], "д" .. p[2], "д" .. p[3], "к" .. p[3], "к" .. p[4], "к" .. p[7], "к" .. p[8], "х" .. p[3], "х" .. p[6], "ч" .. p[3],
"г" .. p[1], "г" .. p[2], "г" .. p[5], "г" .. p[6], "д" .. p[1], "д" .. p[4], "е" .. p[1], "ж" .. p[1], "ж" .. p[2], "к" .. p[1], "к" .. p[2], "к" .. p[5], "к" .. p[6], "л" .. p[1], "л" .. p[2], "п" .. p[1], "т" .. p[1], "т" .. p[2], "т" .. p[3], "ф" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[4], "х" .. p[5], "ц" .. p[1], "ч" .. p[1], "ч" .. p[2], "ш" .. p[1], "ш" .. p[2]
}
},
},
}
m["abr"] = {
"tiếng Abron",
34831,
"alv-ctn",
"Latn",
"Tiếng Abron",
"Abron",
ancestors = "ak",
}
m["abs"] = {
"tiếng Mã Lai Ambon",
3124354,
"crp",
"Latn",
"Tiếng Mã Lai Ambon",
"Mã Lai Ambon",
ancestors = "ms",
}
m["abt"] = {
"tiếng Ambulas",
3508015,
"paa-spk",
"Latn",
"Tiếng Ambulas",
"Ambulas",
}
m["abu"] = {
"tiếng Abure",
34767,
"alv-ptn",
"Latn",
"Tiếng Abure",
"Abure",
}
m["abv"] = {
"Baharna Arabic",
56576,
"sem-arb",
"Arab",
entry_name = "ar-entryname",
}
m["abw"] = {
"Pal",
7126121,
"ngf-mad",
"Latn",
}
m["abx"] = {
"Inabaknon",
2820163,
"poz-sbj",
"Latn",
}
m["aby"] = {
"Aneme Wake",
3508107,
"ngf",
"Latn",
}
m["abz"] = {
"tiếng Abui",
2822110,
"qfa-tap",
"Latn",
"Tiếng Abui",
"Abui",
}
m["aca"] = {
"tiếng Achawa",
2822982,
"awd",
"Latn",
"Tiếng Achawa",
"Achawa",
}
m["acb"] = {
"Áncá",
11130787,
"nic-mom",
"Latn",
}
m["acd"] = {
"Gikyode",
35256,
"alv-gng",
"Latn",
}
m["ace"] = {
"tiếng Aceh",
27683,
"cmc",
"Latn, ms-Arab",
"Tiếng Aceh",
"Aceh",
standardChars = {
Latn = "AaBbCcDdEeÉéÈèËëFfGgHhIiJjKkLlMmNnOoÔôÖöPpQqRrSsTtUuVvWwXxYyZz", -- current orthography (not yet add Arab)
c.punc
},
}
m["ach"] = {
"tiếng Acholi",
34926,
"sdv-los",
"Latn",
"Tiếng Acholi",
"Acholi",
}
m["aci"] = {
"Aka-Cari",
2670418,
"qfa-adn",
"Latn",
}
m["ack"] = {
"Aka-Kora",
3433680,
"qfa-adn",
"Latn",
}
m["acl"] = {
"Akar-Bale",
3436825,
"qfa-ads",
"Latn",
}
m["acm"] = {
"tiếng Ả Rập Iraq",
56232,
"sem-arb",
"Arab",
"Tiếng Ả Rập Iraq",
"Ả Rập Iraq",
entry_name = "ar-entryname",
}
m["acn"] = {
"tiếng A Xương",
56582,
"tbq-brm",
"Latn",
"Tiếng A Xương",
"A Xương",
}
m["acp"] = {
"tiếng Đông Acipa",
5329945,
"nic-kmk",
"Latn",
"Tiếng Đông Acipa",
"Đông Acipa",
}
m["acr"] = {
"tiếng Achi",
34774,
"myn",
"Latn",
"Tiếng Achi",
"Achi",
}
m["acs"] = {
"Acroá",
2829146,
"sai-cje",
"Latn",
}
m["acu"] = {
"tiếng Achuar",
2823170,
"sai-jiv",
"Latn",
"Tiếng Achuar",
"Achuar",
}
m["acv"] = {
"tiếng Achumawi",
56661,
"nai-pal",
"Latn",
"Tiếng Achumawi",
"Achumawi",
}
m["acw"] = {
"tiếng Ả Rập Hijazi",
56608,
"sem-arb",
"Arab",
"Tiếng Ả Rập Hijazi",
"Ả Rập Hijazi",
entry_name = "ar-entryname",
}
m["acx"] = {
"tiếng Ả Rập Oman",
56630,
"sem-arb",
"Arab",
"Tiếng Ả Rập Oman",
"Ả Rập Oman",
entry_name = "ar-entryname",
}
m["acy"] = {
"tiếng Ả Rập Síp",
56416,
"sem-arb",
"Latn, Grek",
"Tiếng Ả Rập Síp",
"Ả Rập Síp",
ancestors = "acm",
standardChars = {
Latn = "AaBbCcDdΔδEeFfGgĠġĊċIiJjKkLlMmNnOoPpΘθRrSsTtUuVvWwXxYyZzŞş",
c.punc
},
entry_name = {remove_diacritics = c.grave .. c.acute .. c.breve},
}
m["acz"] = {
"tiếng Acheron",
34769,
"alv-tal",
"Latn",
"Tiếng Acheron",
"Acheron",
}
m["ada"] = {
"tiếng Adangme",
35141,
"alv-gda",
"Latn",
"Tiếng Adangme",
"Adangme",
}
m["adb"] = { -- rename or remove, see RFM
"Adabe",
36872,
nil,
"Latn",
}
m["add"] = {
"Dzodinka",
35266,
"nic-nka",
"Latn",
}
m["ade"] = {
"Adele",
27740,
"alv-ntg",
"Latn",
}
m["adf"] = {
"Dhofari Arabic",
56565,
"sem-arb",
"Arab",
entry_name = "ar-entryname",
}
m["adg"] = {
"Andegerebinha",
3508123,
"aus-pam",
"Latn",
}
m["adh"] = {
"Adhola",
1971400,
"sdv-los",
"Latn",
}
m["adi"] = {
"tiếng Adi",
56440,
"sit-tan",
"Latn",
"Tiếng Adi",
"Adi",
}
m["adj"] = {
"tiếng Adjukru",
34738,
"alv-lag",
"Latn",
}
m["adl"] = {
"tiếng Galo",
2857892,
"sit-tan",
"Latn",
"Tiếng Galo",
"Galo",
}
m["adn"] = {
"Adang",
3398276,
"qfa-tap",
"Latn",
}
m["ado"] = {
"Abu",
56659,
"paa-ram",
"Latn",
}
m["adp"] = {
"Adap",
3512402,
"sit-tib",
"Tibt",
ancestors = "dz",
translit = "Tibt-translit",
override_translit = true,
display_text = s["Tibt-displaytext"],
entry_name = s["Tibt-entryname"],
sort_key = "Tibt-sortkey",
wikipedia_article = "Dzongkha", -- Considered a dialect of Dzongkha
}
m["adq"] = {
"Adangbe",
34730,
"alv-gda",
"Latn",
ancestors = "ada",
}
m["adr"] = {
"Adonara",
4684505,
"poz-cet",
"Latn",
}
m["ads"] = {
"Adamorobe Sign Language",
27709,
"sgn",
"Latn", -- when documented
}
m["adt"] = {
"tiếng Adnyamathanha",
2225391,
"aus-psw",
"Latn",
"Tiếng Adnyamathanha",
"Adnyamathanha",
}
m["adu"] = {
"Aduge",
34734,
"alv-nwd",
"Latn",
ancestors = "opa",
wikipedia_article = "Okpamheri language",
}
m["adw"] = {
"Amondawa",
12626847,
"tup-gua",
"Latn",
}
m["ady"] = {
"tiếng Adygea",
27776,
"cau-cir",
"Cyrl, Latn, Arab",
"Tiếng Adygea",
"Adygea",
translit = {
Cyrl = "cau-cir-translit",
Arab = "ar-translit",
},
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {
Cyrl = s["cau-Cyrl-entryname"],
Latn = s["cau-Latn-entryname"],
},
sort_key = {
Cyrl = {
from = {
"кхъу", "къӏу", -- 4 chars
"гъу", "джу", "дзу", "жъу", "къу", "кхъ", "къӏ", "кӏу", "кӏь", "лъу", "лӏу", "пӏу", "сӏу", "тӏу", "фӏу", "хъу", "цӏу", "чъу", "чӏу", "шъу", "шӏу", "щӏу", -- 3 chars
"гу", "гъ", "гь", "дж", "дз", "ё", "жъ", "жь", "ку", "къ", "кь", "кӏ", "лъ", "ль", "лӏ", "пӏ", "сӏ", "тӏ", "фӏ", "ху", "хъ", "хь", "цу", "цӏ", "чу", "чъ", "чӏ", "шъ", "шӏ", "щӏ", "ӏу", "ӏь" -- 2 chars
},
to = {
"к" .. p[5], "к" .. p[7],
"г" .. p[3], "д" .. p[2], "д" .. p[4], "ж" .. p[2], "к" .. p[3], "к" .. p[4], "к" .. p[6], "к" .. p[10], "к" .. p[11], "л" .. p[2], "л" .. p[5], "п" .. p[2], "с" .. p[2], "т" .. p[2], "ф" .. p[2], "х" .. p[3], "ц" .. p[3], "ч" .. p[3], "ч" .. p[5], "ш" .. p[2], "ш" .. p[4], "щ" .. p[2],
"г" .. p[1], "г" .. p[2], "г" .. p[4], "д" .. p[1], "д" .. p[3], "е" .. p[1], "ж" .. p[1], "ж" .. p[3], "к" .. p[1], "к" .. p[2], "к" .. p[8], "к" .. p[9], "л" .. p[1], "л" .. p[3], "л" .. p[4], "п" .. p[1], "с" .. p[1], "т" .. p[1], "ф" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[4], "ц" .. p[1], "ц" .. p[2], "ч" .. p[1], "ч" .. p[2], "ч" .. p[4], "ш" .. p[1], "ш" .. p[3], "щ" .. p[1], "ӏ" .. p[1], "ӏ" .. p[2]
}
},
},
}
m["adz"] = {
"tiếng Adzera",
nil,
"poz-ocw",
"Latn",
"Tiếng Adzera",
"Adzera",
}
m["aea"] = {
"Areba",
3509129,
"aus-pam",
"Latn",
}
m["aeb"] = {
"tiếng Ả Rập Tunisia",
56240,
"sem-arb",
"Arab",
"Tiếng Ả Rập Tunisia",
"Ả Rập Tunisia",
entry_name = "ar-entryname",
}
m["aed"] = {
"Argentine Sign Language",
3322073,
"sgn",
"Latn", -- when documented
}
m["aee"] = {
"Northeast Pashayi",
12642198,
"inc-pas",
"fa-Arab, Latn",
}
m["aek"] = {
"Haeke",
5638166,
"poz-cln",
"Latn",
}
m["ael"] = {
"Ambele",
34818,
"nic-grf",
"Latn",
}
m["aem"] = {
"tiếng Arem",
3507920,
"mkh-vie",
"Latn",
"Tiếng Arem",
"Arem",
}
m["aen"] = {
"Armenian Sign Language",
3446604,
"sgn",
}
m["aeq"] = {
"tiếng Aer",
3246741,
"inc-wes",
"Arab",
"Tiếng Aer",
"Aer",
}
m["aer"] = {
"tiếng Arrernte Đông",
10728232,
"aus-pam",
"Latn",
"Tiếng Arrernte Đông",
"Arrernte Đông",
}
m["aes"] = {
"tiếng Alsea",
2395641,
nil,
"Latn",
"Tiếng Alsea",
"Alsea",
}
m["aeu"] = {
"Akeu",
4700657,
"tbq-sil",
"Latn",
}
m["aew"] = {
"Ambakich",
56642,
"paa-ram",
"Latn",
}
m["aey"] = {
"Amele",
3508025,
"ngf-mad",
"Latn",
}
m["aez"] = {
"Aeka",
16110528,
"ngf",
"Latn",
wikipedia_article = "Orokaiva language", -- subvariety?
}
m["afb"] = {
"tiếng Ả Rập vùng Vịnh",
56385,
"sem-arb",
"Arab",
"Tiếng Ả Rập vùng Vịnh",
"Ả Rập vùng Vịnh",
entry_name = "ar-entryname",
}
m["afd"] = {
"Andai",
4753480,
"paa-arf",
"Latn",
}
m["afe"] = {
"Putukwam",
3914930,
"nic-ben",
"Latn",
}
m["afg"] = {
"Afghan Sign Language",
4689093,
"sgn",
}
m["afh"] = {
"Afrihili",
384707,
"art",
"Latn",
type = "appendix-constructed",
}
m["afi"] = {
"Akrukay",
57003,
"paa-ram",
"Latn",
}
m["afk"] = {
"Nanubae",
6964416,
"paa-arf",
"Latn",
}
m["afn"] = {
"Defaka",
35174,
"nic",
"Latn",
}
m["afo"] = {
"Eloyi",
3914066,
"nic-plt",
"Latn",
}
m["afp"] = {
"Tapei",
16887371,
"paa-arf",
"Latn",
}
m["afs"] = {
"Afro-Seminole Creole",
27867,
"crp",
"Latn",
ancestors = "en",
}
m["aft"] = {
"Afitti",
3400829,
"sdv-nyi",
"Latn",
}
m["afu"] = {
"Awutu",
34847,
"alv-gng",
"Latn",
}
m["afz"] = {
"Obokuitai",
7075258,
"paa-lkp",
"Latn",
}
m["aga"] = {
"Aguano",
3331203,
nil,
"Latn",
}
m["agb"] = {
"Legbo",
35584,
"nic-uce",
"Latn",
}
m["agc"] = {
"tiếng Agatu",
34732,
"alv-ido",
"Latn",
"Tiếng Agatu",
"Agatu",
}
m["agd"] = {
"Agarabi",
3399642,
"paa-kag",
"Latn",
}
m["age"] = {
"Angal",
10951553,
"paa-eng",
"Latn",
}
m["agf"] = {
"Arguni",
12473346,
"poz-cet",
"Latn",
}
m["agg"] = {
"Angor",
3508100,
"paa",
"Latn",
}
m["agh"] = {
"Ngelima",
7022266,
"bnt-bta",
"Latn",
}
m["agi"] = {
"Agariya",
663586,
"mun",
"Deva",
}
m["agj"] = {
"tiếng Argobba",
29292,
"sem-eth",
"Ethi",
"Tiếng Argobba",
"Argobba",
}
m["agk"] = {
"Isarog Agta",
6078982,
"phi",
"Latn",
}
m["agl"] = {
"Fembe",
372927,
"ngf",
"Latn",
}
m["agm"] = {
"tiếng Angaataha",
3508001,
"ngf-ang",
"Latn",
}
m["agn"] = {
"Agutaynen",
3399717,
"phi-kal",
"Latn",
}
m["ago"] = {
"Tainae",
7676186,
"ngf",
"Latn",
}
m["agq"] = {
"tiếng Aghem",
34737,
"nic-rnw",
"Latn",
"Tiếng Aghem",
"Aghem",
}
m["agr"] = {
"Aguaruna",
1526530,
"sai-jiv",
"Latn",
"Tiếng Aguaruna",
"Aguaruna",
}
m["ags"] = {
"tiếng Esimbi",
35260,
"nic-bds",
"Latn",
"Tiếng Esimbi",
"Esimbi",
}
m["agt"] = {
"Central Cagayan Agta",
5017296,
"phi",
"Latn",
}
m["agu"] = {
"tiếng Aguacateca",
35091,
"myn",
"Latn",
"Tiếng Aguacateca",
"Aguacateca",
}
m["agv"] = {
"Remontado Agta",
3508085,
"phi",
"Latn",
}
m["agw"] = {
"Kahua",
3191906,
"poz-sls",
"Latn",
}
m["agx"] = {
"tiếng Aghul",
36498,
"cau-esm",
"Cyrl",
"Tiếng Aghul",
"Aghul",
translit = "cau-nec-translit",
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {Cyrl = s["cau-Cyrl-entryname"]},
sort_key = {
from = {"аь", "гъ", "гь", "гӏ", "дж", "ё", "къ", "кь", "кӏ", "оь", "пӏ", "тӏ", "уь", "хъ", "хь", "хӏ", "цӏ", "чӏ"},
to = {"а" .. p[1], "г" .. p[1], "г" .. p[2], "г" .. p[3], "д" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "о" .. p[1], "п" .. p[1], "т" .. p[1], "у" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "ц" .. p[1], "ч" .. p[1]}
},
}
m["agy"] = {
"Southern Alta",
7569611,
"phi",
"Latn",
}
m["agz"] = {
"Mount Iriga Agta",
6921432,
"phi",
"Latn",
}
m["aha"] = {
"Ahanta",
34729,
"alv-ctn",
"Latn",
}
m["ahb"] = {
"Axamb",
2874710,
"poz-vnc",
"Latn",
}
m["ahg"] = {
"tiếng Qimant",
35663,
"cus-cen",
"Latn",
"Tiếng Qimant",
"Qimant",
}
m["ahh"] = {
"Aghu",
3436645,
"ngf",
"Latn",
}
m["ahi"] = {
"Tiagbamrin Aizi",
3400073,
"kro-aiz",
"Latn",
}
m["ahk"] = {
"tiếng Akha",
56643,
"tbq-han",
"Latn, Mymr, Thai",
"Tiếng Akha",
"Akha",
sort_key = {
Thai = {
from = {"[%pๆ]", "[็-๎]", "([เแโใไ])([ก-ฮ])"},
to = {"", "", "%2%1"}
},
},
}
m["ahl"] = {
"Igo",
35412,
"alv-ktg",
"Latn",
}
m["ahm"] = {
"Mobumrin Aizi",
35967,
"kro-aiz",
"Latn",
}
m["ahn"] = {
"Àhàn",
34723,
"alv-aah",
"Latn",
}
m["aho"] = {
"tiếng Ahom",
34778,
"tai-swe",
"Ahom",
"Tiếng Ahom",
"Ahom",
translit = "Ahom-translit",
}
m["ahp"] = {
"Aproumu Aizi",
34810,
"alv-kwa",
"Latn",
}
m["ahr"] = {
"tiếng Ahiran",
15549890,
"inc-wes",
"Deva",
"Tiếng Ahiran",
"Ahiran",
translit = "mr-translit",
}
m["ahs"] = {
"Ashe",
34823,
"nic-plc",
"Latn",
}
m["aht"] = {
"tiếng Ahtna",
21058,
"ath-nor",
"Latn",
"Tiếng Ahtna",
"Ahtna",
}
m["aia"] = {
"Arosi",
2863483,
"poz-sls",
"Latn",
}
m["aib"] = {
"tiếng Äynu",
27927,
"qfa-mix",
"Arab, Latn",
"Tiếng Äynu",
"Äynu",
ancestors = "ug, fa"
}
m["aic"] = {
"Ainbai",
3332149,
"paa-brd",
"Latn",
}
m["aid"] = {
"Alngith",
3279409,
"aus-pmn",
"Latn",
}
m["aie"] = {
"Amara",
2841180,
"poz-ocw",
"Latn",
}
m["aif"] = {
"Agi",
3331491,
"qfa-tor",
"Latn",
}
m["aig"] = {
"Antigua and Barbuda Creole English",
3244184,
"crp",
"Latn",
ancestors = "en",
}
m["aih"] = {
"Ai-Cham",
2827749,
"qfa-kms",
"Latn, Hani",
sort_key = {Hani = "Hani-sortkey"},
}
m["aii"] = {
"tiếng Tân Aram Assyria",
29440,
"sem-nna",
"Syrc, Cyrl",
"Tiếng Tân Aram Assyria",
"Tân Aram Assyria",
translit = {Syrc = "aii-translit"},
entry_name = "Syrc-entryname",
}
m["aij"] = {
"tiếng Lishanid Noshan",
3436467,
"sem-nna",
"Hebr",
"Tiếng Lishanid Noshan",
"Lishanid Noshan",
}
m["aik"] = {
"Ake",
34808,
"nic-pls",
"Latn",
}
m["ail"] = {
"Aimele",
3327418,
"ngf",
"Latn",
}
m["aim"] = {
"tiếng Aimol",
4697175,
"tbq-kuk",
"Latn, Beng",
"Tiếng Aimol",
"Aimol",
}
m["ain"] = {
"tiếng Ainu",
27969,
"qfa-ain",
"Kana, Latn, Cyrl",
"Tiếng Ainu",
"Ainu",
sort_key = {Kana = "Kana-sortkey"},
}
m["aio"] = {
"tiếng Aiton",
3399725,
"tai-swe",
"Mymr",
"Tiếng Aiton",
"Aiton",
translit = "aio-phk-translit",
entry_name = {remove_diacritics = c.VS01},
}
m["aip"] = {
"Burumakok",
5000984,
"ngf-okk",
"Latn",
}
m["air"] = {
"Airoran",
3321131,
"paa-tkw",
"Latn",
}
m["ait"] = {
"Arikem",
3446679,
"tup",
"Latn",
}
m["aiw"] = {
"tiếng Aari",
7495,
"omv-aro",
"Latn, Ethi",
"Tiếng Aari",
"Aari",
}
m["aix"] = {
"Aighon",
3504287,
"poz-ocw",
"Latn",
}
m["aiy"] = {
"Ali",
34814,
"alv-gbf",
"Latn",
}
m["aja"] = {
"Aja",
3237491,
"csu-bkr",
"Latn",
}
m["ajg"] = {
"tiếng Adja",
35035,
"alv-gbe",
"Latn",
"Tiếng Adja",
"Adja",
}
m["aji"] = {
"tiếng Ajië",
2828867,
"poz-cln",
"Latn",
"Tiếng Ajië",
"Ajië",
}
m["ajn"] = {
"Andajin",
16111302,
"aus-wor",
"Latn",
}
m["ajp"] = {
"tiếng Ả Rập Nam Levant",
nil,
"sem-arb",
"Arab",
"Tiếng Ả Rập Nam Levant",
"Ả Rập Nam Levant",
entry_name = "ar-entryname",
}
m["ajw"] = {
"Ajawa",
56645,
"cdc-wst",
"Latn",
}
m["ajz"] = {
"Amri Karbi",
3508092,
"tbq-kuk",
"Latn",
ancestors = "mjw",
}
m["akb"] = {
"Angkola Batak",
2640686,
"btk",
"Latn, Batk",
}
m["akc"] = {
"Mpur",
3327139,
"paa-wpa",
"Latn",
}
m["akd"] = {
"Ukpet-Ehom",
36618,
"nic-ucr",
"Latn",
}
m["ake"] = {
"tiếng Akawaio",
28059,
"sai-pem",
"Latn",
"Tiếng Akawaio",
"Akawaio",
}
m["akf"] = {
"Akpa",
34801,
"alv-ido",
"Latn",
}
m["akg"] = {
"Anakalangu",
4750964,
"poz-cet",
"Latn",
}
m["akh"] = {
"Angal Heneng",
10950354,
"paa-eng",
"Latn",
}
m["aki"] = {
"Aiome",
56735,
"paa",
"Latn",
}
m["akj"] = {
"tiếng Aka-Jeru",
2919121,
"qfa-adn",
"Latn, Deva",
"Tiếng Aka-Jeru",
"Aka-Jeru",
}
m["akk"] = {
"tiếng Akkad",
35518,
"sem-eas",
"Xsux, Latn",
"Tiếng Akkad",
"Akkad",
}
m["akl"] = {
"tiếng Aklanon",
8773,
"phi",
"Latn",
"Tiếng Aklanon",
"Aklanon",
ancestors = "poz-pro,phi-pro",
}
m["akm"] = {
"tiếng Aka-Bo",
35361,
"qfa-adn",
"Latn",
"Tiếng Aka-Bo",
"Aka-Bo",
}
m["ako"] = {
"Akurio",
56650,
"sai-tar",
"Latn",
}
m["akp"] = {
"tiếng Siwu",
36470,
"alv-ntg",
"Latn",
"Tiếng Siwu",
"Siwu",
}
m["akq"] = {
"Ak",
56654,
"paa",
"Latn",
}
m["akr"] = {
"tiếng Araki",
2699882,
"poz-vnc",
"Latn",
"Tiếng Araki",
"Araki",
}
m["aks"] = {
"tiếng Akaselem",
34817,
"nic-grm",
"Latn",
"Tiếng Akaselem",
"Akaselem",
}
m["akt"] = {
"Akolet",
3330162,
"poz-ocw",
"Latn",
}
m["aku"] = {
"Akum",
34799,
"nic-ykb",
"Latn",
}
m["akv"] = {
"tiếng Akhvakh",
56423,
"cau-and",
"Cyrl",
"Tiếng Akhvakh",
"Akhvakh",
translit = "cau-nec-translit",
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {Cyrl = s["cau-Cyrl-entryname"]},
}
m["akw"] = {
"Akwa",
34802,
"bnt-mbo",
"Latn",
}
m["akx"] = {
"tiếng Aka-Kede",
3436816,
"qfa-adc",
"Latn",
"Tiếng Aka-Kede",
"Aka-Kede",
}
m["aky"] = {
"Aka-Kol",
3436784,
"qfa-adc",
"Latn",
}
m["akz"] = {
"tiếng Alabama",
1815020,
"nai-mus",
"Latn",
"Tiếng Alabama",
"Alabama",
}
m["ala"] = {
"Alago",
34813,
"alv-ido",
"Latn",
}
m["alc"] = {
"tiếng Kawésqar",
56544,
"aqa",
"Latn",
"Tiếng Kawésqar",
"Kawésqar",
}
m["ald"] = {
"Alladian",
34837,
"alv-lag",
"Latn",
}
m["ale"] = {
"tiếng Aleut",
27210,
"esx",
"Latn, Cyrl",
"Tiếng Aleut",
"Aleut",
}
m["alf"] = {
"Alege",
34815,
"nic-ben",
"Latn",
}
m["alh"] = {
"tiếng Alawa",
2147917,
"aus-gun",
"Latn",
"Tiếng Alawa",
"Alawa",
}
m["ali"] = {
"tiếng Amaimon",
3327427,
"ngf-mad",
"Latn",
"Tiếng Amaimon",
"Amaimon",
}
m["alj"] = {
"tiếng Alangan",
3327423,
"phi",
"Latn",
"Tiếng Alangan",
"Alangan",
}
m["alk"] = {
"tiếng Alak",
2714690,
"mkh",
"Latn, Laoo",
"Tiếng Alak",
"Alak"
}
m["all"] = {
"tiếng Allar",
3393634,
"dra-mal",
"Mlym",
"Tiếng Allar",
"Allar",
translit = "ml-translit"
}
-- "aln" IS TREATED AS "sq", SEE WT:LT
m["alm"] = {
"Amblong",
11022615,
"poz-vnc",
"Latn",
}
m["alo"] = {
"Larike-Wakasihu",
3217929,
"poz-cma",
"Latn",
}
m["alp"] = {
"tiếng Alune",
3327367,
"poz-cet",
"Latn",
}
m["alq"] = {
"tiếng Algonquin",
28092,
"alg",
"Latn",
"Tiếng Algonquin",
"Algonquin",
ancestors = "oj",
}
m["alr"] = {
"tiếng Alutor",
28213,
"qfa-ckn",
"Cyrl",
"Tiếng Alutor",
"Alutor",
entry_name = {
from = {"['’]"},
to = {"ʼ"}
},
sort_key = {
from = {"вʼ", "гʼ", "ғ", "ә", "ё", "ӄ", "ӈ"},
to = {"в" .. p[1], "г" .. p[1], "г" .. p[2], "е" .. p[1], "е" .. p[2], "к" .. p[1], "н" .. p[1]}
},
}
m["alt"] = {
"tiếng Nam Altai",
1991779,
"trk-kkp",
"Cyrl",
"Tiếng Nam Altai",
"Nam Altai",
translit = "Altai-translit",
sort_key = {
from = {"ј", "ё", "ҥ", "ӧ", "ӱ"},
to = {"д" .. p[1], "е" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1]}
},
}
m["alu"] = {
"tiếng 'Are'are",
5160,
"poz-sls",
"Latn",
"Tiếng 'Are'are",
"'Are'are",
}
m["alw"] = {
"tiếng Alaba-K’abeena",
56652,
"cus-hec",
"Latn, Ethi",
"Tiếng Alaba-K’abeena",
"Alaba-K’abeena",
}
m["alx"] = {
"Amol",
3504260,
"qfa-tor",
"Latn",
}
m["aly"] = {
"Alyawarr",
3327389,
"aus-pam",
"Latn",
}
m["alz"] = {
"Alur",
56507,
"sdv-los",
"Latn",
}
m["ama"] = {
"Amanayé",
3508053,
"tup-gua",
"Latn",
}
m["amb"] = {
"Ambo",
3450142,
"nic-tvn",
"Latn",
}
m["amc"] = {
"tiếng Amahuaca",
2669150,
"sai-pan",
"Latn",
"Tiếng Amahuaca",
"Amahuaca",
}
m["ame"] = {
"tiếng Yanesha'",
3088540,
"awd",
"Latn",
"Tiếng Yanesha'",
"Yanesha'",
}
m["amf"] = {
"tiếng Hamer-Banna",
35764,
"omv-aro",
"Latn, Ethi",
"Tiếng Hamer-Banna",
"Hamer-Banna",
}
m["amg"] = {
"tiếng Amurdag",
3360016,
"aus-wdj",
"Latn",
"Tiếng Amurdag",
"Amurdag",
}
m["ami"] = {
"tiếng Amis",
35132,
"map",
"Latn",
"Tiếng Amis",
"Amis",
}
m["amj"] = {
"tiếng Amdang",
28335,
"ssa-fur",
"Latn",
"Tiếng Amdang",
"Amdang",
}
m["amk"] = {
"tiếng Ambai",
1875885,
"poz-hce",
"Latn",
"Tiếng Ambai",
"Ambai",
}
m["aml"] = {
"tiếng War-Jaintia",
56321,
"aav-khs",
"Latn",
"Tiếng War-Jaintia",
"War-Jaintia",
}
m["amm"] = {
"tiếng Ama",
3446626,
"qfa-mal",
"Latn",
"Tiếng Ama",
"Ama",
}
m["amn"] = {
"tiếng Amanab",
3327399,
"paa-brd",
"Latn",
"Tiếng Amanab",
"Amanab",
}
m["amo"] = {
"Amo",
34826,
"nic-kne",
"Latn",
}
m["amp"] = {
"tiếng Alamblak",
56688,
"paa",
"Latn",
"Tiếng Alamblak",
"Alamblak",
}
m["amq"] = {
"Amahai",
3327384,
"poz-cma",
"Latn",
}
m["amr"] = {
"Amarakaeri",
35128,
"sai-har",
"Latn",
}
m["ams"] = {
"tiếng Nam Amami Ōshima",
2840986,
"jpx-nry",
"Jpan",
"Tiếng Nam Amami Ōshima",
"Nam Amami Ōshima",
translit = s["jpx-translit"],
display_text = s["jpx-displaytext"],
entry_name = s["jpx-entryname"],
sort_key = s["jpx-sortkey"],
}
m["amt"] = {
"Amto",
56517,
"paa-asa",
"Latn",
}
m["amu"] = {
"tiếng Amuzgo",
3501942,
"omq",
"Latn",
"Tiếng Amuzgo",
"Amuzgo",
}
m["amv"] = {
"Ambelau",
2669214,
"poz-cma",
"Latn",
}
m["amw"] = {
"tiếng Tân Aram Tây",
34226,
"sem-arw",
"Armi, Syrc, Latn",
"Tiếng Tân Aram Tây",
"Tân Aram Tây",
entry_name = {Syrc = "Syrc-entryname"},
}
m["amx"] = {
"Anmatyerre",
10412317,
"aus-pam",
"Latn",
}
m["amy"] = {
"Ami",
12626835,
"aus-dal",
"Latn",
}
m["amz"] = {
"Atampaya",
3446651,
"aus-pam",
"Latn",
}
m["ana"] = {
"Andaqui",
2846078,
nil,
"Latn",
}
m["anb"] = {
"Andoa",
2846171,
"sai-zap",
"Latn",
}
m["anc"] = {
"tiếng Ngas",
35999,
"cdc-wst",
"Latn",
"Tiếng Ngas",
"Ngas",
}
m["and"] = {
"Ansus",
3513300,
"poz-hce",
"Latn",
}
m["ane"] = {
"tiếng Xârâcùù",
3571097,
"poz-cln",
"Latn",
"Tiếng Xârâcùù",
"Xârâcùù",
}
m["anf"] = {
"Animere",
34783,
"alv-ktg",
"Latn",
}
m["ang"] = {
"tiếng Anh cổ",
42365,
"gmw-ang",
"Latn, Runr",
"Tiếng Anh cổ",
"Anh cổ",
translit = {Runr = "Runr-translit"},
entry_name = {
Latn = {
remove_diacritics = c.acute .. c.macron .. c.dotabove,
from = {"Ƿ", "ƿ"},
to = {"W", "w"}
},
},
sort_key = {
Latn = {
from = {"æ", "ð", "þ", "ƿ"},
to = {"ae", "t" .. p[1], "t" .. p[2], "w" .. p[1]}
},
},
}
m["anh"] = {
"Nend",
6991554,
"ngf-mad",
"Latn",
}
m["ani"] = {
"tiếng Andi",
34849,
"cau-and",
"Cyrl",
"Tiếng Andi",
"Andi",
translit = "cau-nec-translit",
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {Cyrl = s["cau-Cyrl-entryname"]},
}
m["anj"] = {
"Anor",
56458,
"paa",
"Latn",
}
m["ank"] = {
"Goemai",
35272,
"cdc-wst",
"Latn",
}
m["anl"] = {
"Anu",
4777679,
"sit-mru",
"Latn",
}
m["anm"] = {
"tiếng Anal",
56235,
"tbq-kuk",
"Latn",
"Tiếng Anal",
"Anal",
}
m["ann"] = {
"Obolo",
36614,
"nic-lcr",
"Latn",
}
m["ano"] = {
"Andoque",
2669225,
"qfa-iso",
"Latn",
}
m["anp"] = {
"tiếng Angika",
28378,
"inc-bih",
"Deva, Kthi",
"Tiếng Angika",
"Angika",
translit = {
Deva = "hi-translit",
Kthi = "bho-Kthi-translit",
},
ancestors = "bh",
}
m["anq"] = {
"tiếng Jarawa",
2475526,
"qfa-ong",
"Latn, Deva",
"Tiếng Jarawa",
"Jarawa",
}
m["anr"] = {
"Andh",
4754314,
"inc-sou",
"Deva",
}
m["ans"] = {
"Anserma",
3446613,
"sai-chc",
"Latn",
}
m["ant"] = {
"Antakarinya",
921304,
"aus-psw",
"Latn",
}
m["anu"] = {
"tiếng Anuak",
56677,
"sdv-lon",
"Latn, Ethi",
"Tiếng Anuak",
"Anuak",
}
m["anv"] = {
"Denya",
35187,
"nic-mam",
"Latn",
}
m["anw"] = {
"tiếng Anaang",
2845320,
"nic-ief",
"Latn",
"Tiếng Anaang",
"Anaang",
}
m["anx"] = {
"Andra-Hus",
2846195,
"poz-aay",
"Latn",
}
m["any"] = {
"tiếng Anyi",
28395,
"alv-ctn",
"Latn",
"Tiếng Anyi",
"Anyi",
}
m["anz"] = {
"Anem",
56512,
"paa",
"Latn",
}
m["aoa"] = {
"tiếng Angola",
34994,
"crp",
"Latn",
"Tiếng Angola",
"Angola",
ancestors = "pt",
}
m["aob"] = {
"Abom",
3446647,
"ngf",
"Latn",
}
m["aoc"] = {
"tiếng Pemon",
10729616,
"sai-pem",
"Latn",
"Tiếng Pemon",
"Pemon",
}
m["aod"] = {
"Andarum",
3507888,
"paa",
"Latn",
}
m["aoe"] = {
"Angal Enen",
10951638,
"paa-eng",
"Latn",
}
m["aof"] = {
"Bragat",
3507977,
"qfa-tor",
"Latn",
}
m["aog"] = {
"Angoram",
56366, -- cf 6754745 for merged dialect
"paa-lsp",
"Latn",
}
m["aoi"] = {
"Anindilyakwa",
2714654,
"aus-arn",
"Latn",
}
m["aoj"] = {
"Mufian",
3507881,
"qfa-tor",
"Latn",
}
m["aok"] = {
"Arhö",
4790086,
"poz-cln",
"Latn",
}
m["aol"] = {
"Alor",
3332062,
"poz",
"Latn",
}
m["aom"] = {
"Ömie",
8078975,
"ngf",
"Latn",
}
m["aon"] = {
"Bumbita Arapesh",
3508044,
"qfa-tor",
"Latn",
}
m["aor"] = {
"Aore",
12627129,
"poz-vnc",
"Latn",
}
m["aos"] = {
"Taikat",
7676018,
"paa-brd",
"Latn",
}
m["aot"] = {
"tiếng Atong (Ấn Độ)",
5646,
"tbq-bdg",
"Latn, Beng",
"Tiếng Atong (Ấn Độ)",
"Atong (Ấn Độ)",
}
m["aou"] = {
"tiếng A'ou",
16109994,
"qfa-gel",
"Latn", -- also Hani?
"Tiếng A'ou",
"A'ou",
}
m["aox"] = {
"Atorada",
3507932,
"awd",
"Latn",
}
m["aoz"] = {
"Uab Meto",
3441962,
"poz-tim",
"Latn",
}
m["apb"] = {
"Sa'a",
36294,
"poz-sls",
"Latn",
}
m["apc"] = {
"tiếng Ả Rập Bắc Levant",
22809485,
"sem-arb",
"Arab",
"Tiếng Ả Rập Bắc Levant",
"Ả Rập Bắc Levant",
entry_name = "ar-entryname",
}
m["apd"] = {
"tiếng Ả Rập Sudan",
56573,
"sem-arb",
"Arab",
"Tiếng Ả Rập Sudan",
"Ả Rập Sudan",
entry_name = "ar-entryname",
}
m["ape"] = {
"tiếng Bukiyip",
3507895,
"paa-ara",
"Latn",
}
m["apf"] = {
"Pahanan Agta",
7135432,
"phi",
"Latn",
}
m["apg"] = {
"Ampanang",
4748035,
"poz",
"Latn",
}
m["aph"] = {
"tiếng Athpariya",
3449126,
"sit-kie",
"Deva, Latn",
"Tiếng Athpariya",
"Athpariya",
}
m["api"] = {
"Apiaká",
3507941,
"tup-gua",
"Latn",
}
m["apj"] = {
"tiếng Jicarilla",
28277,
"apa",
"Latn",
"Tiếng Jicarilla",
"Jicarilla",
}
m["apk"] = {
"tiếng Apache đồng bằng",
27861,
"apa",
"Latn",
"Tiếng Apache đồng bằng",
"Apache đồng bằng"
}
m["apl"] = {
"tiếng Lipan",
28269,
"apa",
"Latn",
"Tiếng Lipan",
"Lipan",
}
m["apm"] = {
"tiếng Chiricahua",
13368,
"apa",
"Latn",
"Tiếng Chiricahua",
"Chiricahua",
}
m["apn"] = {
"tiếng Apinayé",
2858311,
"sai-nje",
"Latn",
"Tiếng Apinayé",
"Apinayé",
}
m["apo"] = {
"Ambul",
12627135,
"poz-ocw",
"Latn",
}
m["app"] = {
"Apma",
2669188,
"poz-vnc",
"Latn",
}
m["apq"] = {
"tiếng Pucikwar",
28466,
"qfa-adc",
"Latn",
"Tiếng Pucikwar",
"Pucikwar",
}
m["apr"] = {
"Arop-Lokep",
2863482,
"poz-ocw",
"Latn",
}
m["aps"] = {
"Arop-Sissano",
12627242,
"poz-ocw",
"Latn",
}
m["apt"] = {
"tiếng Apatani",
56306,
"sit-tan",
"Latn",
"Tiếng Apatani",
"Apatani",
}
m["apu"] = {
"Apurinã",
2859081,
"awd",
"Latn",
}
m["apv"] = {
"Alapmunte",
16110782,
"sai-nmk",
"Latn",
}
m["apw"] = {
"tiếng Apache Tây",
28060,
"apa",
"Latn",
"Tiếng Apache Tây",
"Apache Tây",
}
m["apx"] = {
"tiếng Aputai",
12473343,
"poz-tim",
"Latn",
"Tiếng Aputai",
"Aputai",
}
m["apy"] = {
"tiếng Aparaí",
2736980,
"sai-gui",
"Latn",
"Tiếng Aparaí",
"Aparaí",
}
m["apz"] = {
"Safeyoka",
7398693,
"ngf",
"Latn",
}
m["aqc"] = {
"tiếng Archi",
34915,
"cau-lzg",
"Cyrl",
"Tiếng Archi",
"Archi",
translit = "cau-nec-translit",
override_translit = true,
display_text = {Cyrl = s["cau-Cyrl-displaytext"]},
entry_name = {Cyrl = s["cau-Cyrl-entryname"]},
sort_key = {
from = {
"ккъӏв", "ххьӏв", -- 5 chars
"гъӏв", "ёоӏ", "ккъӏ", "ккъв", "къӏв", "ллъв", "ххьӏ", "хъӏв", "хьӏв", "ццӏв", "ччӏв", -- 4 chars
"ааӏ", "гӏв", "гъӏ", "гъв", "гьв", "ееӏ", "ёӏ", "ёо", "ииӏ", "кӏв", "ккв", "ккъ", "къӏ", "къв", "кьв", "лӏв", "ллъ", "лъв", "льв", "ооӏ", "пӏв", "ппв", "ссв", "тӏв", "ттв", "ууӏ", "хӏв", "ххв", "хъӏ", "хъв", "хьӏ", "цӏв", "ццӏ", "ццв", "чӏв", "ччӏ", "ээӏ", "юуӏ", "яаӏ", -- 3 chars
"аӏ", "аа", "гӏ", "гв", "гъ", "гь", "дв", "еӏ", "ее", "ё", "жв", "зв", "иӏ", "ии", "кӏ", "кв", "кк", "къ", "кь", "лӏ", "лв", "лъ", "ль", "оӏ", "оо", "пӏ", "пв", "пп", "св", "сс", "тӏ", "тв", "тт", "уӏ", "уу", "фв", "хӏ", "хв", "хх", "хъ", "цӏ", "цв", "цц", "чӏ", "чв", "шв", "щв", "эӏ", "ээ", "юӏ", "юу", "яӏ", "яа" -- 2 chars
},
to = {
"к" .. p[8], "х" .. p[7],
"г" .. p[6], "е" .. p[7], "к" .. p[7], "к" .. p[9], "к" .. p[12], "л" .. p[5], "х" .. p[6], "х" .. p[10], "х" .. p[13], "ц" .. p[6], "ч" .. p[5],
"а" .. p[3], "г" .. p[2], "г" .. p[5], "г" .. p[7], "г" .. p[9], "е" .. p[3], "е" .. p[5], "е" .. p[6], "и" .. p[3], "к" .. p[2], "к" .. p[5], "к" .. p[6], "к" .. p[11], "к" .. p[13], "к" .. p[15], "л" .. p[2], "л" .. p[4], "л" .. p[7], "л" .. p[9], "о" .. p[3], "п" .. p[2], "п" .. p[5], "с" .. p[3], "т" .. p[2], "т" .. p[5], "у" .. p[3], "х" .. p[2], "х" .. p[5], "х" .. p[9], "х" .. p[11], "х" .. p[12], "ц" .. p[2], "ц" .. p[5], "ц" .. p[7], "ч" .. p[2], "ч" .. p[4], "э" .. p[3], "ю" .. p[3], "я" .. p[3],
"а" .. p[1], "а" .. p[2], "г" .. p[1], "г" .. p[3], "г" .. p[4], "г" .. p[8], "д" .. p[1], "е" .. p[1], "е" .. p[2], "е" .. p[4], "ж" .. p[1], "з" .. p[1], "и" .. p[1], "и" .. p[2], "к" .. p[1], "к" .. p[3], "к" .. p[4], "к" .. p[10], "к" .. p[14], "л" .. p[1], "л" .. p[3], "л" .. p[6], "л" .. p[8], "о" .. p[1], "о" .. p[2], "п" .. p[1], "п" .. p[3], "п" .. p[4], "с" .. p[1], "с" .. p[2], "т" .. p[1], "т" .. p[3], "т" .. p[4], "у" .. p[1], "у" .. p[2], "ф" .. p[1], "х" .. p[1], "х" .. p[3], "х" .. p[4], "х" .. p[8], "ц" .. p[1], "ц" .. p[3], "ц" .. p[4], "ч" .. p[1], "ч" .. p[3], "ш" .. p[1], "щ" .. p[1], "э" .. p[1], "э" .. p[2], "ю" .. p[1], "ю" .. p[2], "я" .. p[1], "я" .. p[2]
}
},
}
m["aqd"] = {
"Ampari Dogon",
4748057,
"nic-dgw",
"Latn",
}
m["aqg"] = {
"Arigidi",
34829,
"alv-von",
"Latn",
}
m["aqm"] = {
"Atohwaim",
11732297,
"ngf",
"Latn",
}
m["aqn"] = {
"Northern Alta",
7058116,
"phi",
"Latn",
}
m["aqp"] = {
"Atakapa",
10975683,
"qfa-iso",
"Latn",
}
m["aqr"] = {
"Arhâ",
4790085,
"poz-cln",
"Latn",
}
m["aqt"] = {
"Angaité",
15736037,
"sai-mas",
"Latn",
}
m["aqz"] = {
"tiếng Akuntsu",
4701960,
"tup",
"Latn",
"Tiếng Akuntsu",
"Akuntsu",
}
m["arc"] = {
"tiếng Aram",
28602,
"sem-ara",
"Hebr, Armi, Syrc, Palm, Nbat, Phnx, Mand, Samr, Hatr, Elym",
"Tiếng Aram",
"Aram",
translit = {
Armi = "Armi-translit",
Palm = "Palm-translit",
},
entry_name = {
Hebr = {remove_diacritics = u(0x0591) .. "-" .. u(0x05BD) .. u(0x05BF) .. "-" .. u(0x05C5) .. u(0x05C7)},
Syrc = {remove_diacritics = u(0x0730) .. "-" .. u(0x0748)},
remove_diacritics = c.macron .. c.diaer .. c.macronbelow}, -- Which script(s)?
}
m["ard"] = {
"Arabana",
3507959,
"aus-kar",
"Latn",
}
m["are"] = {
"Western Arrernte",
12645549,
"aus-pam",
"Latn",
}
m["arh"] = {
"tiếng Arhuaco",
2640621,
"cba",
"Latn",
"Tiếng Arhuaco",
"Arhuaco",
}
m["ari"] = {
"Arikara",
56539,
"cdd",
"Latn",
}
m["arj"] = {
"Arapaso",
12627166,
"sai-tuc",
"Latn",
}
m["ark"] = {
"Arikapú",
3446640,
"sai-mje",
"Latn",
}
m["arl"] = {
"Arabela",
2591221,
"sai-zap",
"Latn",
}
m["arn"] = {
"tiếng Mapuche",
33730,
"sai-ara",
"Latn",
"Tiếng Mapuche",
"Mapuche",
}
m["aro"] = {
"Araona",
958414,
"sai-tac",
"Latn",
}
m["arp"] = {
"tiếng Arapaho",
56417,
"alg-ara",
"Latn",
"Tiếng Arapaho",
"Arapaho",
}
m["arq"] = {
"tiếng Ả Rập Algérie",
56499,
"sem-arb",
"Arab",
"Tiếng Ả Rập Algérie",
"Ả Rập Algérie",
entry_name = "ar-entryname",
}
m["arr"] = {
"Arara-Karo",
35539,
"tup",
"Latn",
}
m["ars"] = {
"tiếng Ả Rập Najd",
56574,
"sem-arb",
"Arab",
"Tiếng Ả Rập Najd",
"Ả Rập Najd",
entry_name = "ar-entryname",
}
m["aru"] = {
"Arua",
2746221,
"auf",
"Latn",
}
m["arv"] = {
"Arbore",
56883,
"cus-eas",
"Latn",
}
m["arw"] = {
"tiếng Lokono",
2655664,
"awd-taa",
"Latn",
"Tiếng Lokono",
"Lokono",
}
m["arx"] = {
"Aruá",
3507907,
"tup",
"Latn",
}
m["ary"] = {
"tiếng Ả Rập Maroc",
56426,
"sem-arb",
"Arab",
"Tiếng Ả Rập Maroc",
"Ả Rập Maroc",
entry_name = "ar-entryname",
sort_key = {
from = {"^%f[" .. u(0x5D0) .. "-" .. u(0x5EA) .. "]"},
to = {u(0xFB21)},
},
}
m["arz"] = {
"tiếng Ả Rập Ai Cập",
29919,
"sem-arb",
"Arab",
"Tiếng Ả Rập Ai Cập",
"Ả Rập Ai Cập",
entry_name = "ar-entryname",
}
m["asa"] = {
"Pare",
36403,
"bnt-par",
"Latn",
}
m["asb"] = {
"tiếng Assiniboine",
2591288,
"sio-dkt",
"Latn",
"Tiếng Assiniboine",
"Assiniboine",
}
m["asc"] = {
"Casuarina Coast Asmat",
11732046,
"ngf",
"Latn",
}
m["ase"] = {
"ngôn ngữ ký hiệu Mỹ",
14759,
"sgn",
"Sgnw",
"Ngôn ngữ ký hiệu Mỹ",
"ngôn ngữ ký hiệu Mỹ",
}
m["asf"] = {
"Auslan",
29525,
"sgn",
"Latn", -- when documented
}
m["asg"] = {
"Cishingini",
35199,
"nic-kam",
"Latn",
}
m["ash"] = {
"Abishira",
2871740,
"qfa-iso",
"Latn",
}
m["asi"] = {
"Buruwai",
5001031,
"ngf",
"Latn",
}
m["asj"] = {
"Nsari",
36418,
"nic-bbe",
"Latn",
}
m["ask"] = {
"tiếng Ashkun",
29379,
"nur-sou",
"Arab, Latn",
"Tiếng Ashkun",
"Ashkun",
}
m["asl"] = {
"Asilulu",
12473347,
"poz-cma",
"Latn",
}
m["asn"] = {
"Xingú Asuriní",
8044571,
"tup-gua",
"Latn",
}
m["aso"] = {
"Dano",
5220979,
"paa-kag",
"Latn",
}
m["asp"] = {
"Algerian Sign Language",
3135421,
"sgn",
}
m["asq"] = {
"Austrian Sign Language",
36668,
"sgn",
"Latn", -- when documented
}
m["asr"] = {
"tiếng Asur",
3504321,
"mun",
"Deva, Latn",
"Tiếng Asur",
"Asur"
}
m["ass"] = {
"Ipulo",
35408,
"nic-tvc",
"Latn",
}
m["ast"] = {
"tiếng Asturias",
29507,
"roa-ibe",
"Latn",
"Tiếng Asturias",
"Asturias",
ancestors = "roa-ole",
}
m["asu"] = {
"Tocantins Asurini",
32041490,
"tup-gua",
"Latn",
}
m["asv"] = {
"Asoa",
56296,
"csu-maa",
"Latn",
}
m["asw"] = {
"Australian Aboriginal Sign Language",
955216,
"sgn",
"Latn", -- when documented
}
m["asx"] = {
"Muratayak",
11732766,
"ngf-fin",
"Latn",
}
m["asy"] = {
"Yaosakor Asmat",
16113158,
"ngf",
"Latn",
}
m["asz"] = {
"As",
2866218,
"poz-hce",
"Latn",
}
m["ata"] = {
"Pele-Ata",
56511,
"paa",
"Latn",
}
m["atb"] = {
"tiếng Zaiwa",
56594,
"tbq-brm",
"Latn, Lisu", -- also Hani?
"Tiếng Zaiwa",
"Zaiwa",
translit = {Lisu = "Lisu-translit"},
sort_key = {Lisu = s["Lisu-sortkey"]},
}
m["atc"] = {
"tiếng Atsahuaca",
4817730,
"sai-pan",
"Latn",
"Tiếng Atsahuaca",
"Atsahuaca",
}
m["atd"] = {
"Ata Manobo",
12627315,
"mno",
"Latn",
}
m["ate"] = {
"tiếng Atemble",
4813055,
"ngf-mad",
"Latn",
"Tiếng Atemble",
"Atemble",
}
m["atg"] = {
"Okpela",
7082551,
"alv-yek",
"Latn",
}
m["ati"] = {
"Attié",
34844,
"alv-lag",
"Latn",
}
m["atj"] = {
"tiếng Atikamekw",
56590,
"alg",
"Latn",
ancestors = "cr",
"Tiếng Atikamekw",
"Atikamekw",
}
m["atk"] = {
"Ati",
4815751,
"phi",
"Latn",
}
m["atl"] = {
"Mount Iraya Agta",
6921430,
"phi",
"Latn",
}
m["atm"] = {
"Ata",
4812603,
"phi",
"Latn",
}
m["ato"] = {
"Atong (Cameroon)",
34824,
"nic-grs",
"Latn",
}
m["atp"] = {
"Pudtol Atta",
12640726,
"phi",
"Latn",
}
m["atq"] = {
"Aralle-Tabulahan",
4783889,
"poz-ssw",
"Latn",
}
m["atr"] = {
"Waimiri-Atroari",
56865,
"sai-car",
"Latn",
}
m["ats"] = {
"Gros Ventre",
56628,
"alg-ara",
"Latn",
}
m["att"] = {
"Pamplona Atta",
12639245,
"phi",
"Latn",
}
m["atu"] = {
"Reel",
7306882,
"sdv-dnu",
"Latn",
}
m["atv"] = {
"tiếng Bắc Altai",
2640863,
"trk-ssb",
"Cyrl",
"Tiếng Bắc Altai",
"Bắc Altai",
translit = "Altai-translit",
}
m["atw"] = {
"Atsugewi",
56718,
"nai-pal",
"Latn",
}
m["atx"] = {
"Arutani",
56609,
nil,
"Latn",
}
m["aty"] = {
"Aneityum",
2379113,
"poz-oce",
"Latn",
}
m["atz"] = {
"Arta",
3508067,
"phi",
"Latn",
}
m["aua"] = {
"tiếng Asumboa",
4811870,
"poz-oce",
"Latn",
"Tiếng Asumboa",
"Asumboa",
}
m["aub"] = {
"Alugu",
12626798,
"tbq-urp",
"Latn", -- also Hani?
}
m["auc"] = {
"Huaorani",
758570,
"qfa-iso",
"Latn",
}
m["aud"] = {
"Anuta",
35326,
"poz-pnp",
"Latn",
}
m["aug"] = {
"Aguna",
34733,
"alv-gbe",
"Latn",
}
m["auh"] = {
"Aushi",
2872082,
"bnt-sbi",
"Latn",
}
m["aui"] = {
"tiếng Anuki",
3508132,
"poz-ocw",
"Latn",
"Tiếng Anuki",
"Anuki",
}
m["auj"] = {
"tiếng Awjila",
56398,
"ber",
"Latn, Arab, Tfng",
"Tiếng Awjila",
"Awjila",
}
m["auk"] = {
"Heyo",
3504295,
"qfa-tor",
"Latn",
}
m["aul"] = {
"Aulua",
427300,
"poz-vnc",
"Latn",
}
m["aum"] = {
"Asu",
34798,
"alv-ngb",
"Latn",
}
m["aun"] = {
"Molmo One",
12637224,
"qfa-tor",
"Latn",
}
m["auo"] = {
"Auyokawa",
56247,
"cdc-wst",
"Latn",
}
m["aup"] = {
"Makayam",
6738863,
"ngf",
"Latn",
}
m["auq"] = {
"Anus",
23855,
"poz-ocw",
"Latn",
}
m["aur"] = {
"Aruek",
3504279,
"qfa-tor",
"Latn",
}
m["aut"] = {
"Austral",
2669261,
"poz-pep",
"Latn",
}
m["auu"] = {
"Auye",
4827334,
"ngf",
"Latn",
}
m["auw"] = {
"Awyi",
3513326,
"paa-brd",
"Latn",
}
m["aux"] = {
"Aurá",
3507995,
"tup-gua",
"Latn",
}
m["auy"] = {
"Auyana",
2873211,
"paa-kag",
"Latn",
}
m["auz"] = {
"tiếng Ả Rập Uzbekistan",
3399507,
"sem-arb",
"Arab",
"Tiếng Ả Rập Uzbekistan",
"Ả Rập Uzbekistan",
entry_name = "ar-entryname",
}
m["avb"] = {
"Avau",
12627412,
"poz-ocw",
"Latn",
}
m["avd"] = {
"Alviri-Vidari",
3327357,
"xme",
"fa-Arab",
ancestors = "xme-mid",
}
m["avi"] = {
"Avikam",
34840,
"alv-lag",
"Latn",
}
m["avk"] = {
"tiếng Kotava",
1377116,
"art",
"Latn",
"Tiếng Kotava",
"Kotava",
type = "appendix-constructed",
}
m["avm"] = {
"Angkamuthi",
nil,
"aus-pmn",
"Latn",
}
m["avn"] = {
"tiếng Avatime",
34796,
"alv-ktg",
"Latn",
"Tiếng Avatime",
"Avatime",
}
m["avo"] = {
"Agavotaguerra",
3508007,
"awd",
"Latn",
}
m["avs"] = {
"Aushiri",
3409318,
"sai-zap",
"Latn",
}
m["avt"] = {
"Au",
3446608,
"qfa-tor",
"Latn",
}
m["avu"] = {
"tiếng Avokaya",
56685,
"csu-mma",
"Latn",
"Tiếng Avokaya",
"Avokaya",
}
m["avv"] = {
"Avá-Canoeiro",
4829584,
"tup-gua",
"Latn",
}
m["awa"] = {
"tiếng Awadh",
29579,
"inc-hie",
"Deva, Kthi, fa-Arab",
"Tiếng Awadh",
"Awadh",
translit = {Deva = "hi-translit"},
}
m["awb"] = {
"Awa (New Guinea)",
2874650,
"paa-kag",
"Latn",
}
m["awc"] = {
"Cicipu",
35193,
"nic-kam",
"Latn",
}
m["awe"] = {
"Awetí",
4830038,
"tup",
"Latn",
}
m["awg"] = {
"tiếng Anguthimri",
4764288,
"aus-pam",
"Latn",
"Tiếng Anguthimri",
"Anguthimri",
}
m["awh"] = {
"Awbono",
3446684,
"ngf",
"Latn",
}
m["awi"] = {
"Aekyom",
3399691,
"ngf",
"Latn",
}
m["awk"] = {
"Awabakal",
3449138,
"aus-pam",
"Latn",
}
m["awm"] = {
"Arawum",
4784537,
"ngf-mad",
"Latn",
}
m["awn"] = {
"tiếng Awngi",
34934,
"cus-cen",
"Ethi",
"Tiếng Awngi",
"Awngi",
}
m["awo"] = {
"Awak",
3446643,
"alv-wjk",
"Latn",
}
m["awr"] = {
"Awera",
56379,
"paa-lkp",
"Latn",
}
m["aws"] = {
"South Awyu",
12633986,
"ngf",
"Latn",
}
m["awt"] = {
"tiếng Araweté",
4784535,
"tup-gua",
"Latn",
"Tiếng Araweté",
"Araweté",
}
m["awu"] = {
"Central Awyu",
12628801,
"ngf",
"Latn",
}
m["awv"] = {
"Jair Awyu",
16110177,
"ngf",
"Latn",
}
m["aww"] = {
"Awun",
56369,
"paa-spk",
"Latn",
}
m["awx"] = {
"Awara",
2874670,
"ngf-fin",
"Latn",
}
m["awy"] = {
"Edera Awyu",
12630425,
"ngf",
"Latn",
}
m["axb"] = {
"Abipon",
11252539,
"sai-guc",
"Latn",
}
m["axe"] = {
"Ayerrerenge",
16112737,
"aus-pam",
"Latn",
}
m["axg"] = {
"Mato Grosso Arára",
3446660,
nil,
"Latn",
}
m["axk"] = {
"Aka (Central Africa)",
11010149,
"bnt-ngn",
"Latn",
}
m["axl"] = {
"Lower Southern Aranda",
6693295,
"aus-pam",
"Latn",
}
m["axm"] = {
"tiếng Armenia trung đại",
4438498,
"hyx",
"Armn",
"Tiếng Armenia trung đại",
"Armenia trung đại",
ancestors = "xcl",
-- Chuyển tự Armn đã có sẵn ở [[Mô đun:scripts/data]]
override_translit = true,
strip_diacritics = {
remove_diacritics = "՞՜՛՟",
from = {"եւ", "ՙ", "՚"},
to = {"և", "ʻ", "’"}
}
}
m["axx"] = {
"Xaragure",
8045635,
"poz-cln",
"Latn",
}
m["aya"] = {
"Awar",
56876,
"paa",
"Latn",
}
m["ayb"] = {
"Ayizo",
34841,
"alv-pph",
"Latn",
}
m["ayd"] = {
"Ayabadhu",
3509164,
"aus-pmn",
"Latn",
}
m["aye"] = {
"tiếng Ayere",
34788,
"alv-aah",
"Latn",
"Tiếng Ayere",
"Ayere",
}
m["ayg"] = {
"Nyanga (Togo)",
35446,
"alv-gng",
"Latn",
}
m["ayi"] = {
"Leyigha",
3914492,
"nic-uce",
"Latn",
}
m["ayk"] = {
"tiếng Akuku",
3450179,
"alv-nwd",
"Latn",
}
m["ayl"] = {
"tiếng Ả Rập Libya",
56503,
"sem-arb",
"Arab",
strip_diacritics = "ar-stripdiacritics",
}
m["ayn"] = {
"tiếng Ả Rập Sana'a",
1686766,
"sem-arb",
"Arab, Hebr",
strip_diacritics = {
Arab = "ar-stripdiacritics",
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["ayo"] = {
"Ayoreo",
56634,
"sai-zam",
"Latn",
}
m["ayp"] = {
"tiếng Ả Rập Bắc Lưỡng Hà",
56577,
"sem-arb",
"Arab",
"Tiếng Ả Rập Bắc Lưỡng Hà",
"Ả Rập Bắc Lưỡng Hà",
ancestors = "acm",
entry_name = "ar-entryname",
}
m["ayq"] = {
"Ayi",
56449,
"paa-spk",
"Latn",
}
m["ays"] = {
"Sorsogon Ayta",
7563752,
"phi",
"Latn",
}
m["ayt"] = {
"Bataan Ayta",
4921648,
"phi",
"Latn",
}
m["ayu"] = {
"tiếng Ayu",
34786,
"alv",
"Latn",
}
m["ayy"] = {
"Tayabas Ayta",
7689745,
"phi",
"Latn",
}
m["ayz"] = {
"Maybrat",
4830892,
"paa-wpa",
"Latn",
}
m["aza"] = {
"Azha",
4832486,
"tbq-axi",
"Latn",
}
m["azd"] = {
"Eastern Durango Nahuatl",
16115449,
"azc-nah",
"Latn",
}
m["azg"] = {
"San Pedro Amuzgos Amuzgo",
35092,
"omq",
"Latn",
}
m["azm"] = {
"Ipalapa Amuzgo",
12633013,
"omq",
"Latn",
}
m["azn"] = {
"Western Durango Nahuatl",
12645553,
"azc-nah",
"Latn",
}
m["azo"] = {
"tiếng Awing",
34856,
"nic-nge",
"Latn",
"Tiếng Awing",
"Awing",
}
m["azt"] = {
"Faire Atta",
12630884,
"phi",
"Latn",
}
m["azz"] = {
"Highland Puebla Nahuatl",
12953754,
"azc-nah",
"Latn",
}
return require("Module:languages").finalizeData(m, "language")
861pltuuriqj8x612j8uu3t0ylp36f6
Mô đun:headword utilities
828
270803
2573055
2568724
2026-10-23T16:03:23Z
TheHighFighter2
42988
2573055
Scribunto
text/plain
local export = {}
--[==[
FIXME:
1. Implement ? = unknown or uncertain. There should be no label by default but it should be configurable.
The default category should be "{plpos} with unknown or uncertain plurals" for nouns/proper nouns. It should
be an error to specify values along with this.
2. Implement ! = unattested. The default label should be "{label} not attested". The default category should be
"{plpos} with unattested plurals" for nouns/proper nouns. It should be an error to specify values along with
this.
3. Implement +- = sometimes has a value, e.g. "countable and uncountable" for plurals.
4. Implement ~ standing for the pagename in heads and inflections. [DONE]
5. Implement abbr= for abbreviations. [DONE]
6. Extract from insert_inflection the logic to handle the special mode signals, determine the actual label and
category and the actual values without inserting them.
7. Support no_label for booleans.
8. Document the various types of parts of speech and implement pos_category per part of speech definition. [DONE]
9. Implement apply_link_modifiers() for head=~...
10. Correctly handle var=both. [DONE]
11. Implement checkredlinks and port simplify_pos to [[Module:headword]].
12. Fix longstanding accelerator bug: if embeddded links in inflection, don't make it green.
]==]
local require_when_needed = require("Module:utilities/require when needed")
local affix_module = "Module:affix"
local debug_track_module = "Module:debug/track"
local decorations_module = "Module:decorations"
local en_utilities_module = "Module:en-utilities"
local fun_is_callable_module = "Module:fun/isCallable"
local headword_module = "Module:headword"
local headword_data_module = "Module:headword/data"
local languages_module = "Module:languages"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local parse_interface_module = "Module:parse interface"
local parse_utilities_module = "Module:parse utilities"
local string_pattern_escape_module = "Module:string/patternEscape"
local string_replacement_escape_module = "Module:string/replacementEscape"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local yesno_module = "Module:yesno"
local dump = mw.dumpObject
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local insert = table.insert
local concat = table.concat
local remove = table.remove
local sort = table.sort
local deep_equals = require_when_needed(table_module, "deepEquals")
local extend = require_when_needed(table_module, "extend")
local insert_if_not = require_when_needed(table_module, "insertIfNot")
local list_to_set = require_when_needed(table_module, "listToSet")
local serial_comma_join = require_when_needed(table_module, "serialCommaJoin")
local shallow_copy = require_when_needed(table_module, "shallowCopy")
local split = require_when_needed(string_utilities_module, "split")
local ugsub = require_when_needed(string_utilities_module, "gsub")
local umatch = require_when_needed(string_utilities_module, "match")
local pattern_escape = require_when_needed(string_pattern_escape_module)
local replacement_escape = require_when_needed(string_replacement_escape_module)
local escape_wikicode = require_when_needed(parse_utilities_module, "escape_wikicode")
local parse_inline_modifiers = require_when_needed(parse_utilities_module, "parse_inline_modifiers")
local term_contains_top_level_html = require_when_needed(parse_utilities_module, "term_contains_top_level_html")
local get_lang_by_code = require_when_needed(languages_module, "getByCode")
local is_callable = require_when_needed(fun_is_callable_module)
local format_decorations = require_when_needed(decorations_module, "format_decorations")
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
--[==[ intro:
This module contains utilities for constructing language-specific headword modules.
[fill in]
===About parts of speech===
There are several versions of the part of speech (POS) of a given term:
* The ''primary categorizing POS'' is the basic part of speech to which a term belongs. The primary POS determines
whether the term is a lemma or non-lemma form, and in its plural form, it is used to categorize the terms (unless it
is a variant term), along with caetegorizing into a ''lemmas'' or ''non-lemma forms'' category. (Variant terms,
typically marked by {{para|var|1}}, are categorized into ''variant lemmas'' or ''variant non-lemma forms'' and are not
categorized into a primary POS category.)
* The ''raw {{tl|head}} POS'' is parameter {{para|2}} to {{tl|head}}. This is used to determine the primary categorizing
POS by a process of canonicalization, because this parameter may contain abbreviations (e.g. ''a'' or ''adj'' for an
adjective) and may be (and usually is) given in its singular form.
* The ''template-indicated POS'' is the part of speech indicated by a headword template such as {{tl|nl-noun}} or
{{tl|mn-head}}. It is either inherent to the template (in a case like {{tl|nl-noun}}), in which case it is specified
by the template code and should always be in canonical, plural form; or it is specified by the user in the template
call (in a case like {{tl|mn-head}} or other generic POS template, usually ending in `-head`), in which case it may
be given in raw form, like for the raw {{tl|head}} POS, and is canonicalized using the same code that canonicalizes
raw {{tl|head}} parts of speech. The template-indicate POS may not be a valid primary categorizing POS. For example,
Dutch has a template-indicated POS ''diminutiva tantum nouns'', specified through the template {{tl|nl-dim-tant}}, but
there is no such primary categorizing POS (that POS would be `nouns`). Similarly, Arabic has a template-indicated POS
''collective nouns'', whose primary categorizing POS is also `nouns`. As a result, the template-indicated POS may need
to be converted to a primary categorizing POS through a ''normalization'' process (which uses a `pos_category` field
attached to the `pos_functions` structure for the template-indicated POS). Note that the template-indicated POS comes
in several variants:
*# It may be ''head-raw'', meaning that it uses the literal string `head` in place of the user-specified POS in a
generic POS template like {{tl|mn-head}}; it may be ''non-head'', meaning that it uses the actual user-specified
POS in such a case; or it may be ''head-augmented'', meaning that in the case of a generic POS template it is of the
form e.g. `head.nouns`, contanining both the literal `head` and the user-specified POS.
*# It may be ''suffix-raw'', meaning that it uses the primary categorizing POS `suffixes` in place of the
template-indicated POS when the term is a suffix, or it may be ''non-suffix'', meaning that it uses the
template-indicated POS in such a case. The headword for a suffix uses the template corresponding to whatever POS the
suffix forms, e.g. {{nl-noun}} for Dutch noun-forming suffixes.
*# The ''indexing POS'' is the variant of the template-indicated POS that is used to index into the `pos_functions`
table. Normally it is head-raw and non-suffix, but it will be head-augmented if the corresponding head-augmented
entry exists in `pos_functions`.
*# The ''unnormalized categorizing POS'' is the variant of the template-indicated POS that is potentially usable as the
primary categorizing POS (see above). It is non-head and suffix-raw, i.e. it uses the actual template-specified or
user-specified form of the template-indicated POS except when the term is a suffix, in which case it has the value
`suffixes`. In most circumstances this can be used directly as the primary categorizing POS, but in some cases this
POS is not a valid primary categorizing POS and needs to be normalized to get the actual primary categorizing POS, as
mentioned above under the description for the template-indicated POS.
* Finally, there is a ''simplified categorizing POS''. This collapses variations of primary categorizing parts of speech
together for use in red-link and similar categories. For example, the POS `proper nouns` is collapsed into `nouns`,
and all types of participles are collapsed into `participles`. There are two variants of the simplification process,
''lemma-status-preserving'' and ''non-lemma-status-preserving''. The latter is the default and is simpler, in that
e.g. it means any part of speech ending in `nouns` to `nouns`, even if this causes non-lemma forms to become lemmas,
as with `diminutive nouns` and `verbal nouns` (which are non-lemma forms) and likewise with `comparative adjectives`
and `superlative adjectives` (which are again non-lemma forms). The former, ''lemma-status-preserving'', keeps lemmas
as lemmas and (more important) non-lemmas as non-lemmas by converting e.g. `diminutive nouns` and `verbal nouns` to
`noun forms` rather than `nouns`. The reason two variants exist in that they have different use cases. The default,
non-lemma-status-preserving, type is used for tracking categories such as red-link and request categories, where
completeness is more important than clutter. The lemma-status-preserving variant is used for informative categories
such as ` ``lang`` masculine nouns`, which should only have lemmas in them to avoid clutter. (For the same reason,
variant terms specified using {{para|var|1}} aren't normally categorized into informative categories but are placed
in tracking categories.)
===About properties and data objects===
[fill in]
]==]
--[=[
Add decorations to a term. `termobj` is the object describing the term, which should optionally contain:
* left qualifiers in `q`, an array of strings;
* right qualifiers in `qq`, an array of strings;
* left labels in `l`, an array of strings;
* right labels in `ll`, an array of strings;
* references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text`
(formatted reference text) and optionally `name` and/or `group`;
`text` is the text of the term itself, and `lang` is the language object.
]=]
local function add_decorations(text, termobj, lang)
local function field_non_empty(field)
local list = termobj[field]
if not list then
return nil
end
if type(list) ~= "table" then
error(("Internal error: Wrong type for `termobj.%s`=%s, should be \"table\""):format(
field, mw.dumpObject(list)))
end
return list[1]
end
if field_non_empty("q") or field_non_empty("qq") or field_non_empty("l") or field_non_empty("ll") or
field_non_empty("refs") then
text = format_decorations {
lang = lang,
text = text,
q = termobj.q,
qq = termobj.qq,
l = termobj.l,
ll = termobj.ll,
refs = termobj.refs,
}
end
return text
end
local param_mods = {
alt = {}, -- always allow so e.g. - can be specified as a suffix form
id = {}, -- disabled when `is_head = true`
q = {type = "qualifier"},
qq = {type = "qualifier"},
l = {type = "labels"},
ll = {type = "labels"},
-- [[Module:headword]] expects part references in `.refs`.
ref = {item_dest = "refs", type = "references", store = "insert-flattened"},
}
local optional_param_mods = {
g = {item_dest = "genders", type = "genders"},
lang = {type = "language"},
sc = {type = "script"},
t = {item_dest = "gloss"},
gloss = {},
pos = {},
lit = {},
tr = {},
ts = {},
face = {},
nolinkinfl = {type = "boolean"},
}
local optional_headword_param_mods = {
sc = {type = "script"},
tr = {},
ts = {},
}
--[==[
Parse a single inflection or headword form or list of such forms. In either case, inline modifiers may be attached.
`data` is an object with the following fields:
* `val`: The raw value to parse. Required.
* `paramname`: The name of the parameter from which the value was taken; used in error messages. Required.
* `is_head`: We are parsing a headword parameter (a value which goes into the `heads` field of `data`). This changes
the allowed modifiers, disabling the `id` modifier and only allowing a subset of optional modifiers.
* `frob`: An optional function of one value to apply to the form after inline modifiers have been removed (i.e. to
apply to the `.term` field of the returned object).
* `include_mods`: List of extra inline modifiers to include, besides the default ones (see below). Each list item is
either a string specifying a recognized extra inline modifier (see `optional_param_mods` in the code), or a two-item
list of modifier name and modifier spec, where the spec should follow the syntax for modifier specs in
`parse_inline_modifiers` in [[Module:parse utilities]].
* `exclude_mods`: List of default inline modifiers to not include.
* `splitchar`: If specified, the value in `val` can be a list of forms to parse, separated by the value of `splitchar`
(which is a Lua pattern, as in `parse_inline_modifiers` in [[Module:parse utilities]]). Most commonly, `splitchar` is
a single comma and the values are comma-separated (in this case, splitting will not happen if a space follows the
comma).
* `parse_lang_prefix`: If specified, allow a language prefix to precede a form, and if found, store into the `.lang`
field of the returned object.
* `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in
`parse_inline_modifiers` in [[Module:parse utilities]].
Returns an object suitable for storing as one element of one of the lists in `headdata.inflections`, where `headdata`
is the structure passed to [[Module:headword]]. If `splitchar` is specified, howeve, the return value is a list of such
objects.
The following default inline modifiers are currently recognized:
* `q`: Left qualifier.
* `qq`: Right qualifier.
* `l`: Comma-separated list of left labels. No space should follow the comma.
* `ll`: Comma-separated list of right labels. No space should follow the comma.
* `ref`: Reference or references. See {{tl|IPA}} for the syntax.
* `id`: Sense ID, in case there are multiple senses. See {{tl|l}}.
The following are the recognized additional inline modifiers:
* `g`: Comma-separated list of genders.
* `alt`: Display text.
* `lang`: Language code of language of the form, if different from the language of the headword.
* `sc`: Script code of script of the form. Almost never needed.
* `t`: Gloss for the form.
* `gloss`: Gloss for the form (alias for `t`).
* `pos`: Part of speech of the form.
* `lit`: Literal meaning of the form.
* `tr`: Manual transliteration of the form.
* `ts`: Transcription of the form, for languages where the transliteration differs markedly from the pronunciation.
* `face`: Face to display the form in, e.g. {"hypothetical"} for a hypothetical form (unlinkable and displayed in italics).
* `nolinkinfl`: Make the form unlinkable.
]==]
function export.parse_term_with_modifiers(data)
local paramname, val, frob = data.paramname, data.val, data.frob
local function generate_obj(term, parse_err)
if frob then
term = frob(term, parse_err)
end
if data.parse_lang_prefix and term:find(":") then
return require(parse_utilities_module).generate_obj_maybe_parsing_lang_prefix {
term = term,
paramname = paramname,
parse_lang_prefix = true,
parse_err = parse_err,
}
else
return {term = term}
end
end
-- Check for inline modifier, e.g. מרים<tr:Miryem>. But exclude top-level HTML entry with <span ...>,
-- <sup> or similar in it.
if (val:find("<", nil, true) or data.splitchar) and not term_contains_top_level_html(val) and
-- don't parse inline modifiers if is_head and the value begins with a ~ (link modifier syntax)
(not data.is_head or not val:find("^~")) then
local param_mods = param_mods
if data.is_head then
param_mods = shallow_copy(param_mods)
param_mods.id = nil
end
if data.include_mods or data.exclude_mods then
if not data.is_head then
-- already copied when data.is_head
param_mods = shallow_copy(param_mods)
end
if data.include_mods then
local optional_mods = data.is_head and optional_headword_param_mods or optional_param_mods
for _, mod in ipairs(data.include_mods) do
if type(mod) == "table" then
if #mod ~= 2 then
error(("Internal error: Modifier spec %s in `include_mods` should be of length 2"):format(
dump(mod)))
end
local modkey, modvalue = unpack(mod)
param_mods[modkey] = modvalue
elseif not optional_mods[mod] then
error(("Internal error: Unrecognized modifier spec %s in `include_mods`"):format(
dump(mod)))
else
param_mods[mod] = optional_mods[mod]
end
end
end
if data.exclude_mods then
for _, mod in ipairs(data.exclude_mods) do
if not param_mods[mod] then
error(("Internal error: Modifier spec %s in `exclude_mods` not found among existing modifiers"
):format(dump(mod)))
else
param_mods[mod] = nil
end
end
end
end
return parse_inline_modifiers(val, {
paramname = paramname,
param_mods = param_mods,
generate_obj = generate_obj,
splitchar = data.splitchar,
preserve_splitchar = data.preserve_splitchar,
delimiter_key = data.delimiter_key,
escape_fun = data.escape_fun,
unescape_fun = data.unescape_fun,
pre_normalize_modifiers = data.pre_normalize_modifiers,
})
else
local retval = generate_obj(val)
if data.splitchar then
retval = {retval}
end
return retval
end
end
--[==[
Parse a list of inflection forms that may have inline modifiers attached. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. Required.
* `paramname`: The name of the first parameter from which the value was taken; used in error messages. If this is a
two-element list, the first element is the first parameter and the second element is the prefix of the remaining
parameters. Parameter names that are numbers are handled correctly, as are those with \1 in it marking where the
parameter index goes. Required.
* `qualifiers`: If specified, a possibly gappy list of left qualifiers to add to the parsed terms (for compatibility
purposes).
* `splitchar`: As in `parse_term_with_modifiers()`. The resulting per-term lists will be flattened.
* `frob`, `include_mods`, `exclude_mods`, `is_head`, `preserve_splitchar`, `parse_lang_prefix`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_with_modifiers()`.
Returns a list of objects, suitable for storing as one of the lists in `headdata.inflections` (once a label is added),
where `headdata` is the structure passed to [[Module:headword]].
]==]
function export.parse_term_list_with_modifiers(data)
local paramname, forms = data.paramname, data.forms
local qualifiers = data.qualifiers
local first, restpref
if type(paramname) == "table" then
first = paramname[1]
restpref = paramname[2]
else
first = paramname
restpref = paramname
end
local terms = {}
data = shallow_copy(data)
for i, val in ipairs(forms) do
data.paramname = i == 1 and first or type(restpref) == "number" and restpref + i - 1 or
restpref:find("\1", nil, true) and restpref:gsub("\1", tostring(i)) or restpref .. i
data.val = val
local parsed = export.parse_term_with_modifiers(data)
if qualifiers and qualifiers[i] then
if data.splitchar then
for _, term in ipairs(parsed) do
term.q = {qualifiers[i]}
end
else
parsed.q = {qualifiers[i]}
end
end
if data.splitchar then
extend(terms, parsed)
else
terms[i] = parsed
end
end
return terms
end
--[==[
Construct a link to [[Appendix:Glossary]] for `entry`. If `text` is specified, it is the display text; otherwise,
`entry` is used.
]==]
function export.glossary_link(entry, text)
text = text or entry
return "[[Phụ lục:Từ điển thuật ngữ#" .. entry .. "|" .. text .. "]]"
end
function export.replace_glossary_links_in_label(label)
if label:find("<<", nil, true) then
label = label:gsub("<<(.-)|(.-)>>", export.glossary_link):gsub("<<(.-)>>", export.glossary_link)
end
return label
end
-- If a part of speech ends with one of these, either pluralized or followed by ' forms', chop off whatever precedes.
-- Also, if a part of speech is of the form `BASIC_POS FOO forms` e.g. `noun construct forms`, remove the `FOO`
-- portion. Note that "phrase" is *NOT* listed here because 'prepositional phrase' and 'postpositional phrase' are not
-- types of 'phrase' per the definition of these parts of speech in Wiktionary.
local basic_poses = {
"Tính từ",
"Phó từ",
"Từ rút gọn",
"Danh từ riêng",
"Danh từ",
"Phân từ",
"Đại từ",
"Ký hiệu",
"Động từ",
}
--[==[
Canonicalize and then simplify a part of speech by removing adjectival qualifiers. This converts e.g.
`proper noun(s)` -> `nouns`, `comparative adjective(s)` -> `adjectives`, `past participle form(s)` -> `participle forms`
and `pronoun possessive form(s)` -> `pronoun forms`. (The one exception is with phrases. In Wiktionary, ''phrase''
really means a clause or similar constituent or occasionally non-constituent, so `prepositional phrases` are not types
of `phrases`.) Its purpose is for use in categorization, since generally the simplified part of speech is used in
categories other than the one for the part of speech itself. (For example, proper nouns are normally categorized under
` ``lang`` nouns with ...` rather than ` ``lang`` proper nouns with ...`.) The returned part of speech is in plural
form.
]==]
local function optimized_pattern_escape(pos)
if pos:find("-", nil, true) then
return pattern_escape(pos)
else
return pos
end
end
--[==[
Convert a qualified part of speech (e.g. ''proper nouns'', ''past participles'') to its unqualified equivalent (e.g.
''nouns'' or ''participles''). If `preserve_proper_nouns` is given, ''proper nouns'' is left as-is rather than being
converted to ''nouns''. If `preserve_lemma_status` is given, the function attempts to return a POS that has the same
lemma status (lemma or non-lemma form) as the original POS; thus, ''comparative adjectives'' becomes ''adjective forms''
and ''diminutive nouns'' becomes ''noun forms'' because both are non-lemma forms. If `preserve_lemma_status` is not
given, the function simply chops off the qualifiers, converting e.g. ''comparative adjectives'' to ''adjectives'' even
though this changes the lemma status of the POS.
]==]
function export.simplify_pos(pos, preserve_lemma_status, preserve_proper_nouns)
-- This allows for both singular and plural parts of speech in 'pos'.
local plpos = require(headword_module).canonicalize_pos(pos)
for _, basic_pos in ipairs(basic_poses) do
if basic_pos ~= "Danh từ riêng" or preserve_proper_nouns then
if plpos == "Biến thể hình thái " .. basic_pos then
-- So 'proper noun forms' doesn't get converted to 'noun forms' in the next round
return plpos
end
local basic_pos_pattern = optimized_pattern_escape(basic_pos)
if plpos:find(("^Biến thể hình thái %s .*.$"):format(basic_pos_pattern)) then
return "Biến thể hình thái " .. basic_pos
end
if plpos:find(("^.* %s forms$"):format(basic_pos_pattern)) then
return basic_pos .. " forms"
end
local pl_basic_pos = require(headword_module).pluralize_pos(basic_pos)
if plpos == pl_basic_pos then
-- So 'proper nouns' doesn't get converted to 'nouns' in the next round
return plpos
end
local pl_basic_pos_pattern = optimized_pattern_escape(pl_basic_pos)
if plpos:find(("^.* %s$"):format(pl_basic_pos_pattern)) then
if preserve_lemma_status then
local lemma_status = require(headword_module).pos_lemma_or_nonlemma(plpos)
if lemma_status == "non-lemma form" then
return "Biến thể hình thái " .. basic_pos
end
end
return pl_basic_pos
end
end
end
return plpos
end
--[==[
Insert a fixed inflection (a label not associated with any inflection values) into an `inflections` field. The
`inflections` field will be initialized if needed. `data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `originating_term`: The term object from which this label is derived. If specified, decorations will be taken from
this object.
]==]
function export.insert_fixed_inflection(data)
local headdata, origterm, label = data.headdata, data.originating_term, data.label
local inflobj = data.inflobj or headdata
inflobj.inflections = inflobj.inflections or {}
if not origterm then
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label)
})
else
if origterm.id then
error(("It doesn't make sense to pass in an ID '%s' for label '%s' in conjunction with a term value '%s'"
):format(origterm.id, label, origterm.term))
end
origterm = shallow_copy(origterm)
-- Preserve decorations
origterm.term = nil
origterm.label = export.replace_glossary_links_in_label(label)
insert(inflobj.inflections, origterm)
end
end
--[==[
Insert previously-parsed terms into an `inflections` field. The `inflections` field will be initialized if needed.
`data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `terms`: The list of parsed terms. If {nil} or omitted, nothing happens unless `request` is set.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `fixed_adj_label`: If specified, an adjective used to construct the defaults for the fixed labels specified by
`no_label`, `usually_no_label` and `sometimes_label`. Examples are "comparable" for a comparative and "countable"
for a plural.
* `no_label`: If the term is {"-"} and there are no other terms, insert a fixed label with this value. If
`fixed_adj_label` is given, defaults to {"not "} plus the adjective, else {"no "} plus the label.
* `usually_no_label`: If the term is {"-"} and there are other terms, insert a fixed label with this value. Defaults to
{"usually "} plus the value of `no_label`.
* `sometimes_label`: If the term is {"+-"}, insert a fixed label with this value. If `fixed_adj_label` is given,
defaults to {"sometimes "} plus the adjective, else {"sometimes with a(n) "} plus the label.
* `cats`: List of categories to insert when terms are given that are not {"-"}. Each category is a string naming a full
category to insert (including the appropriate language name prefixed).
* `no_cats`: List of categories to insert when a term is given as {"-"}.
* `usually_no_cats`: List of categories to insert when a term is given as {"-"} and additional terms are specified as
well (representing, e.g. for the inflection {"plural"}, a term which usually has no plural but does under some
circumstances). If omitted, both the categories in `cats` and `no_cats` are inserted.
* `sometimes_cats`: List of categories to insert when a term is given as {"+-"} (indicating that the inflection
sometimes exists and sometimes does not, normally depending on the precise sense involved). If omitted, both the
categories in `cats` and `no_cats` are inserted (same default as for `usually_no_cats`).
* `accel`: If specified, a full accelerator object to add to the inflections.
* `request`: If specified and no terms are given, insert a label with a request for inflections to be given.
* `enable_auto_translit`: If specified and terms are given, display automatic transliteration of the terms.
The return value indicates whether the inflection exists and how many terms are in it. It is an object with the
following fields:
* `exists`: {"yes"} if one or more terms were specified; {"no"} if the value was given as {"-"}; {"usually no"} if
the first value was given as {"-"} but additional terms were supplied; otherwise {nil}, indicating that the status
is unspecified.
* `numterms`: Number of terms in the inflection. Will be 0 unless `exists` has the value {"yes"} or {"usually no"}.
* `terms`: The terms that were inserted. If there are no terms, this is an empty list.
* `request`: True if no terms were specified but a term request was inserted into the inflection (because
`data.request` was specified). Otherwise {nil}.
]==]
function export.insert_inflection(data)
local headdata, terms, label = data.headdata, data.terms, data.label
local inflobj = data.inflobj or headdata
local retval = {}
local accel = data.accel
if data.accel_form then
if accel then
error("Internal error: can't specify both data.accel and data.accel_form")
end
if headdata.heads then
local lemmas = {}
local lemma_translits = {}
for i, headobj in ipairs(headdata.heads) do
lemmas[i] = headobj.term
if lemmas[i] == "+" then
error("Internal error: If you use data.accel_form, you should have resolved all occurrences of + in heads appropriately")
end
lemma_translits[i] = headobj.tr
end
accel = {
lemma = lemmas,
lemma_translit = lemma_translits,
form = data.accel_form,
}
else
accel = {
form = data.accel_form,
}
end
end
local function insert_cats(cats)
for _, cat in ipairs(cats) do
insert(headdata.categories, cat)
end
end
if terms and terms[1] then
terms = shallow_copy(terms)
if terms[1].term == "-" then
if terms[2] then
export.insert_fixed_inflection {
headdata = headdata,
inflobj = inflobj,
originating_term = terms[1],
label = data.usually_no_label or "thường không " .. label,
}
remove(terms, 1)
retval.numterms = #terms
retval.exists = "thường không"
if data.usually_no_cats then
insert_cats(data.usually_no_cats)
else
if data.no_cats then
insert_cats(data.no_cats)
end
if data.cats then
insert_cats(data.cats)
end
end
else
export.insert_fixed_inflection {
headdata = headdata,
inflobj = inflobj,
originating_term = terms[1],
label = data.no_label or "không " .. label,
}
retval.numterms = 0
retval.terms = {}
retval.exists = "không"
if data.no_cats then
insert_cats(data.no_cats)
end
return retval
end
else
retval.numterms = #terms
retval.exists = "có"
if data.cats then
insert_cats(data.cats)
end
end
if data.check_missing then
error("Internal error: check_missing support removed; use checkredlinks=true in [[Module:headword]]")
end
terms.label = export.replace_glossary_links_in_label(label)
if accel then
terms.accel = accel
end
terms.enable_auto_translit = data.enable_auto_translit
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, terms)
retval.terms = terms
elseif data.request then
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label),
request = true,
})
retval.numterms = 0
retval.terms = {}
-- retval.exists = nil
retval.request = true
else
retval.numterms = 0
retval.terms = {}
-- retval.exists = nil
end
return retval
end
--[==[
Parse raw arguments from `forms` for inline modifiers, and insert the resulting terms (which should not require
significant additional processing) into `headdata.inflections`. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. If {nil} or omitted, nothing happens.
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `paramname`: As in `parse_term_list_with_modifiers()`. Required.
* `label`: As in `insert_inflection()`. Required.
* `qualifiers`, `frob`, `include_mods`, `exclude_mods`, `is_head`, `splitchar`, `preserve_splitchar`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_list_with_modifiers()`.
* `accel`: As in `insert_inflection()`.
Return value is as in `insert_inflection()`.
]==]
function export.parse_and_insert_inflection(data)
local forms = data.forms
if forms and forms[1] then
data = shallow_copy(data)
data.forms = forms
data.terms = export.parse_term_list_with_modifiers(data)
return export.insert_inflection(data)
end
return {
numterms = 0
}
end
--[==[
Canonicalize a single term or term-like object or a list of either into a list of term-like objects. `abterms` is the
term or list to canonicalize, and `field` is the name of the field holding the term (defaulting to {"term"}). This
does the minimal work necessary, meaning that the return value may partly or completely share memory with the value
passed in. As a special case, if `abterms` is {nil}, {nil} is returned. If `origin` or `originating_term` are specified,
add fields `origin` and/or `originating_term` containing the specified value(s) to each resulting term-like object (in
this case, the object will be copied a necessary to avoid side-effecting the passed-in objects). `origin` is intended to
be a string indicating where the term originated from (e.g. {"default"} if a default value, {"resolve_special"} if
originating from a shortcut value such as {"+"}) and `originating_term` is the shortcut term itself, if any. (There is
generally no such term for default values.)
]==]
function export.canonicalize_termobj_list(abterms, field, origin, originating_term)
if abterms == nil then
return nil
end
field = field or "term"
if type(abterms) == "string" then
return {{[field] = abterms, origin = origin, originating_term = originating_term}}
elseif not abterms[1] then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy(abterms)
abterms.origin = origin
abterms.originating_term = originating_term
end
return {abterms}
else
-- Check if already in full list term and return directly if so (unless `origin_val` is given, in which case we
-- need to shallow-copy both the list and each term in it).
local must_convert = false
for _, term in ipairs(abterms) do
if type(term) == "string" then
must_convert = true
break
end
end
if not must_convert then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy(abterms)
for i, abterm in ipairs(abterms) do
abterms[i] = shallow_copy(abterm)
abterms[i].origin = origin
abterms[i].originating_term = originating_term
end
end
return abterms
end
end
local retval = {}
for _, term in ipairs(abterms) do
if type(term) == "string" then
insert(retval, {[field] = term, origin = origin, originating_term = originating_term})
else
if origin ~= nil or originating_term ~= nil then
term = shallow_copy(term)
term.origin = origin
term.originating_term = originating_term
end
insert(retval, term)
end
end
return retval
end
--[==[
Combine two sets of decorations. If either is {nil}, just return the other, and if both are {nil}, return {nil}.
]==]
function export.combine_decorations(decs1, decs2)
if not decs1 and not decs2 then
return nil
end
if not decs1 then
return decs2
end
if not decs2 then
return decs1
end
local combined = shallow_copy(decs1)
for _, dec in ipairs(decs2) do
insert_if_not(combined, dec)
end
return combined
end
function export.combine_qualifiers_or_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng combine_decorations")
end
--[==[
Combine the decorations (qualifiers, labels, references) and ID's of two term objects. `destobj` is the "destination
term object" into which the combined properties are written, and `srcobj` is the "source object" into which the
properties are merged. `destobj` is side-effected (but the lists inside of `destobj` are not); if this is undesirable,
make sure to shallow-copy `destobj` first. If both objects have values for a given decoration, the values of `destobj`
come first. If both objects have a value for `id`, the values must match or an error is thrown; otherwise, the resulting
value of `id` comes from whichever one is defined.
'''NOTE:''' This may not be the correct behavior when deduplicating a list of term objects. See
`insert_termobj_combining_duplicates` for a different approach.
]==]
function export.combine_termobj_decorations(destobj, srcobj)
destobj.q = export.combine_decorations(destobj.q, srcobj.q)
destobj.qq = export.combine_decorations(destobj.qq, srcobj.qq)
destobj.l = export.combine_decorations(destobj.l, srcobj.l)
destobj.ll = export.combine_decorations(destobj.ll, srcobj.ll)
destobj.refs = export.combine_decorations(destobj.refs, srcobj.refs)
if destobj.id and srcobj.id and destobj.id ~= srcobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(srcobj.id, destobj.id))
end
destobj.id = destobj.id or srcobj.id
return destobj
end
function export.combine_termobj_qualifiers_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng combine_termobj_decorations")
end
function export.termobj_has_decorations(obj)
return obj.q and obj.q[1] or obj.qq and obj.qq[1] or obj.l and obj.l[1] or obj.ll and obj.ll[1] or
obj.refs and obj.refs[1]
end
function export.termobj_has_qualifiers_or_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng termobj_has_decorations")
end
local function one_decoration_equal(prop1, prop2)
local prop1_is_nil = not prop1 or not prop1[1]
local prop2_is_nil = not prop2 or not prop2[1]
if prop1_is_nil and prop2_is_nil then
return true
end
if prop1_is_nil or prop2_is_nil then
return false
end
return deep_equals(prop1, prop2)
end
function export.termobj_decorations_equal(obj1, obj2)
return one_decoration_equal(obj1.q, obj2.q) and
one_decoration_equal(obj1.qq, obj2.qq) and
one_decoration_equal(obj1.l, obj2.l) and
one_decoration_equal(obj1.ll, obj2.ll) and
one_decoration_equal(obj1.refs, obj2.refs) and
obj1.id == obj2.id
end
function export.termobj_ancillary_properties_equal(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng termobj_decorations_equal")
end
function export.convert_termobj_to_formobj(termobj)
local formobj = {
form = termobj.term,
translit = termobj.tr,
}
local footnotes
local function mods_to_footnote(mod_prefix, mod_vals)
if mod_vals and mod_vals[1] then
footnotes = footnotes or {}
for _, val in ipairs(mod_vals) do
insert(footnotes, "[" .. mod_prefix .. ":" .. val .. "]")
end
end
end
mods_to_footnote("q", termobj.q)
mods_to_footnote("qq", termobj.qq)
mods_to_footnote("l", termobj.l)
mods_to_footnote("ll", termobj.ll)
mods_to_footnote("ref", termobj.refs)
mods_to_footnote("id", termobj.id and {termobj.id} or nil)
formobj.footnotes = footnotes
return formobj
end
local recognized_multi_mods = {
q = "q",
qq = "qq",
l = "l",
ll = "ll",
ref = "refs",
}
local recognized_single_mods = {
id = "id",
}
function export.add_footnote_to_termobj(termobj, footnote)
local stripped_footnote = footnote:match("^%[(.*)%]$")
if not stripped_footnote then
error("Internal error: Footnote should be surrounded by brackets at this stage: " .. footnote)
end
local prefix, rest = stripped_footnote:match("^([a-z]+):(.+)$")
local field, is_multi
if prefix then
if recognized_multi_mods[prefix] then
field = recognized_multi_mods[prefix]
is_multi = true
elseif recognized_single_mods[prefix] then
field = recognized_single_mods[prefix]
is_multi = false
end
end
if not field then
rest = stripped_footnote
field = "l"
is_multi = true
end
if is_multi then
if not termobj[field] then
termobj[field] = {}
end
insert(termobj[field], rest)
else
if termobj[field] and termobj[field] ~= rest then
error(("Không thể đặt hai giá trị của '%s': '%s' và '%s'"):format(field, termobj[field], rest))
end
termobj[field] = rest
end
end
function export.convert_formobj_to_termobj(formobj)
local termobj = {
term = formobj.form,
tr = formobj.translit,
}
if formobj.footnotes then
for _, footnote in ipairs(formobj.footnotes) do
export.add_footnote_to_termobj(termobj, footnote)
end
end
return termobj
end
local function extract_termobj_field_modifiers(fieldval)
return fieldval:match("^([*+]?)(.*)$")
end
function export.remove_termobj_field_modifiers(termobj)
local function remove_field_modifiers(field)
if termobj[field] and termobj[field][1] then
local any_field_modifiers = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods ~= "" then
any_field_modifiers = true
break
end
end
local new_field = {}
if any_field_modifiers then
for _, val in ipairs(termobj[field]) do
local _, field_without_mods = extract_termobj_field_modifiers(val)
insert_if_not(new_field, field_without_mods)
end
termobj[field] = new_field
end
end
end
remove_field_modifiers("q")
remove_field_modifiers("qq")
remove_field_modifiers("l")
remove_field_modifiers("ll")
remove_field_modifiers("refs")
end
function export.insert_termobj_combining_duplicates(destobjs, termobj)
for _, destobj in ipairs(destobjs) do
if destobj.term == termobj.term and destobj.tr == termobj.tr then
-- Form already present; maybe combine footnotes.
local function combine_field_values(field)
if termobj[field] and termobj[field][1] then
-- Check to see if there are existing values with *; if so, remove them.
if destobj[field] and destobj[field][1] then
local any_values_with_asterisk = false
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%*") then
any_values_with_asterisk = true
break
end
end
if any_values_with_asterisk then
local filtered_values = {}
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if not field_mods:find("%*") then
insert(filtered_values, val)
end
end
if filtered_values[1] then
destobj[field] = filtered_values
else
destobj[field] = nil
end
end
end
local any_footnotes_with_plus = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
any_footnotes_with_plus = true
break
end
end
if any_footnotes_with_plus then
if not destobj[field] then
destobj[field] = {}
else
destobj[field] = shallow_copy(destobj[field])
end
for _, val in ipairs(termobj[field]) do
local already_seen = false
local field_mods, field_without_mods = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
for _, existing_val in ipairs(destobj[field]) do
local _, existing_field_without_mods =
extract_termobj_field_modifiers(existing_val)
if existing_field_without_mods == field_without_mods then
already_seen = true
break
end
end
if not already_seen then
insert(destobj[field], val)
end
end
end
end
end
end
combine_field_values("q")
combine_field_values("qq")
combine_field_values("l")
combine_field_values("ll")
combine_field_values("refs")
if destobj.id and termobj.id and destobj.id ~= termobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(termobj.id, destobj.id))
end
destobj.id = destobj.id or termobj.id
return
end
end
insert(destobjs, termobj)
end
export.allowed_special_indicators = {
["first"] = true,
["first-second"] = true,
["first-last"] = true,
["second"] = true,
["last"] = true,
["each"] = true,
["+"] = true, -- requests the default behavior with preposition handling
}
--[==[
Check for special indicators (values such as {"+first"} or {"+first-last"} that are used in a `pl`, `f`, etc. argument
and indicate how to inflect a multiword term). If `form` is such an indicator, the return value is `form` minus
the initial `+` sign; otherwise, if form begins with a `+` sign, an error is thrown; otherwise the return value is nil.
]==]
function export.get_special_indicator(form, noerror)
if form:find("^%+") then
form = form:gsub("^%+", "")
if not export.allowed_special_indicators[form] then
if noerror then
return nil
end
local indicators = {}
for indic, _ in pairs(export.allowed_special_indicators) do
insert(indicators, "+" .. indic)
end
sort(indicators)
error("Special inflection indicator beginning with '+' can only be " ..
mw.text.listToText(indicators) .. ": +" .. form)
end
return form
end
return nil
end
local function add_endings(bases, endings)
local retval = {}
if type(bases) ~= "table" then
bases = {bases}
end
if type(endings) ~= "table" then
endings = {endings}
end
for _, base in ipairs(bases) do
for _, ending in ipairs(endings) do
insert(retval, base .. ending)
end
end
return retval
end
--[==[
Inflect a possibly multiword or hyphenated term `form` using the function `inflect`, which is a function of one argument
that is called on a single word to inflect and should return either the inflected word or a list of inflected words.
`special` indicates how to inflect the multiword term and should be e.g. {"first"} to inflect only the first word,
{"first-last"} to inflect the first and last words, {"each"} to inflect each word, etc. See `allowed_special_indicators`
above for the possibilities. If `special` is `+`, or is omitted and the term is multiword (i.e. containing a space
character), and `prepositions` is supplied, the function checks for multiword or hyphenated terms containing the
prepositions in `prepositions`, e.g. Italian [[senso di marcia]] or [[medaglia d'oro]] or Portuguese
[[tartaruga-do-mar]]. If such a term is found, only the first word is inflected. Otherwise, the default is
{"first-last"}. `prepositions` is a list of Lua patterns matching prepositions. The patterns will automatically have the
separator character (space or hyphen) added to the left side but not the right side, so they should contain a space
character (which will automatically be converted to the appropriate separator) on the right side unless the preposition
is joined on the right side with an apostrophe. Examples of preposition patterns for Italian are {"di "}, {"sull'"} and
{"d?all[oae] "} (which matches {"dallo "}, {"dalle "}, {"alla "}, etc.).
The return value is always either a list of inflected multiword or hyphenated terms, or nil if `special` is omitted
and `form` is not multiword. (If `special` is specified and `form` is not multiword or hyphenated, an error results.)
]==]
function export.handle_multiword(form, special, inflect, prepositions, sep)
sep = sep or form:find(" ") and " " or "%-"
local raw_sep = sep == " " and " " or "-"
-- Used to add regex version of separator in the replacement portion of ugsub() or :gsub()
local sep_replacement = sep == " " and " " or "%%-"
-- Given a Lua pattern, replace space with the appropriate separator.
local function hack_re(re)
if sep == " " then
return re
end
return (re:gsub(" ", sep_replacement))
end
if special == "first" then
local first, rest = form:match(hack_re("^(.-)( .*)$"))
if not first then
error("Special indicator 'first' can only be used with a multiword term: " .. form)
end
return add_endings(inflect(first), rest)
elseif special == "second" then
local first, second, rest = form:match(hack_re("^([^ ]+ )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings({first}, inflect(second)), rest)
elseif special == "first-second" then
local first, space, second, rest = form:match(hack_re("^([^ ]+)( )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'first-second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings(add_endings(inflect(first), space), inflect(second)), rest)
elseif special == "each" then
local terms = split(form, sep)
if #terms < 2 then
error("Special indicator 'each' can only be used with a multiword term: " .. form)
end
for i, term in ipairs(terms) do
terms[i] = inflect(term)
if i > 1 then
terms[i] = add_endings(raw_sep, terms[i])
end
end
local result = ""
for _, term in ipairs(terms) do
result = add_endings(result, term)
end
return result
elseif special == "first-last" then
local first, middle, last = form:match(hack_re("^(.-)( .* )(.-)$"))
if not first then
first, middle, last = form:match(hack_re("^(.-)( )(.*)$"))
end
if not first then
error("Special indicator 'first-last' can only be used with a multiword term: " .. form)
end
return add_endings(add_endings(inflect(first), middle), inflect(last))
elseif special == "last" then
local rest, last = form:match(hack_re("^(.* )(.-)$"))
if not rest then
error("Special indicator 'last' can only be used with a multiword term: " .. form)
end
return add_endings(rest, inflect(last))
elseif special and special ~= "+" then
error("Unrecognized special=" .. special)
end
-- Only do default behavior if special indicator '+' explicitly given or separator is space; otherwise we will
-- break existing behavior with hyphenated words.
if (special == "+" or sep == " ") and form:find(sep) then
if prepositions then
-- check for prepositions in the middle of the word; do it this way so we can handle
-- more than one word before the preposition (and usually inflect each word)
for _, prep in ipairs(prepositions) do
local first, space_prep_rest = umatch(form, hack_re("^(.-)( " .. prep .. ".*)$"))
if first then
return add_endings(inflect(first), space_prep_rest)
end
end
end
-- multiword or hyphenated expressions default to first-last; we need to pass in the separator to avoid
-- problems with multiword terms containing hyphens in the individual words
return export.handle_multiword(form, "first-last", inflect, prepositions, sep)
end
return nil
end
local function link_hyphen_split_component(word, data)
if data.link_hyphen_split_component then
return data.link_hyphen_split_component(word)
else
return "[[" .. word .. "]]"
end
end
-- Default function to split a word on apostrophes. Don't split apostrophes at the beginning or end of a word (e.g.
-- [['ndrangheta]] or [[po']]). Handle multiple apostrophes correctly, e.g. [[l'altr'ieri]] -> [[l']][altr']][[ieri]].
function export.default_split_apostrophe(word, data)
local apostrophe_parts = split(word, "'", true, true)
local linked_apostrophe_parts = {}
local apostrophes_at_beginning = ""
local i = 1
-- Apostrophes at beginning get attached to the first word after (which will always exist but may
-- be blank if the word consists only of apostrophes).
while i < #apostrophe_parts do -- <, not <=, in case the word consists only of apostrophes
local apostrophe_part = apostrophe_parts[i]
i = i + 1
if apostrophe_part == "" then
apostrophes_at_beginning = apostrophes_at_beginning .. "'"
else
break
end
end
apostrophe_parts[i] = apostrophes_at_beginning .. apostrophe_parts[i]
-- Now, do the remaining parts. A blank part indicates more than one apostrophe in a row; we join
-- all of them to the preceding word.
while i <= #apostrophe_parts do
local apostrophe_part = apostrophe_parts[i]
if apostrophe_part == "" then
linked_apostrophe_parts[#linked_apostrophe_parts] =
linked_apostrophe_parts[#linked_apostrophe_parts] .. "'"
elseif i == #apostrophe_parts then
insert(linked_apostrophe_parts, apostrophe_part)
else
insert(linked_apostrophe_parts, apostrophe_part .. "'")
end
i = i + 1
end
for j, tolink in ipairs(linked_apostrophe_parts) do
linked_apostrophe_parts[j] = link_hyphen_split_component(tolink, data)
end
return concat(linked_apostrophe_parts)
end
--[=[
Auto-add links to a word that should not have spaces but may have hyphens and/or apostrophes. We split off final
punctuation, then split on hyphens if `data.split_hyphen` is given, and also split on apostrophes if
`data.split_apostrophe` is given. We only split on hyphens if they are in the middle of the word, not at the beginning
or end (hyphens at the beginning or end indicate suffixes or prefixes, respectively). `include_hyphen_prefixes`, if
given, is a set of prefixes (not including the final hyphen) where we should include the final hyphen in the prefix.
Hence, e.g. if "anti" is in the set, a Portuguese word like [[anti-herói]] "anti-hero" will be split [[anti-]][[herói]]
(whereas a word like [[código-fonte]] "source code" will be split as [[código]]-[[fonte]]).
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
]=]
local function add_single_word_links(space_word, data, term_has_spaces)
local space_word_no_punct, punct
local punct_pattern = data.punctuation
if punct_pattern and is_callable(punct_pattern) then
space_word_no_punct, punct = punct_pattern(space_word)
else
if punct_pattern == nil then
punct_pattern = "[,;:?!]"
end
space_word_no_punct, punct = umatch(space_word, "^(.*)(" .. punct_pattern .. ")$")
end
space_word_no_punct = space_word_no_punct or space_word
punct = punct or ""
local words
if space_word_no_punct:sub(1, 1) == "-" or space_word_no_punct:sub(-1) == "-" then
-- don't split prefixes and suffixes
words = {space_word_no_punct}
else
local splitter
if term_has_spaces then
splitter = data.split_hyphen_when_space
else
splitter = data.split_hyphen_when_no_space
end
if is_callable(splitter) then
words = splitter(space_word_no_punct)
if type(words) == "string" then
return words .. punct
end
end
end
if not words then
local split_hyphen
if term_has_spaces then
split_hyphen = data.split_hyphen_when_space
else
split_hyphen = data.split_hyphen_when_no_space
if split_hyphen == nil then -- default to true; use `false` to avoid this
split_hyphen = true
end
end
if split_hyphen then
words = split(space_word_no_punct, "-", true, true)
else
words = {space_word_no_punct}
end
end
local linked_words = {}
for j, word in ipairs(words) do
if j < #words and data.include_hyphen_prefixes and data.include_hyphen_prefixes[word] then
word = "[[" .. word .. "-]]"
elseif j > 1 and data.include_hyphen_suffixes and data.include_hyphen_suffixes[word] then
word = "[[-" .. word .. "]]"
else
-- Don't split on apostrophes if the word is in `no_split_apostrophe_words`.
if (not data.no_split_apostrophe_words or not data.no_split_apostrophe_words[word]) and
data.split_apostrophe and word:find("'", nil, true) then
if data.split_apostrophe == true then
word = export.default_split_apostrophe(word, data)
else -- custom apostrophe splitter/linker
word = data.split_apostrophe(word)
end
elseif word ~= "" then -- avoid -[[]]- (e.g. f--k)
word = link_hyphen_split_component(word, data)
end
if j < #words then
word = word .. "-"
end
end
insert(linked_words, word)
end
return concat(linked_words) .. punct
end
--[=[
Auto-add links to a multiword term. `data` contains fields customizing how to do this. By default we proceed as follows:
(1) If the term already has embedded links in it, they are left unchanged.
(2) Otherwise, if there are spaces present, we split on spaces and link each word separately.
(3) If a given space-separated component ends in punctuation (defaulting to [,;:?!]), it is separated off, the remainder
of the algorithm run, and the punctuation pasted back on.
(4) If there are hyphens in a given space-separated component, we may link each hyphenated term separately depending
on the settings in `data`. Normally the hyphens are not included in the linked terms, but this can be overridden
for specific prefixes and/or suffixes. By default, if there are spaces in the multiword term, we do not link
hyphenated components (because of cases like "boire du petit-lait" where "petit-lait" should be linked as a whole),
but do so otherwise (e.g. for "avant-avant-hier"); this can overridden for cases like "croyez-le ou non".
Cases where only some of the hyphens should be split can always be handled by explicitly specifying the head (e.g.
"Nord-Pas-de-Calais" given as head=[[Nord]]-[[Pas-de-Calais]]).
(5) If there are apostrophes in a given component, we may link each apostrophe-separated term separately depending
on the settings in `data`, including the apostrophe in the link to its left (so we split "de l'eau" as
"[[de]] [[l']][[eau]]").
The settings in `data` are as follows:
`split_hyphen_when_no_space`: Whether to split on hyphens when the term has no spaces. Defaults to true if set to `nil`.
This can be a function of one argument, to implement a custom splitting algorithm for hyphen-separated terms. If
this returns [FIXME: FINISH ME ...]
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
We don't always split on hyphens because of cases like "boire du petit-lait" where "petit-lait" should be linked as a
whole, but provide the option to do it for cases like "croyez-le ou non". If there's no space, however, then it makes
sense to split on hyphens by `no_split_apostrophe_words` and `include_hyphen_prefixes` allow for special-case handling
of particular words and are as described in the comment above add_single_word_links().
]=]
function export.add_links_to_multiword_term(term, data)
if term:match("[%[%]]") then
return term
end
local words = split(term, " ", true, true)
local term_has_spaces = #words > 1
local linked_words = {}
for _, word in ipairs(words) do
insert(linked_words, add_single_word_links(word, data, term_has_spaces))
end
local retval = concat(linked_words, " ")
-- If we ended up with a single link consisting of the entire term,
-- remove the link.
return retval:match("^%[%[([^%[%]]*)%]%]$") or retval
end
local function canonicalize_begin_end_spec(spec)
local from, to = spec:match("^(.-):(.*)$")
if not from then
from = spec
to = ""
end
return from, to
end
--[==[
Given a `linked_term` that is the output of add_links_to_multiword_term(), apply modifications as given in
`modifier_spec` to change the link destination of subterms (normally single-word non-lemma forms; sometimes
collections of adjacent words). This is usually used to link non-lemma forms to their corresponding lemma, but can
also be used to replace a span of adjacent separately-linked words to a single multiword lemma. The format of
`modifier_spec` is one or more semicolon-separated subterm specs, where each such spec is of the form
SUBTERM:DEST, where SUBTERM is one or more words in the `linked_term` but without brackets in them, and DEST is the
corresponding link destination to link the subterm to. Any occurrence of ~ in DEST is replaced with SUBTERM.
Alternatively, a single modifier spec can be of the form BEGIN[FROM:TO], which is equivalent to writing
BEGINFROM:BEGINTO (see example below).
For example, given the source phrase [[il bue che dice cornuto all'asino]] "the pot calling the kettle black"
(literally "the ox that calls the donkey horned/cuckolded"), the result of calling add_links_to_multiword_term()
is [[il]] [[bue]] [[che]] [[dice]] [[cornuto]] [[all']][[asino]]. With a modifier_spec of 'dice:dire', the result
is [[il]] [[bue]] [[che]] [[dire|dice]] [[cornuto]] [[all']][[asino]]. Here, based on the modifier spec, the
non-lemma form [[dice]] is replaced with the two-part link [[dire|dice]].
Another example: given the source phrase [[chi semina vento raccoglie tempesta]] "sow the wind, reap the whirlwind"
(literally (he) who sows wind gathers [the] tempest"). The result of calling add_links_to_multiword_term() is
[[chi]] [[semina]] [[vento]] [[raccoglie]] [[tempesta]], and with a modifier_spec of 'semina:~re; raccoglie:~re',
the result is [[chi]] [[seminare|semina]] [[vento]] [[raccogliere|raccoglie]] [[tempesta]]. Here we use the ~
notation to stand for the non-lemma form in the destination link.
A more complex example is [[se non hai altri moccoli puoi andare a letto al buio]], which becomes
[[se]] [[non]] [[hai]] [[altri]] [[moccoli]] [[puoi]] [[andare]] [[a]] [[letto]] [[al]] [[buio]] after calling
add_links_to_multiword_term(). With the following modifier_spec:
'hai:avere; altr[i:o]; moccol[i:o]; puoi: potere; andare a letto:~; al buio:~', the result of applying the spec is
[[se]] [[non]] [[avere|hai]] [[altro|altri]] [[moccolo|moccoli]] [[potere|puoi]] [[andare a letto]] [[al buio]].
Here, we rely on the alternative notation mentioned above for e.g. 'altr[i:o]', which is equivalent to 'altri:altro',
and link multiword subterms using e.g. 'andare a letto:~'. (The code knows how to handle multiword subexpressions
properly, and if the link text and destination are the same, only a single-part link is formed.)
]==]
function export.apply_link_modifiers(linked_term, modifier_spec, lang)
local split_modspecs = split(modifier_spec, "%s*;%s*")
for j, modspec in ipairs(split_modspecs) do
local id
if modspec:find("<") then
local rest
rest, id = modspec:match("^(.*)<id:(.-)>$")
if rest then
modspec = rest
end
end
local subterm, dest, otherlang
local begin_spec, rest, end_spec = modspec:match("^%[(.-)%]([^:]*)%[(.-)%]$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = begin_from .. rest .. end_from
dest = begin_to .. rest .. end_to
end
if not subterm then
rest, end_spec = modspec:match("^([^:]*)%[(.-)%]$")
if rest then
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = rest .. end_from
dest = rest .. end_to
end
end
if not subterm then
begin_spec, rest = modspec:match("^%[(.-)%]([^:]*)$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
subterm = begin_from .. rest
dest = begin_to .. rest
end
end
if not subterm then
subterm, dest = modspec:match("^(.-)%s*:%s*(.*)$")
if subterm and subterm ~= "^" and subterm ~= "$" then
local langdest
-- Parse off an initial language code (e.g. 'en:Higgs', 'la:minūtia' or 'grc:σκατός'). Also handle
-- Wikipedia prefixes ('w:Abatemarco' or 'w:it:Colle Val d'Elsa').
otherlang, langdest = dest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if otherlang == "w" then
local foreign_wikipedia, foreign_term = langdest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if foreign_wikipedia then
otherlang = otherlang .. ":" .. foreign_wikipedia
langdest = foreign_term
end
dest = ("%s:%s"):format(otherlang, langdest)
otherlang = nil
elseif otherlang then
otherlang = get_lang_by_code(otherlang, true, "allow etym")
dest = langdest
end
end
end
if not subterm then
if modspec == "?" or modspec == "!" then
subterm = "$"
dest = modspec
elseif modspec == "..." or modspec == "...?" then
subterm = "$"
dest = " " .. modspec
elseif modspec:find("^[A-Z]$") then
-- X, Y, etc. by themselves are unlinked, to help with snowclones
subterm = modspec
dest = "_"
else
subterm = modspec
dest = "~"
end
end
if subterm == "^" then
linked_term = dest:gsub("_", " ") .. linked_term
elseif subterm == "$" then
linked_term = linked_term .. dest:gsub("_", " ")
else
if subterm:find("[", nil, true) then
error(("Subterm '%s' in modifier spec '%s' cannot have brackets in it"):format(
escape_wikicode(subterm), escape_wikicode(modspec)))
end
local escaped_subterm = pattern_escape(subterm)
local subterm_re = "%[%[" .. escaped_subterm:gsub("(%%?[ ',%-])", "%%]*%1%%[*") .. "%]%]"
local expanded_dest
if dest:find("~", nil, true) then
expanded_dest = dest:gsub("~", replacement_escape(subterm))
else
expanded_dest = dest
end
if otherlang then
expanded_dest = expanded_dest .. "#" .. otherlang:getCanonicalName()
end
local subterm_replacement
if expanded_dest == "_" then
subterm_replacement = subterm
if id then
error("Can't supply <id:...> with an unlinked subterm")
end
if otherlang then
error("Can't supply prefixed language with an unlinked subterm")
end
elseif id or otherlang then
if id and expanded_dest:find("[", nil, true) then
error("Can't supply <id:...> with destination with embedded brackets")
end
subterm_replacement = require(links_module).language_link {
lang = otherlang or lang,
term = expanded_dest,
alt = subterm,
id = id,
}
elseif expanded_dest:find("[", nil, true) then
-- Use the destination directly if it has brackets in it (e.g. to put brackets around parts of a word).
subterm_replacement = expanded_dest
elseif expanded_dest == subterm then
subterm_replacement = "[[" .. subterm .. "]]"
else
subterm_replacement = "[[" .. expanded_dest .. "|" .. subterm .. "]]"
end
local escaped_subterm_replacement = replacement_escape(subterm_replacement)
local replaced_linked_term = ugsub(linked_term, subterm_re, escaped_subterm_replacement)
if replaced_linked_term == linked_term then
mw.log(("Attempted to replace %s with %s in %s"):format(subterm_re, escaped_subterm_replacement, linked_term))
error(("Subterm '%s' could not be located in %slinked expression %s, or replacement same as subterm"):format(
subterm, j > 1 and "intermediate " or "", escape_wikicode(linked_term)))
else
linked_term = replaced_linked_term
end
end
end
return linked_term
end
local inflection_to_cats_and_label = {
plural = {
filter_plpos = function(plpos)
-- plurals also occur with determiners, adjectives etc. and we don't want to generate categories like
-- 'countable determiners', 'countable adjectives', etc. Note that the passed-in `plpos` has `proper nouns`
-- converted to `nouns`.
return plpos == "Danh từ"
end,
cats = {"{plpos} đếm được"},
no_cats = {"{plpos} không đếm được"},
no_label = "<<không đếm được>>",
sometimes_label = "<<đếm được>> và <<không đếm được>>",
},
comparative = {
cats = {"{plpos} so sánh được"},
no_cats = {"{plpos} không so sánh được"},
fixed_adj_label = "so sánh được",
},
["female equivalent"] = {
cats = {"{plpos} with other-gender equivalents"},
},
["male equivalent"] = {
cats = {"{plpos} with other-gender equivalents"},
},
}
--[=[
Validate the items in `items` against the list or set of valid items in `valid_items`. If `field` is given, fetch the
item to check from that-named field of each object in `items`; otherwise use the items in `items` directly. If an error
occurs, `item_type` specifies the type of item to mention in the error message, which will also list the allowed items
(either taken directly from `valid_items` if a list, or from the sorted keys if a set).
]=]
local function validate_items(data)
local items, field, valid_items, item_type =
data.items, data.field, data.valid_items, data.item_type
local valid_set
if valid_items[1] then
valid_set = list_to_set(valid_items)
else
valid_set = valid_items
end
for _, item in ipairs(items) do
if field then
item = item[field]
end
if not valid_set[item] then
local valid_list
if valid_items[1] then
valid_list = valid_items
else
valid_list = {}
for valid_item, _ in pairs(valid_items) do
insert(valid_list, valid_item)
end
table.sort(valid_list)
end
error(("Invalid %s: %s; expected one of %s"):format(item_type, item, mw.text.listToText(valid_list)))
end
end
end
function export.has_plural_gender(genders)
local saw_p, saw_non_p
for _, val in ipairs(genders) do
local g = val.spec
if g:find("p$") then
saw_p = true
elseif g ~= "?" then
saw_non_p = true
end
end
return saw_p, saw_non_p
end
function export.is_plurale_tantum(genders)
local saw_p, saw_non_p = export.has_plural_gender(genders)
return saw_p and not saw_non_p
end
local Headdata = {}
function Headdata:get_simplified_plpos()
return export.simplify_pos(self.pos_category)
end
--[==[
Canonicalize a category. The category string will have the full language name (i.e. the name of the L2 language under
which an entry is inserted, which may a parent language if the language in question is an etymology-only language)
prepended to it, and any occurrences of `{plpos}` in the string replaced with the actual plural part of speech (with
some canonicalization; specifically, `proper nouns` is converted to `nouns` when replacing `{plpos}`). To specify a
full category and not have the language name prepended to it, precede it with {"Category:"}, which will be removed.
]==]
function Headdata:canonicalize_category(category)
if category:find("{plpos}") then
local plpos = self:get_simplified_plpos()
category = category:gsub("{plpos}", plpos)
end
if category:find("^Category:") then
return (category:gsub("^Category:", ""))
else
return self.langfullname .. " " .. category
end
end
--[==[
Canonicalize a list of categories according to the process described in `Headdata:canonicalize_category`. This simply
loops over each category in `categories` and calls `Headdata:canonicalize_category` on each one.
]==]
function Headdata:canonicalize_categories(categories)
if not categories then
return categories
end
local canon_cats = {}
for _, cat in ipairs(categories) do
insert(canon_cats, self:canonicalize_category(cat))
end
return canon_cats
end
--[==[
Insert a category into the `categories` list in the headword `data` structure. `category` is normally a string naming
the category, which will have the full language name prepended to it and any occurrences of `{plpos}` in the string
replaced with the actual plural part of speech (with some canonicalization; specifically, `proper nouns` is converted to
`nouns` when replacing `{plpos}`). To specify a full category and not have the language name prepended to it, precede it
with {"Category:"}.
]==]
function Headdata:insert_category(category)
insert(self.categories, self:canonicalize_category(category))
end
--[==[
Validate the genders in `genders` (a list of gender spec objects, as produced by {type = "genders"} in
[[Module:parameters]] and accepted by [[Module:gender and number]]), checking that all specified genders are in the list
given in `valid_genders`. Optional `props` controls how the validation happens. In particular, unless `props.no_augment`
is given, then for any gender beginning with `m`, if a corresponding gender beginning with `f` occurs, analogous genders
beginning with `mf`, `mfbysense` and `mfequiv` are also allowed. For example, if `m-d` (masculine dual) and `f-d`
(feminine dual) both occur, genders `mf-d`, `mfbysense-d` and `mfequiv-d` are also allowed. If a disallowed gender is
given, an error occurs, giving the disallowed gender along with the list of all allowed genders.
]==]
function Headdata:validate_genders(genders, valid_genders, props)
if not genders then
return
end
props = props or {}
local gender_type, no_augment = props.gender_type, props.no_augment
gender_type = gender_type or "headword"
local valid_gender_set = list_to_set(valid_genders)
local augmented_gender_set
if no_augment then
augmented_gender_set = valid_gender_set
else
augmented_gender_set = {}
for g, _ in pairs(valid_gender_set) do
augmented_gender_set[g] = true
if g:find("^m") and not g:find("^mf") and valid_gender_set[g:gsub("^m", "f")] then
augmented_gender_set[g:gsub("^m", "mf")] = true
augmented_gender_set[g:gsub("^m", "mfbysense")] = true
augmented_gender_set[g:gsub("^m", "mfequiv")] = true
end
end
end
validate_items {
items = genders,
field = "spec",
valid_items = augmented_gender_set,
item_type = ("%s gender"):format(gender_type),
}
end
--[==[
Parse an inflection specified in `field`, the name of a parameter holding an inflection. If the parameter is numeric,
the field should be given as a number (as with the `params` structure passed to [[Module:parameters]]), not a string
containing the representation of a number. The field can specify multiple comma-separated terms, and each term can have
associated inline modifiers that will be parsed (unless there is top-level HTML in the parameter, i.e. HTML not
contained inside an inline modifier, e.g. as may be generated by using {{tl|l}} or similar template inside a parameter).
This is a wrapper around the top-level `parse_term_with_modifiers()` function. `props` is an optional structure
containing additional properties, including all additional properties documented for the top-level
`parse_term_with_modifiers()` function.
If the parameter in `field` is unspecified, the return value of this function will be an empty list, not {nil}, so it
is always safe to iterate over the return value.
By default, the allowed modifiers are the same as for `parse_term_with_modifiers()`, except that (normally) the
`<tr:...>` modifier will be allowed if `include_tr` was specified in the original call to `process_headword()`; likewise
for the `<ts:...>` modifier if `include_ts` was specified and the `<sc:...>` modifier if `include_sc` was specified. If
If you pass in your own `include_mods` list of additional allowed modifiers, it will (normally) automatically be
augmented with {"tr"}, {"ts"} and/or {"sc"} if `include_tr`, `include_ts` and/or `include_sc` was specified when calling
`process_headword()`. To disable automatic augmentation of these modifiers (whether or not you specify an `include_mods`
property), specify {no_augment_include_mods = true} in `props`.
]==]
function Headdata:parse_inflection(field, props)
local val = self.process_props.args[field]
if not val then
return {}
end
props = props and shallow_copy(props) or {}
local include_mods = props.include_mods
local calldata = self.process_props.calldata
if not props.no_augment_include_mods and (calldata.include_tr or calldata.include_ts or calldata.include_sc) then
include_mods = include_mods and shallow_copy(include_mods) or {}
if calldata.include_tr then
insert_if_not(include_mods, "tr")
end
if calldata.include_ts then
insert_if_not(include_mods, "ts")
end
if calldata.include_sc then
insert_if_not(include_mods, "sc")
end
end
props.val = val
props.paramname = field
props.splitchar = props.splitchar or ","
props.include_mods = include_mods
local orig_frob = props.frob
local function convert_tilde_to_pagename(term)
if orig_frob then
term = orig_frob(term)
end
if not term:find("~", nil, true) then
return term
end
term = term:gsub("\\~", "\1"):gsub("~", replacement_escape(self.pagename)):gsub("\1", "~")
return term
end
props.frob = convert_tilde_to_pagename
return export.parse_term_with_modifiers(props) or {}
end
--[==[
Insert previously-parsed terms into the `inflections` of the headword `data` structure. This is a wrapper around
the top-level `insert_inflection()` function. `terms` is the list of parsed terms. (If {nil}, nothing happens unless
`request` is set in `props`.) `label` is the the label that the inflections are given; any parts of the label surrounded
in `<<...>>` are linked to the glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.)
`props` is an optional structure containing additional properties, including all additional properties documented for
the top-level `insert_inflection()` function.
Unless `no_auto_cats` is given in `props`, certain labels automatically trigger the insertion of additional
categories in specific circumstances. This is controlled by the `inflection_to_cats_and_label` structure in
[[Module:headword utilities]]. For example, if the part of speech is {"nouns"} or {"proper nouns"} and the label (after
removing any links and `<<...>>` glossary specs) is {"plural"}, an additional category
<code><var>lang</var> countable nouns</code> will be added if a plural value is given (i.e. the value is not {"-"}). If
the value is {"-"} (which indicates that there is no plural and triggers the insertion of the fixed inflection label
{"no plural"}), <code><var>lang</var> uncountable nouns</code> will be inserted instead, and if both {"-"} and a value
are given (which triggers the insertion of the {"usually no plural"} fixed inflection label), both categories are added.
Similar categories are inserted when a comparative is given (with a label {"comparative"}), and if the label is
{"female equivalent"} or {"male equivalent"} and the value is not {"-"}, a category such as
<code><var>lang</var> nouns with other-gender equivalents</code> is inserted.
]==]
function Headdata:insert_inflection(terms, label, props)
props = props and shallow_copy(props) or {}
if not props.no_auto_cats then
local bare_label = props.label_for_cats_and_modes
if not bare_label then
bare_label = label
if bare_label:find("[[", nil, true) then
bare_label = require(links_module).remove_links(bare_label)
end
if bare_label:find("<<", nil, true) then
bare_label = bare_label:gsub("<<.-|(.-)>>", "%1"):gsub("<<(.-)>>", "%1")
end
end
local cats = inflection_to_cats_and_label[bare_label]
if cats then
if not cats.filter_plpos or cats.filter_plpos(self:get_simplified_plpos()) then
if props.cats == nil then
props.cats = self:canonicalize_categories(cats.cats)
end
if props.usually_no_cats == nil then
props.usually_no_cats = self:canonicalize_categories(cats.usually_no_cats)
end
if props.no_cats == nil then
props.no_cats = self:canonicalize_categories(cats.no_cats)
end
end
end
end
props.headdata = self
props.terms = terms
props.label = label
return export.insert_inflection(props)
end
--[==[
Insert a "fixed" inflection (a label without associated values) into the `inflections` table of the headword `data`
structure, labeled according to `label` (which can have glossary links in it specified using `<<...>>`, exactly as for
`:insert_inflection()`). An example label (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"},
specifying that the noun belongs to the hidden-''g'' declension. This is a direct wrapper around the top-level function
`insert_fixed_inflection()`; see that function for more details on optional `props`.
]==]
function Headdata:insert_fixed_inflection(label, props)
props = props and shallow_copy(props) or {}
props.headdata = self
props.label = label
export.insert_fixed_inflection(props)
end
--[==[
Parse the inflection(s) specified in `field` and insert them into the `inflections` table of the headword `data`
structure, labeled according to `label`. This is equivalent to calling {terms = data:parse_inflection(field, props)}
followed by {return data:insert_inflection(terms, label, props)} and behaves the same as the combination of those two
functions. See their documentation for more details.
]==]
function Headdata:parse_and_insert_inflection(field, label, props)
local terms = self:parse_inflection(field, props)
return self:insert_inflection(terms, label, props)
end
--[==[
Generate an inflection that may be specified explicitly or defaulted (which involves looping over the specified or
defaulted heads and determining the script of each one, since the formation of the default depends on the script).
`data` is the data object passed into the POS handler. `terms` is the list of terms to process. Those where the term
itself is not `+` will be returned unchanged, while those where the term is `+` will be handled by generating the
appropriate inflections from the headwords using `make_inflection` (which is passed three arguments, `head`, `tr` and
`sccode`, i.e. the script code of `head`) and should return two values, term and translit, either of which can be
nil. A nil head will be ignored, and otherwise the decorations specified on the `+` term will be combined with the
decorations specified on the head. The return value is a list of inflections where no requests for the default
inflection remain.
]==]
function Headdata:resolve_special(terms, handle_special, props)
props = props or {}
local infls = {}
local is_special = props.is_special or function(_data, infl) return infl.term == "+" end
for _, termobj in ipairs(terms) do
if not is_special(self, termobj) then
insert(infls, termobj)
else
for _, headobj in ipairs(self.heads) do
local head = headobj.term or self.pagename
local head_no_links
if props.with_links then
head = head:find("%[") and head or require(headword_module).add_multiword_links(head, not headobj.term)
head_no_links = require(links_module).remove_links(head)
else
head = require(links_module).remove_links(head)
head_no_links = head
end
local newterms = handle_special {
headdata = self,
head = head,
head_no_links = head_no_links,
tr = headobj.tr,
infl = termobj,
sc = self.lang:findBestScript(head_no_links),
}
if newterms then
newterms = export.canonicalize_termobj_list(newterms, "term", "resolve_special", termobj)
for _, newterm in ipairs(newterms) do
if not props.no_combine_handle_special_retval_with_origin then
export.combine_termobj_decorations(newterm, termobj)
end
if not props.no_combine_handle_special_retval_with_head then
export.combine_termobj_decorations(newterm, headobj)
end
insert(infls, newterm)
end
end
end
end
end
return infls
end
--[==[
Add the current page to a tracking page named `Wiktionary:Tracking/``lang``-headword/``page```, where ``lang`` is the
language code of the current language. For example, if the current language is `mak` and `page` is {"redundant-lon"},
the current page will get added to the tracking page `Wiktionary:Tracking/mak-headword/redundant-lon`. All pages added
to that tracking page can be seen by going to [[Special:WhatLinksHere/Wiktionary:Tracking/mak-headword/redundant-lon]].
This is typically used to track issues occurring in user-specified parameters that do not rise to the level of errors
(e.g. redundant parameters, deprecated usages or other dispreferred values).
]==]
function Headdata:track(page)
return require(debug_track_module)(self.langcode .. "-headword/" .. page)
end
local boolean_param = {type = "boolean"}
--[==[
Process an arbitrary headword in an arbitrary language, handling generic and language-specific arguments and calling
`full_headword()` in [[Module:headword]]. This is intended for use in implementing headword modules (e.g.
[[Module:uz-headword]] for Uzbek, [[Module:mn-headword]] for Uzbek, [[Module:gsw-headword]] for Alemannic German, etc.)
and provides a general implementation of such modules. On input, `data` is an object with the following fields:
* `lang`: The language object of the language being handled. '''Required.''' Use the special value {false} to indicate
that the language is specified by the user in {{para|1}}.
* `frame`: The frame object passed into the `show()` function of your module, which implements headword-handling for
all parts of speech in the module, including a generic POS-handling template (e.g. {{tl|uz-head}} or {{tl|mn-head}}),
which allows arbitrary parts of speech to be handled. '''Required.'''
* `pos_functions`: A table listing, for each part of speech requiring special handling, the extra parameters (if any)
that the part of speech accepts, along with how to handle them. See the examples below. '''Required.'''
* `validate_lang`: If {lang = true} is specified, this is a function of one argument (a language object, based on the
language specified in {{para|1}}) that should throw an error if the language object is disallowed. If omitted, all
languages are allowed.
* `numbered_head`: If true, explicit headwords are specified in a numbered param instead of in {{para|head}}. The param
used is usually {{para|1}}, but is {{para|2}} for generic POS templates such as {{tl|mn-head}} or for POS-specific
templates when {lang = true} is specified (e.g. {{tl|arb-noun}}), and is {{para|3}} for generic POS templates when
{lang = true} is spcified (e.g. {{tl|arb-head}}).
* `include_tr`: If true, allow explicit transliterations to be specified. The transliteration(s) for the headword(s)
themselves is/are specified in {{para|tr}} or through the {{cd|<tr:...>}} inline modifier on headwords, and
transliterations of inflections are specified through the {{cd|<tr:...>}} inline modifier. This should generally be
given when a headword for the language may be in a script other than Latin.
* `include_ts`: If true, allow explicit transcriptions to be specified. The transcription(s) for the headword(s)
themselves is/are specified in {{para|ts}} or through the {{cd|<ts:...>}} inline modifier on headwords, and
transcriptions of inflections are specified through the {{cd|<ts:...>}} inline modifier. This should generally only
be given for certain languages where the spelling is radically different from the pronunciation (e.g. in cuneiform
languages such as Hittite and Akkadian, and potentially in Tibetan), and represents a pronunciation-based rendering
(usually not direct IPA).
* `include_sc`: If true, allow an explicit script code to be specified. The overall script code for the headword(s)
themselves can be specified using {{para|sc}}, and per-headword or per-inflection script codes are specified using the
{{cd|<sc:...>}} inline modifier. This should generally be given when a language supports multiple scripts.
* `infls`: An inflections structure specifying extra generic parameters that apply to all parts of speech and how to
handle them. The format is the same as for the `infls` structure in `pos_functions`.
* `augment_params`: A callback function to add extra generic parameters, or modify existing generic parameters in the
`params` structure; but in general, extra generic parameters should be added through the `infls` structure instead.
This callback should not be used to add part-of-speech-specific parameters; those are handled through the appropriate
setting in `pos_functions`. It is passed two single arguments, the `headdata` object and the `params` table to be
augmented. See below for extra fields stored in the `process_props` structure of the `headdata` object. This function
is called after initializing the `params` table and processing the overall `infls` structure, but just before adding
part-of-speech-specific parameters (from `pos_functions`) to `params`. Thus, it can override any generic parameters
but may itself be overridden by a part-of-speech-specific parameter.
* `augment_headdata`: A callback function to modify the `headdata` object passed to `full_headword()` in
[[Module:headword]]. This should not be used to for part-of-speech-specific parameter handling; this is handled
through the appropriate setting in `pos_functions`. It is passed a single argument, the `headdata` object, as for
`augment_params`; but the `process_props` structure and other fields will be more filled out, as this callback is
called later. This can be used, for example, to override the value of a generic setting in `headdata` (e.g.
[[Module:uz-headword]] uses this to mark non-Latin terms as variant forms by setting `headdata.var`, being careful not
to override a value already set by the user). This function is called after initializing the `headdata` table with all
information taken from generic parameters and processing generic parameters specified in the overall `infls`
structure, and just before processing the appropriate part-of-speech-specific `infls` structure in `pos_functions`
(which in turn is followed by any handler function in `pos_functions`). Thus, it can override any value set during
generic parameter processing but may itself be overridden by a part-of-speech-specific parameter or handler.
* `force_cat`: If true, add the headword to the appropriate categories even on non-mainspace pages. This can be used for
testing category handling in sample template calls on userspace test pages or template documentation pages. It should
not be set in production code.
* `enable_auto_translit`: If true, turn on automatic transliteration of inflections at a global level (i.e. applying to
all inflections). This has no effect on headwords, which are automatically transliterated by default if in a non-Latin
script and automatic transliteration is available for the language. You can also set this value for particular
inflections in the `insert_inflection()` function.
The `headdata` headword data structure has an extra field in it called `process_props` that is specific to the
`process_headword()` function, containing various extra properies. As the operation of `process_headword()` proceeds,
this object gets filled out with more fields. For example, once parameter parsing happens, the resulting values are
available in the `args` field of `process_props`. The following fields are found in `process_props` (note that
`pos_category`, the canonicalized plural part of speech of the headword being processed, is *not* present here; it's
directly on `headdata`):
* `namespace`: The name of the current namespace; an empty string for the mainspace. This references the namespace of
the actual page and isn't affected by the {{para|pagename}} parameter.
* `indexing_pos`: The canonicalized part of speech of the headword used to index into `pos_functions`. This is the
same as `poscat` for specific part-of-speech templates such as {{tl|uz-noun}}, but has the value {"head"} for generic
part-of-speech templates such as {{tl|uz-head}}. (Note that `poscat` is directly available on `headdata`.)
* `generic_pos_template`: True if a generic POS templates like {{tl|uz-head}} or {{tl|mn-head}} was used. (This is
signaled by omitting the invocation parameter {{para|1}} to `process_headword`.)
* `lang_in_1`: True if the language code is to be fetched from {{para|1}}.
* `pos_param`: The parameter holding the part of speech, if a generic POS tempalte like {{tl|mn-head}} is being
processed (i.e. `generic_pos_template` is set). In such a case, it will have the value of {1} or {2}, depending on
whether the language code is being fetched from {{para|1}} (see `lang_in_1`). Otherwise it will be {nil}.
* `head_param`: The parameter holding the explicit headword. If `numbered_head` was specified (as for Mongolian headword
templates), this has the value {1}, {2} or {3} depending on whether the language code is being fetched from {{para|1}}
(see `lang_in_1`) and whether a generic POS template like {{tl|mn-head}} is being processed (see
`generic_pos_template`). Otherwise, it has the value {"head"}. Also see the `lang` and `numbered_head` properties in
the `data` structure sent to `process_headword()`.
* `is_suffix`: True if the current term is a suffix. This is set when processing the `suffix`, `nosuffix` and `clitic`
parameters; it is always {false} beforehand (i.e. during `augment_params` and processing of the general `infls`
structure).
* `insert_specs`: This is a table mapping parameter names to the return value of `Headdata:insert_inflection()`, filled
out as parameter values are processed. This lets a given parameter processing function in `infls` gain access to the
result of calling `insert_inflection()` on previous parameters (which indicates the number of items inserted as well
as whether `-` was specified).
The `pos_functions` table contains an entry for each part of speech needing special handling, where the key is the
canonical plural part of speech (e.g. {"adverbs"} or {"proper nouns"}). The value associated with each key is a table
normally containing a field `infls`, listing the extra part-of-speech-specific inflection and other parameters along
with how to handle them. The specs in `infls` are used in three ways:
# to augment the `params` object passed to the `process()` function in [[Module:parameters]], specifying how to parse
the appropriate inflectional parameters;
# to specify how to process any inflectional parameters given and insert them into the `headdata` object passed to
`full_headword()` in [[Module:headword]];
# to generate appropriate documentation for the parameters and other changes made by the headword template (e.g.
inserting categories).
Alternatively, you can separately control the augmentation of the `params` object and the procesing of the resulting
arguments. This is done by specifying two fields in place of `infls`, named `params` and `func`. `params` is a table
containing extra parameters to add to the overall `params` object passed to the `process()` function in
[[Module:parameters]]. `func` is a function of two arguments, normally called `data` (the headword data structure
`headdata`) and `args` (the processed arguments table). However, this alternative method is not normally recommended
because it leads to duplication between the `params and `func` fields and the documentation, which must be manually
specified.
A simple example, as used to handle pronouns for Turoyo, is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
infls = {
{2, type = "genders", validate = valid_genders},
{"f", label = "feminine"},
{"pl", label = "plural"},
},
}
}
The equivalent using `params` and `func` is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
params = {
[2] = {type = "genders"},
f = true,
pl = true,
},
func = function(data, args)
data:validate_genders(args[2], valid_genders)
data.genders = args[2]
data:parse_and_insert_inflection("f", "feminine")
data:parse_and_insert_inflection("pl", "plural")
end
}
}
Note how the version with separate `params and `func` is longer and splits information on the parameters between the
two fields. The `params` structure sets extra user-specifiable parameters {{para|2}} for genders (since the headword is
in {{para|1}}) as well a {{para|f}} and {{para|pl}}, and the `func` handler processes those parameters. Note how this is
done by calling methods on the headword `data` structure. Each such parameter can have multiple comma-separated values,
and each value can have inline modifiers attached to it to specify further properties of the value. The `infls` version
ends up making the same method calls, but does it for you instead of you having to do it yourself.
These methods are implemented through a metatable set on the headword `data` structure, which is removed before calling
`full_headword()` in [[Module:headword]]. The methods access extra information related to headword processing (such as
the `args` table) that is stored in the `process_props` field of the headword `data` strucuture. This field is also
removed prior to calling `full_headword()`.
The methods available on the headword `data` structure are as follows. Each one also has its own documentation.
* {parse_inflection(field, props)}: Parse value(s) specified in `field` (a user-specified parameter in the `args` table)
and return a list of term objects. Optional `props` specifies additional properties controlling the parsing.
* {insert_inflection(terms, label, props)}: Insert the terms in `terms` (a list of term objects as returned by
`parse_inflection()`) into the `inflections` list in the headword `data` structure, giving the inflection the label as
specified in `label`. Optional `props` specifies additional properties controlling the parsing.
* {parse_and_insert_inflection(field, label, props)}: A combination of `parse_inflection()` and `insert_inflection()`,
if no further processing of the parsed values needs to be done before insertion.
* {insert_fixed_inflection(label, props)}: Insert a "fixed" inflection (a label without associated values) into the
`inflections` table. An example (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"}, specifying
that the noun belongs to the hidden-''g'' declension.
* {resolve_special(terms, handle_special, props)}: Resolve "special" indicators as specified by the user in an inflection
parameter. A typical example is {"+"}, requesting a default value. `terms` is the list of parsed term objects and
`handle_special` is a handler function to process special indicators and convert them to their actual values.
* {validate_genders(genders, valid_genders, props)}: Validate that the user-specified genders in `genders` all belong to
the list given in `valid_genders`, throwing an error if not.
* {insert_category(category)}: Insert a category into the `categories` list in the headword `data` structure. `category`
is normally a string naming the category, which will have the language prepended to it and any occurrences of
`{plpos}` in the string replaced with the actual plural part of speech.
]==]
function export.process_headword(data)
local lang, frame, pos_functions, validate_lang, numbered_head, include_tr, include_ts, include_sc, force_cat,
enable_auto_translit, checkredlinks, infls, augment_params, augment_headdata =
data.lang, data.frame, data.pos_functions, data.validate_lang, data.numbered_head, data.include_tr,
data.include_ts, data.include_sc, data.force_cat, data.enable_auto_translit, data.checkredlinks, data.infls,
data.augment_params, data.augment_headdata
local iparams = {
[1] = true,
def = true,
}
local iargs = require(parameters_module).process(frame.args, iparams)
local parargs = frame:getParent().args
local langcode
if not lang then
error("Internal error: `data.lang` must be specified; either a language object or `true` for a user-specified language")
end
local lang_in_1
if lang == true then
lang_in_1 = true
langcode = ine(parargs[1])
if langcode then
langcode = mw.text.trim(langcode)
lang = require(languages_module).getByCode(langcode, 1, true)
if validate_lang then
validate_lang(lang)
end
else
error("Language code (see [[WT:Language codes]]) must be specified in 1=")
end
else
langcode = lang:getCode()
if validate_lang then
error("Internal error: `data.validate_lang` must not be specified if a language code is given in `data.lang`")
end
end
local template_indicated_pos = iargs[1]
local generic_pos_template = not template_indicated_pos
local pos_param
if generic_pos_template then
pos_param = lang_in_1 and 2 or 1
template_indicated_pos = ine(parargs[pos_param]) or
mw.title.getCurrentTitle().fullText == ("Bản_mẫu:%s-head"):format(langcode) and "interjection" or
error(("Part of speech must be specified in %s="):format(pos_param))
template_indicated_pos = require(headword_module).canonicalize_pos(template_indicated_pos)
end
local head_param = numbered_head and (generic_pos_template and lang_in_1 and 3 or
(generic_pos_template or lang_in_1) and 2 or 1) or "head"
local indexing_pos
if generic_pos_template then
indexing_pos = "head." .. template_indicated_pos
if not pos_functions[indexing_pos] then
indexing_pos = "head"
end
else
indexing_pos = template_indicated_pos
end
local namespace = mw.loadData(headword_data_module).page.namespace
-- Partly initialize headdata now for use in generic infls callbacks. Will be further initialized later after
-- processing parameters.
local headdata = {
lang = lang,
langcode = langcode,
langfullcode = lang:getFullCode(),
langname = lang:getCanonicalName(),
langfullname = lang:getFullName(),
process_props = {
namespace = namespace,
calldata = data,
-- preserve template-indicated POS in case we normalize it or change it to "suffix"
template_indicated_pos = template_indicated_pos,
indexing_pos = indexing_pos,
generic_pos_template = generic_pos_template,
lang_in_1 = lang_in_1,
pos_param = pos_param,
head_param = head_param,
is_suffix = false,
insert_specs = {},
},
-- We may change this below to "suffix" or normalize it.
pos_category = template_indicated_pos,
categories = {},
inflections = {enable_auto_translit = enable_auto_translit},
force_cat_output = force_cat,
no_redundant_head_cat = true,
}
setmetatable(headdata, {__index = Headdata})
local function resolve_prop(prop, ...)
if type(prop) == "function" then
prop = prop(headdata, ...)
end
return prop
end
local params = {
[head_param] = {template_default = iargs.def},
head2 = {replaced_by = false, instead = ("use comma-separated |%s="):format(head_param)},
id = true,
sort = true,
cat = true,
nolink = boolean_param,
nolinkhead = {type = "boolean", alias_of = "nolink"},
suffix = boolean_param,
nosuffix = boolean_param,
clitic = true,
addlpos = true,
var = {type = "boolean or string", set = {"both"}},
abbr = true,
json = boolean_param,
pagename = true, -- for testing
}
if include_sc then
params.sc = {type = "script"}
end
if include_tr then
params.tr = true
params.tr2 = {replaced_by = false, instead = "use comma-separated |tr= or <tr:...> inline modifier on head"}
end
if include_ts then
params.ts = true
params.ts2 = {replaced_by = false, instead = "use comma-separated |ts= or <ts:...> inline modifier on head"}
end
if lang_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
if generic_pos_template then
params[pos_param] = {required = true} -- required but ignored as already processed above
end
local function augment_params_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local param = infl[1]
if param then
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- We handle defaults as well as validation ourselves.
local typ = resolve_prop(infl.type) or "string"
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
params[param] = {type = typ, required = resolve_prop(infl.required), template_default = resolve_prop(infl.template_default)}
if typ ~= "boolean" then
local allow_and_ignore_list_params = resolve_prop(infl.allow_and_ignore_list_params)
local ignore_param
if type(allow_and_ignore_list_params) == "string" then
ignore_param = allow_and_ignore_list_params
elseif type(param) == "string" then
ignore_param = param
end
if ignore_param then
local old_list_param = allow_and_ignore_list_params and true or
{replaced_by = false, instead = ("use comma-separated |%s="):format(param)}
params[ignore_param .. "2"] = old_list_param
params[ignore_param .. "3"] = old_list_param
params[ignore_param .. "4"] = old_list_param
end
end
end
end
end
if infls then
augment_params_from_infls(infls)
end
if augment_params then
augment_params(headdata, params)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_params_from_infls(pos_infls)
end
local pos_params = pos_functions[indexing_pos].params
if pos_params then
for key, val in pairs(pos_params) do
params[key] = val
end
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData(headword_data_module).pagename
local sc = args.sc or lang:findBestScript(pagename)
headdata.pagename = pagename
headdata.process_props.args = args
headdata.sc = sc
headdata.id = args.id
headdata.sort = args.sort
-- No redundant script cat unless the user explicitly gave sc=
headdata.no_script_code_cat = not args.sc
headdata.var = args.var
local extra_term_mods = {}
if include_tr then
insert(extra_term_mods, "tr")
end
if include_ts then
insert(extra_term_mods, "ts")
end
if include_sc then
insert(extra_term_mods, "sc")
end
if not extra_term_mods[1] then
extra_term_mods = nil
end
local trs = args.tr and split_on_comma(args.tr) or {}
local num_trs = #trs
local tss = args.ts and split_on_comma(args.ts) or {}
local num_tss = #tss
local heads = args[head_param] and export.parse_term_with_modifiers {
val = args[head_param],
paramname = head_param,
splitchar = ",",
is_head = true,
include_mods = extra_term_mods,
} or {}
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 default automatic translit and '-' to stand for no translit"):format(
num_heads, num_heads > 1 and "s" or "", num_trs, num_trs > 1 and "s" or ""))
end
if num_heads > 0 and num_tss > 0 and num_heads ~= num_tss then
error(("%s head%s specified explicitly but %s transcription%s; they must match; use '+' to stand for the default head (the pagename) and '-' to stand for no transcription"):format(
num_heads, num_heads > 1 and "s" or "", num_tss, num_tss > 1 and "s" or ""))
end
if num_trs > 0 and num_tss > 0 and num_trs ~= num_tss then
error(("%s translit%s specified explicitly but %s transcription%s; they must match; use '+' to stand for default automatic translit and '-' to stand for no translit or transcription"):format(
num_trs, num_trs > 1 and "s" or "", num_tss, num_tss > 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.
local max_tr_ts = math.max(num_trs, num_tss)
if num_heads == 0 and max_tr_ts > 0 then
heads = {}
for i = 1, max_tr_ts do
heads[i] = {term = "+"}
end
end
if not heads[1] then
heads = {{term = "+"}}
end
for i, headobj in ipairs(heads) do
if headobj.tr and trs[i] then
if headobj.tr ~= trs[i] then
error(("Saw two different translits '%s' and '%s' for head #%s"):format(
headobj.tr, trs[i], i))
end
else
headobj.tr = headobj.tr or trs[i]
end
if headobj.tr == "+" then
headobj.tr = nil
end
if headobj.ts and tss[i] then
if headobj.ts ~= tss[i] then
error(("Saw two different transcriptions '%s' and '%s' for head #%s"):format(
headobj.ts, tss[i], i))
end
else
headobj.ts = headobj.ts or tss[i]
end
if headobj.ts == "-" then
headobj.ts = nil
end
if headobj.term == "+" then
headobj.term = args.nolink and pagename or nil
if headobj.term and namespace == "Reconstruction" then
headobj.term = "*" .. headobj.term
end
end
end
headdata.heads = heads
local pos_category = headdata.pos_category
-- Do this as late as possible in case the caller wants to conditionalize the primary categorizing POS on
-- arguments or even the presence or absence of explicit heads.
if pos_functions[indexing_pos] then
pos_category = resolve_prop(pos_functions[indexing_pos].pos_category) or pos_category
end
headdata.process_props.normalized_template_indicated_pos = pos_category
headdata.pos_category = pos_category
local function pagename_is_suffix()
if sc:getCode() == "Latn" then
-- shortcut Latin terms to avoid unnecessarily loading [[Module:affix]]
return pagename:find("^%-") and not pagename:find("%-$")
else
local affix_type, _, _, _ = require(affix_module).parse_term_for_affixes(pagename, lang, sc)
return affix_type == "Hậu tố"
end
end
local clitic_label
if args.clitic then
clitic_label = require(yesno_module)(args.clitic, args.clitic)
end
if clitic_label == true then
clitic_label = "clitic"
end
if clitic_label then
headdata:insert_category("clitics")
headdata:insert_fixed_inflection(clitic_label)
elseif args.suffix or (
not args.nosuffix and pagename_is_suffix() and pos_category ~= "Hậu tố" and pos_category ~= "Biến thể hình thái hậu tố"
) then
headdata.process_props.is_suffix = true
local function handle_suffix_pos(pos, is_first)
-- Use the actual POS for the label we insert, but simplify the POS for the category. We need to separately check
-- each of them to see if they end in 'forms' because e.g. 'comparative adjectives' gets simplified to
-- 'adjective forms'.
local form_type = pos:match("^Biến thể hình thái (.*)$")
if form_type then
headdata:insert_fixed_inflection("Dạng hậu tố " .. form_type)
else
local singular_pos = require(en_utilities_module).singularize(pos)
headdata:insert_category(("%s-forming suffixes"):format(singular_pos))
headdata:insert_fixed_inflection(singular_pos .. "-forming suffix")
end
local simplified_pos = export.simplify_pos(pos, "preserve_lemma_status", "preserve_proper_nouns")
local simplified_form_type = simplified_pos:match("^(.*) forms$")
if simplified_form_type then
headdata:insert_category(("%s suffix forms"):format(simplified_form_type))
else
local singular_simplified_pos = require(en_utilities_module).singularize(simplified_pos)
headdata:insert_category(("%s-forming suffixes"):format(singular_simplified_pos))
end
local postype = require(headword_module).pos_lemma_or_nonlemma(pos)
if not postype then
postype = require(headword_module).pos_lemma_or_nonlemma(simplified_pos)
end
if not postype then
error(("Unrecognized canonicalized part of speech '%s' in addlpos=, cannot determine whether lemma or non-lemma form"):format(
pos
))
end
local this_pos_category = postype == "Mục từ" and "Hậu tố" or "Biến thể hình thái hậu tố"
if is_first then
headdata.pos_category = this_pos_category
elseif headdata.pos_category ~= this_pos_category then
local singular_normalized_this_pos_category =
require(en_utilities_module).singularize(this_pos_category)
local singular_normalized_overall_pos_category =
require(en_utilities_module).singularize(headdata.pos_category)
error(("Cannot mix suffixes and suffix forms using addlpos=; '%s' is of a %s while overall POS " ..
"'%s' is a %s; use separate POS headers for the two"):format(pos,
singular_normalized_this_pos_category, pos_category, singular_normalized_overall_pos_category))
end
end
handle_suffix_pos(pos_category, true)
if args.addlpos then
for _, addlpos in ipairs(split(args.addlpos, "%s*,%s*")) do
addlpos = require(headword_module).canonicalize_pos(addlpos)
handle_suffix_pos(addlpos, false)
end
end
end
if args.cat then
for _, cat in ipairs(split_on_comma(args.cat)) do
headdata:insert_category(cat)
end
end
local function augment_headdata_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local function process_labelobjs(labelobjs, originating_term, handle_labelobj)
if labelobjs == nil then
return
end
if type(labelobjs) ~= "string" and type(labelobjs) ~= "table" then
interr(("Wrong type '%s' for label object(s) %s, expected string or table"):format(
type(labelobjs), dump(labelobjs)
))
end
if type(labelobjs) == "string" or type(labelobjs) == "table" and not labelobjs[1] then
labelobjs = {labelobjs}
end
for _, labelobj in ipairs(labelobjs) do
local label, termobj
if type(labelobj) == "string" then
label = labelobj
termobj = originating_term
elseif type(labelobj) ~= "table" then
interr(("Wrong type '%s' for label object %s, expected string or table"):format(
type(labelobj), dump(labelobj)
))
label = labelobj.term
if type(label) ~= "string" then
interr(("Wrong type '%s' for label %s from label object %s, expected string"):format(
type(label), dump(label), dump(labelobj)
))
end
termobj = labelobj
end
handle_labelobj(label, termobj)
end
end
local param = infl[1]
if param then
local vals
-- Fetch the param and make sure it's a string or number.
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- Fetch the type and validate.
local typ = resolve_prop(infl.type)
if typ == nil then
typ = "string"
end
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
-- Fetch the value(s).
if typ == "genders" or typ == "boolean" then
vals = args[param]
elseif typ == "string" then
local parse_inflection_props = resolve_prop(infl.parse_inflection_props)
local include_mods = resolve_prop(infl.include_mods)
local no_augment_include_mods = resolve_prop(infl.no_augment_include_mods)
if include_mods ~= nil or no_augment_include_mods ~= nil then
if parse_inflection_props == nil then
parse_inflection_props = {}
else
parse_inflection_props = shallow_copy(parse_inflection_props)
end
if include_mods ~= nil then
parse_inflection_props.include_mods = include_mods
end
if no_augment_include_mods ~= nil then
parse_inflection_props.no_augment_include_mods = no_augment_include_mods
end
end
vals = headdata:parse_inflection(param, parse_inflection_props)
-- Convert an empty list to nil for consistent checking below.
if not vals[1] then
vals = nil
end
else
interr(("Unrecognized type '%s"):format(typ))
end
-- If value(s) nil, fetch the default.
if vals == nil and infl.default ~= nil then
local default = resolve_prop(infl.default)
if typ == "genders" then
vals = export.canonicalize_termobj_list(default, "spec", "default")
elseif typ == "boolean" then
vals = default
elseif typ == "string" then
vals = export.canonicalize_termobj_list(default, "term", "default")
else
interr(("Unrecognized type '%s"):format(typ))
end
end
-- Resolve "special" values (special signals a string values, such as requesting the default with "+").
if vals ~= nil and infl.resolve_special then
if typ ~= "string" then
interr(("Cannot specify resolve_special= for type %s"):format(dump(typ)))
end
local resolve_special_props = resolve_prop(infl.resolve_special_props, vals)
if infl.is_special ~= nil then
if resolve_special_props == nil then
resolve_special_props = {}
else
resolve_special_props = shallow_copy(resolve_special_props)
end
resolve_special_props.is_special = infl.is_special
end
vals = headdata:resolve_special(vals, infl.resolve_special, resolve_special_props)
end
-- Validate the value(s).
if vals ~= nil and infl.validate ~= nil then
if typ == "boolean" then
interr('Cannot specify validate= when type is "boolean"')
elseif type(infl.validate) == "function" then
infl.validate(headdata, vals)
elseif typ == "genders" then
headdata:validate_genders(vals, infl.validate)
elseif typ == "string" then
validate_items {
items = vals,
field = "term",
valid_items = infl.validate,
item_type = ("values in |%s="):format(param),
}
else
interr(("Unrecognized type '%s"):format(typ))
end
end
-- Run the process_after_parse handler, if it exists.
if vals ~= nil and infl.process_after_parse ~= nil then
local intentionally_nil
vals, intentionally_nil = infl.process_after_parse(headdata, vals)
if vals == nil and not intentionally_nil then
interr("If you return nil from process_after_parse, you must return a second non-nil return " ..
"value to indicate that the nil return value was intentional")
end
end
-- "Implement" the values, if non-falsy (i.e. we don't want to fire on boolean false or empty list).
-- If a fixed label is specified, insert it. Then, depending on the type, attach the values to a label
-- as an inflection, set the `genders` field, or do nothing if boolean (throwing an error if there was
-- no fixed label).
local insert_request = resolve_prop(infl.request, vals)
if vals == true or type(vals) == "table" and vals[1] or insert_request then
if infl.fixed_label and infl.all_fixed_label then
interr("Cannot specify both fixed_label= and all_fixed_label=; specify one or the other")
end
local function check_fixed_label_references_val(label)
if type(label) == "table" and label[1] then
for _, lab in ipairs(label) do
if check_fixed_label_references_val(lab) then
return true
end
end
return false
end
if type(label) == "table" then
if not label.term then
interr(("Fixed label structure %s does not have a value for `.term`"):format(dump(label)))
end
label = label.term
end
if type(label) ~= "string" then
interr(("Wrong type for fixed label %s, should be string"):format(type(label)))
end
return not not label:find("{val}")
end
local fixed_label = infl.fixed_label
local all_fixed_label = infl.all_fixed_label
-- If the value being processed is boolean, there's only one value so treat a fixed_label as an
-- all_fixed_label and output only once; likewise if the caller specified a fixed_label without
-- {val} in it.
if fixed_label and (typ == "boolean" or type(fixed_label) ~= "function" and not
check_fixed_label_references_val(fixed_label)) then
all_fixed_label = fixed_label
fixed_label = nil
end
local inserted_fixed_label
if fixed_label then
if typ == "boolean" then
interr("Boolean fixed_label values should have been converted to all_fixed_label")
end
for _, valobj in ipairs(vals) do
local labelobjs = resolve_prop(fixed_label, valobj)
process_labelobjs(labelobjs, valobj, function(label, termobj)
if label:find("{val}") then
if typ ~= "string" then
interr(('Cannot specify {val} in fixed_label %s when type is "%s"'):format(dump(label), typ))
end
label = label:gsub("{val}", replacement_escape(valobj.term))
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
inserted_fixed_label = true
end)
end
elseif all_fixed_label then
local labelobjs = resolve_prop(all_fixed_label, vals)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{vals}") then
if typ ~= "string" then
interr(('Cannot specify {vals} in all_fixed_label %s when type is "%s"'):format(dump(label), typ))
end
local formatted_labels = {}
for _, valobj in ipairs(vals) do
insert(formatted_labels, add_decorations(valobj.term, valobj, lang))
end
label = label:gsub("{vals}", replacement_escape(serial_comma_join(formatted_labels)))
end
headdata:insert_fixed_inflection(label, termobj)
inserted_fixed_label = true
end)
end
local inserted_vals
if infl.label ~= nil then
if typ ~= "string" then
interr(("label=%s can only be specified for type 'string', not '%s'"):format(
dump(infl.label), typ
))
end
local label = resolve_prop(infl.label, vals)
if label ~= nil then
local insert_inflection_props = resolve_prop(infl.insert_inflection_props, vals)
local function copy_to_insert_inflection_props(field, val)
local fieldval = val or resolve_prop(infl[field], vals)
if fieldval ~= nil then
if insert_inflection_props == nil then
insert_inflection_props = {}
else
insert_inflection_props = shallow_copy(insert_inflection_props)
end
insert_inflection_props[field] = fieldval
end
end
copy_to_insert_inflection_props("label_for_cats_and_modes")
copy_to_insert_inflection_props("no_auto_cats")
copy_to_insert_inflection_props("accel")
copy_to_insert_inflection_props("accel_form")
if insert_request then
copy_to_insert_inflection_props("request", insert_request)
end
local insert_spec = headdata:insert_inflection(vals, label, insert_inflection_props)
headdata.process_props.insert_specs[param] = insert_spec
inserted_vals = true
end
end
if typ == "genders" then
headdata.genders = vals
end
local inserted_cat
if infl.cat then
local allcats = {}
for _, valobj in ipairs(vals) do
local cats = resolve_prop(infl.cat, valobj)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
cat = cat:gsub("{val}", replacement_escape(valobj.term))
end
insert_if_not(allcats, cat)
end
end
end
for _, cat in ipairs(allcats) do
headdata:insert_category(cat)
inserted_cat = true
end
end
if typ == "boolean" then
if not inserted_fixed_label and not inserted_cat then
interr(("User set boolean setting for %s= but no fixed label added and no category " ..
"inserted; if you took action in process_after_parse(), make sure to return " ..
"`nil, true`"):format(param))
end
elseif typ == "string" then
if not inserted_vals and not inserted_fixed_label and not inserted_cat then
interr(("User set value(s) %s for %s= but no inflection inserted and no fixed label " ..
"or category added; if you took action in process_after_parse(), make sure to " ..
"return `nil, true`"):format(dump(vals), param))
end
end
end
else -- no param specified
if infl.label or infl.all_fixed_label then
interr("Cannot have label= or all_fixed_label= without specifying a param")
end
if infl.fixed_label then
local labelobjs = resolve_prop(infl.fixed_label)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{val}") then
interr("Cannot specify {val} in a fixed_label= value without specifying a param")
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
end)
end
if infl.cat then
local cats = resolve_prop(infl.cat)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
interr("Cannot specify {val} in a cat= value without specifying a param")
end
headdata:insert_category(cat)
end
end
end
end
end
end
if infls then
augment_headdata_from_infls(infls)
end
if augment_headdata then
augment_headdata(headdata, args)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_headdata_from_infls(pos_infls)
end
local func = pos_functions[indexing_pos].func
if func then
func(headdata, args)
end
end
headdata:parse_and_insert_inflection("abbr", "abbreviation")
setmetatable(headdata, nil)
headdata.process_props = nil
if args.json then
return require("Module:JSON").toJSON(headdata)
end
return require(headword_module).full_headword(headdata)
end
return export
ngt112aw0bayc31k4sxvr6v7ueh4hoi
2573062
2573055
2026-10-23T16:10:39Z
TheHighFighter2
42988
2573062
Scribunto
text/plain
local export = {}
--[==[
FIXME:
1. Implement ? = unknown or uncertain. There should be no label by default but it should be configurable.
The default category should be "{plpos} with unknown or uncertain plurals" for nouns/proper nouns. It should
be an error to specify values along with this.
2. Implement ! = unattested. The default label should be "{label} not attested". The default category should be
"{plpos} with unattested plurals" for nouns/proper nouns. It should be an error to specify values along with
this.
3. Implement +- = sometimes has a value, e.g. "countable and uncountable" for plurals.
4. Implement ~ standing for the pagename in heads and inflections. [DONE]
5. Implement abbr= for abbreviations. [DONE]
6. Extract from insert_inflection the logic to handle the special mode signals, determine the actual label and
category and the actual values without inserting them.
7. Support no_label for booleans.
8. Document the various types of parts of speech and implement pos_category per part of speech definition. [DONE]
9. Implement apply_link_modifiers() for head=~...
10. Correctly handle var=both. [DONE]
11. Implement checkredlinks and port simplify_pos to [[Module:headword]].
12. Fix longstanding accelerator bug: if embeddded links in inflection, don't make it green.
]==]
local require_when_needed = require("Module:utilities/require when needed")
local affix_module = "Module:affix"
local debug_track_module = "Module:debug/track"
local decorations_module = "Module:decorations"
local en_utilities_module = "Module:en-utilities"
local fun_is_callable_module = "Module:fun/isCallable"
local headword_module = "Module:headword"
local headword_data_module = "Module:headword/data"
local languages_module = "Module:languages"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local parse_interface_module = "Module:parse interface"
local parse_utilities_module = "Module:parse utilities"
local string_pattern_escape_module = "Module:string/patternEscape"
local string_replacement_escape_module = "Module:string/replacementEscape"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local yesno_module = "Module:yesno"
local dump = mw.dumpObject
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local insert = table.insert
local concat = table.concat
local remove = table.remove
local sort = table.sort
local deep_equals = require_when_needed(table_module, "deepEquals")
local extend = require_when_needed(table_module, "extend")
local insert_if_not = require_when_needed(table_module, "insertIfNot")
local list_to_set = require_when_needed(table_module, "listToSet")
local serial_comma_join = require_when_needed(table_module, "serialCommaJoin")
local shallow_copy = require_when_needed(table_module, "shallowCopy")
local split = require_when_needed(string_utilities_module, "split")
local ugsub = require_when_needed(string_utilities_module, "gsub")
local umatch = require_when_needed(string_utilities_module, "match")
local pattern_escape = require_when_needed(string_pattern_escape_module)
local replacement_escape = require_when_needed(string_replacement_escape_module)
local escape_wikicode = require_when_needed(parse_utilities_module, "escape_wikicode")
local parse_inline_modifiers = require_when_needed(parse_utilities_module, "parse_inline_modifiers")
local term_contains_top_level_html = require_when_needed(parse_utilities_module, "term_contains_top_level_html")
local get_lang_by_code = require_when_needed(languages_module, "getByCode")
local is_callable = require_when_needed(fun_is_callable_module)
local format_decorations = require_when_needed(decorations_module, "format_decorations")
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
--[==[ intro:
This module contains utilities for constructing language-specific headword modules.
[fill in]
===About parts of speech===
There are several versions of the part of speech (POS) of a given term:
* The ''primary categorizing POS'' is the basic part of speech to which a term belongs. The primary POS determines
whether the term is a lemma or non-lemma form, and in its plural form, it is used to categorize the terms (unless it
is a variant term), along with caetegorizing into a ''lemmas'' or ''non-lemma forms'' category. (Variant terms,
typically marked by {{para|var|1}}, are categorized into ''variant lemmas'' or ''variant non-lemma forms'' and are not
categorized into a primary POS category.)
* The ''raw {{tl|head}} POS'' is parameter {{para|2}} to {{tl|head}}. This is used to determine the primary categorizing
POS by a process of canonicalization, because this parameter may contain abbreviations (e.g. ''a'' or ''adj'' for an
adjective) and may be (and usually is) given in its singular form.
* The ''template-indicated POS'' is the part of speech indicated by a headword template such as {{tl|nl-noun}} or
{{tl|mn-head}}. It is either inherent to the template (in a case like {{tl|nl-noun}}), in which case it is specified
by the template code and should always be in canonical, plural form; or it is specified by the user in the template
call (in a case like {{tl|mn-head}} or other generic POS template, usually ending in `-head`), in which case it may
be given in raw form, like for the raw {{tl|head}} POS, and is canonicalized using the same code that canonicalizes
raw {{tl|head}} parts of speech. The template-indicate POS may not be a valid primary categorizing POS. For example,
Dutch has a template-indicated POS ''diminutiva tantum nouns'', specified through the template {{tl|nl-dim-tant}}, but
there is no such primary categorizing POS (that POS would be `nouns`). Similarly, Arabic has a template-indicated POS
''collective nouns'', whose primary categorizing POS is also `nouns`. As a result, the template-indicated POS may need
to be converted to a primary categorizing POS through a ''normalization'' process (which uses a `pos_category` field
attached to the `pos_functions` structure for the template-indicated POS). Note that the template-indicated POS comes
in several variants:
*# It may be ''head-raw'', meaning that it uses the literal string `head` in place of the user-specified POS in a
generic POS template like {{tl|mn-head}}; it may be ''non-head'', meaning that it uses the actual user-specified
POS in such a case; or it may be ''head-augmented'', meaning that in the case of a generic POS template it is of the
form e.g. `head.nouns`, contanining both the literal `head` and the user-specified POS.
*# It may be ''suffix-raw'', meaning that it uses the primary categorizing POS `suffixes` in place of the
template-indicated POS when the term is a suffix, or it may be ''non-suffix'', meaning that it uses the
template-indicated POS in such a case. The headword for a suffix uses the template corresponding to whatever POS the
suffix forms, e.g. {{nl-noun}} for Dutch noun-forming suffixes.
*# The ''indexing POS'' is the variant of the template-indicated POS that is used to index into the `pos_functions`
table. Normally it is head-raw and non-suffix, but it will be head-augmented if the corresponding head-augmented
entry exists in `pos_functions`.
*# The ''unnormalized categorizing POS'' is the variant of the template-indicated POS that is potentially usable as the
primary categorizing POS (see above). It is non-head and suffix-raw, i.e. it uses the actual template-specified or
user-specified form of the template-indicated POS except when the term is a suffix, in which case it has the value
`suffixes`. In most circumstances this can be used directly as the primary categorizing POS, but in some cases this
POS is not a valid primary categorizing POS and needs to be normalized to get the actual primary categorizing POS, as
mentioned above under the description for the template-indicated POS.
* Finally, there is a ''simplified categorizing POS''. This collapses variations of primary categorizing parts of speech
together for use in red-link and similar categories. For example, the POS `proper nouns` is collapsed into `nouns`,
and all types of participles are collapsed into `participles`. There are two variants of the simplification process,
''lemma-status-preserving'' and ''non-lemma-status-preserving''. The latter is the default and is simpler, in that
e.g. it means any part of speech ending in `nouns` to `nouns`, even if this causes non-lemma forms to become lemmas,
as with `diminutive nouns` and `verbal nouns` (which are non-lemma forms) and likewise with `comparative adjectives`
and `superlative adjectives` (which are again non-lemma forms). The former, ''lemma-status-preserving'', keeps lemmas
as lemmas and (more important) non-lemmas as non-lemmas by converting e.g. `diminutive nouns` and `verbal nouns` to
`noun forms` rather than `nouns`. The reason two variants exist in that they have different use cases. The default,
non-lemma-status-preserving, type is used for tracking categories such as red-link and request categories, where
completeness is more important than clutter. The lemma-status-preserving variant is used for informative categories
such as ` ``lang`` masculine nouns`, which should only have lemmas in them to avoid clutter. (For the same reason,
variant terms specified using {{para|var|1}} aren't normally categorized into informative categories but are placed
in tracking categories.)
===About properties and data objects===
[fill in]
]==]
--[=[
Add decorations to a term. `termobj` is the object describing the term, which should optionally contain:
* left qualifiers in `q`, an array of strings;
* right qualifiers in `qq`, an array of strings;
* left labels in `l`, an array of strings;
* right labels in `ll`, an array of strings;
* references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text`
(formatted reference text) and optionally `name` and/or `group`;
`text` is the text of the term itself, and `lang` is the language object.
]=]
local function add_decorations(text, termobj, lang)
local function field_non_empty(field)
local list = termobj[field]
if not list then
return nil
end
if type(list) ~= "table" then
error(("Internal error: Wrong type for `termobj.%s`=%s, should be \"table\""):format(
field, mw.dumpObject(list)))
end
return list[1]
end
if field_non_empty("q") or field_non_empty("qq") or field_non_empty("l") or field_non_empty("ll") or
field_non_empty("refs") then
text = format_decorations {
lang = lang,
text = text,
q = termobj.q,
qq = termobj.qq,
l = termobj.l,
ll = termobj.ll,
refs = termobj.refs,
}
end
return text
end
local param_mods = {
alt = {}, -- always allow so e.g. - can be specified as a suffix form
id = {}, -- disabled when `is_head = true`
q = {type = "qualifier"},
qq = {type = "qualifier"},
l = {type = "labels"},
ll = {type = "labels"},
-- [[Module:headword]] expects part references in `.refs`.
ref = {item_dest = "refs", type = "references", store = "insert-flattened"},
}
local optional_param_mods = {
g = {item_dest = "genders", type = "genders"},
lang = {type = "language"},
sc = {type = "script"},
t = {item_dest = "gloss"},
gloss = {},
pos = {},
lit = {},
tr = {},
ts = {},
face = {},
nolinkinfl = {type = "boolean"},
}
local optional_headword_param_mods = {
sc = {type = "script"},
tr = {},
ts = {},
}
--[==[
Parse a single inflection or headword form or list of such forms. In either case, inline modifiers may be attached.
`data` is an object with the following fields:
* `val`: The raw value to parse. Required.
* `paramname`: The name of the parameter from which the value was taken; used in error messages. Required.
* `is_head`: We are parsing a headword parameter (a value which goes into the `heads` field of `data`). This changes
the allowed modifiers, disabling the `id` modifier and only allowing a subset of optional modifiers.
* `frob`: An optional function of one value to apply to the form after inline modifiers have been removed (i.e. to
apply to the `.term` field of the returned object).
* `include_mods`: List of extra inline modifiers to include, besides the default ones (see below). Each list item is
either a string specifying a recognized extra inline modifier (see `optional_param_mods` in the code), or a two-item
list of modifier name and modifier spec, where the spec should follow the syntax for modifier specs in
`parse_inline_modifiers` in [[Module:parse utilities]].
* `exclude_mods`: List of default inline modifiers to not include.
* `splitchar`: If specified, the value in `val` can be a list of forms to parse, separated by the value of `splitchar`
(which is a Lua pattern, as in `parse_inline_modifiers` in [[Module:parse utilities]]). Most commonly, `splitchar` is
a single comma and the values are comma-separated (in this case, splitting will not happen if a space follows the
comma).
* `parse_lang_prefix`: If specified, allow a language prefix to precede a form, and if found, store into the `.lang`
field of the returned object.
* `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in
`parse_inline_modifiers` in [[Module:parse utilities]].
Returns an object suitable for storing as one element of one of the lists in `headdata.inflections`, where `headdata`
is the structure passed to [[Module:headword]]. If `splitchar` is specified, howeve, the return value is a list of such
objects.
The following default inline modifiers are currently recognized:
* `q`: Left qualifier.
* `qq`: Right qualifier.
* `l`: Comma-separated list of left labels. No space should follow the comma.
* `ll`: Comma-separated list of right labels. No space should follow the comma.
* `ref`: Reference or references. See {{tl|IPA}} for the syntax.
* `id`: Sense ID, in case there are multiple senses. See {{tl|l}}.
The following are the recognized additional inline modifiers:
* `g`: Comma-separated list of genders.
* `alt`: Display text.
* `lang`: Language code of language of the form, if different from the language of the headword.
* `sc`: Script code of script of the form. Almost never needed.
* `t`: Gloss for the form.
* `gloss`: Gloss for the form (alias for `t`).
* `pos`: Part of speech of the form.
* `lit`: Literal meaning of the form.
* `tr`: Manual transliteration of the form.
* `ts`: Transcription of the form, for languages where the transliteration differs markedly from the pronunciation.
* `face`: Face to display the form in, e.g. {"hypothetical"} for a hypothetical form (unlinkable and displayed in italics).
* `nolinkinfl`: Make the form unlinkable.
]==]
function export.parse_term_with_modifiers(data)
local paramname, val, frob = data.paramname, data.val, data.frob
local function generate_obj(term, parse_err)
if frob then
term = frob(term, parse_err)
end
if data.parse_lang_prefix and term:find(":") then
return require(parse_utilities_module).generate_obj_maybe_parsing_lang_prefix {
term = term,
paramname = paramname,
parse_lang_prefix = true,
parse_err = parse_err,
}
else
return {term = term}
end
end
-- Check for inline modifier, e.g. מרים<tr:Miryem>. But exclude top-level HTML entry with <span ...>,
-- <sup> or similar in it.
if (val:find("<", nil, true) or data.splitchar) and not term_contains_top_level_html(val) and
-- don't parse inline modifiers if is_head and the value begins with a ~ (link modifier syntax)
(not data.is_head or not val:find("^~")) then
local param_mods = param_mods
if data.is_head then
param_mods = shallow_copy(param_mods)
param_mods.id = nil
end
if data.include_mods or data.exclude_mods then
if not data.is_head then
-- already copied when data.is_head
param_mods = shallow_copy(param_mods)
end
if data.include_mods then
local optional_mods = data.is_head and optional_headword_param_mods or optional_param_mods
for _, mod in ipairs(data.include_mods) do
if type(mod) == "table" then
if #mod ~= 2 then
error(("Internal error: Modifier spec %s in `include_mods` should be of length 2"):format(
dump(mod)))
end
local modkey, modvalue = unpack(mod)
param_mods[modkey] = modvalue
elseif not optional_mods[mod] then
error(("Internal error: Unrecognized modifier spec %s in `include_mods`"):format(
dump(mod)))
else
param_mods[mod] = optional_mods[mod]
end
end
end
if data.exclude_mods then
for _, mod in ipairs(data.exclude_mods) do
if not param_mods[mod] then
error(("Internal error: Modifier spec %s in `exclude_mods` not found among existing modifiers"
):format(dump(mod)))
else
param_mods[mod] = nil
end
end
end
end
return parse_inline_modifiers(val, {
paramname = paramname,
param_mods = param_mods,
generate_obj = generate_obj,
splitchar = data.splitchar,
preserve_splitchar = data.preserve_splitchar,
delimiter_key = data.delimiter_key,
escape_fun = data.escape_fun,
unescape_fun = data.unescape_fun,
pre_normalize_modifiers = data.pre_normalize_modifiers,
})
else
local retval = generate_obj(val)
if data.splitchar then
retval = {retval}
end
return retval
end
end
--[==[
Parse a list of inflection forms that may have inline modifiers attached. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. Required.
* `paramname`: The name of the first parameter from which the value was taken; used in error messages. If this is a
two-element list, the first element is the first parameter and the second element is the prefix of the remaining
parameters. Parameter names that are numbers are handled correctly, as are those with \1 in it marking where the
parameter index goes. Required.
* `qualifiers`: If specified, a possibly gappy list of left qualifiers to add to the parsed terms (for compatibility
purposes).
* `splitchar`: As in `parse_term_with_modifiers()`. The resulting per-term lists will be flattened.
* `frob`, `include_mods`, `exclude_mods`, `is_head`, `preserve_splitchar`, `parse_lang_prefix`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_with_modifiers()`.
Returns a list of objects, suitable for storing as one of the lists in `headdata.inflections` (once a label is added),
where `headdata` is the structure passed to [[Module:headword]].
]==]
function export.parse_term_list_with_modifiers(data)
local paramname, forms = data.paramname, data.forms
local qualifiers = data.qualifiers
local first, restpref
if type(paramname) == "table" then
first = paramname[1]
restpref = paramname[2]
else
first = paramname
restpref = paramname
end
local terms = {}
data = shallow_copy(data)
for i, val in ipairs(forms) do
data.paramname = i == 1 and first or type(restpref) == "number" and restpref + i - 1 or
restpref:find("\1", nil, true) and restpref:gsub("\1", tostring(i)) or restpref .. i
data.val = val
local parsed = export.parse_term_with_modifiers(data)
if qualifiers and qualifiers[i] then
if data.splitchar then
for _, term in ipairs(parsed) do
term.q = {qualifiers[i]}
end
else
parsed.q = {qualifiers[i]}
end
end
if data.splitchar then
extend(terms, parsed)
else
terms[i] = parsed
end
end
return terms
end
--[==[
Construct a link to [[Appendix:Glossary]] for `entry`. If `text` is specified, it is the display text; otherwise,
`entry` is used.
]==]
function export.glossary_link(entry, text)
text = text or entry
return "[[Phụ lục:Từ điển thuật ngữ#" .. entry .. "|" .. text .. "]]"
end
function export.replace_glossary_links_in_label(label)
if label:find("<<", nil, true) then
label = label:gsub("<<(.-)|(.-)>>", export.glossary_link):gsub("<<(.-)>>", export.glossary_link)
end
return label
end
-- If a part of speech ends with one of these, either pluralized or followed by ' forms', chop off whatever precedes.
-- Also, if a part of speech is of the form `BASIC_POS FOO forms` e.g. `noun construct forms`, remove the `FOO`
-- portion. Note that "phrase" is *NOT* listed here because 'prepositional phrase' and 'postpositional phrase' are not
-- types of 'phrase' per the definition of these parts of speech in Wiktionary.
local basic_poses = {
"Tính từ",
"Phó từ",
"Từ rút gọn",
"Danh từ riêng",
"Danh từ",
"Phân từ",
"Đại từ",
"Ký hiệu",
"Động từ",
}
--[==[
Canonicalize and then simplify a part of speech by removing adjectival qualifiers. This converts e.g.
`proper noun(s)` -> `nouns`, `comparative adjective(s)` -> `adjectives`, `past participle form(s)` -> `participle forms`
and `pronoun possessive form(s)` -> `pronoun forms`. (The one exception is with phrases. In Wiktionary, ''phrase''
really means a clause or similar constituent or occasionally non-constituent, so `prepositional phrases` are not types
of `phrases`.) Its purpose is for use in categorization, since generally the simplified part of speech is used in
categories other than the one for the part of speech itself. (For example, proper nouns are normally categorized under
` ``lang`` nouns with ...` rather than ` ``lang`` proper nouns with ...`.) The returned part of speech is in plural
form.
]==]
local function optimized_pattern_escape(pos)
if pos:find("-", nil, true) then
return pattern_escape(pos)
else
return pos
end
end
--[==[
Convert a qualified part of speech (e.g. ''proper nouns'', ''past participles'') to its unqualified equivalent (e.g.
''nouns'' or ''participles''). If `preserve_proper_nouns` is given, ''proper nouns'' is left as-is rather than being
converted to ''nouns''. If `preserve_lemma_status` is given, the function attempts to return a POS that has the same
lemma status (lemma or non-lemma form) as the original POS; thus, ''comparative adjectives'' becomes ''adjective forms''
and ''diminutive nouns'' becomes ''noun forms'' because both are non-lemma forms. If `preserve_lemma_status` is not
given, the function simply chops off the qualifiers, converting e.g. ''comparative adjectives'' to ''adjectives'' even
though this changes the lemma status of the POS.
]==]
function export.simplify_pos(pos, preserve_lemma_status, preserve_proper_nouns)
-- This allows for both singular and plural parts of speech in 'pos'.
local plpos = require(headword_module).canonicalize_pos(pos)
for _, basic_pos in ipairs(basic_poses) do
if basic_pos ~= "Danh từ riêng" or preserve_proper_nouns then
if plpos == "Biến thể hình thái " .. basic_pos then
-- So 'proper noun forms' doesn't get converted to 'noun forms' in the next round
return plpos
end
local basic_pos_pattern = optimized_pattern_escape(basic_pos)
if plpos:find(("^Biến thể hình thái %s .*.$"):format(basic_pos_pattern)) then
return "Biến thể hình thái " .. basic_pos
end
if plpos:find(("^.* %s forms$"):format(basic_pos_pattern)) then
return basic_pos .. " forms"
end
local pl_basic_pos = require(headword_module).pluralize_pos(basic_pos)
if plpos == pl_basic_pos then
-- So 'proper nouns' doesn't get converted to 'nouns' in the next round
return plpos
end
local pl_basic_pos_pattern = optimized_pattern_escape(pl_basic_pos)
if plpos:find(("^.* %s$"):format(pl_basic_pos_pattern)) then
if preserve_lemma_status then
local lemma_status = require(headword_module).pos_lemma_or_nonlemma(plpos)
if lemma_status == "non-lemma form" then
return "Biến thể hình thái " .. basic_pos
end
end
return pl_basic_pos
end
end
end
return plpos
end
--[==[
Insert a fixed inflection (a label not associated with any inflection values) into an `inflections` field. The
`inflections` field will be initialized if needed. `data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `originating_term`: The term object from which this label is derived. If specified, decorations will be taken from
this object.
]==]
function export.insert_fixed_inflection(data)
local headdata, origterm, label = data.headdata, data.originating_term, data.label
local inflobj = data.inflobj or headdata
inflobj.inflections = inflobj.inflections or {}
if not origterm then
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label)
})
else
if origterm.id then
error(("It doesn't make sense to pass in an ID '%s' for label '%s' in conjunction with a term value '%s'"
):format(origterm.id, label, origterm.term))
end
origterm = shallow_copy(origterm)
-- Preserve decorations
origterm.term = nil
origterm.label = export.replace_glossary_links_in_label(label)
insert(inflobj.inflections, origterm)
end
end
--[==[
Insert previously-parsed terms into an `inflections` field. The `inflections` field will be initialized if needed.
`data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `terms`: The list of parsed terms. If {nil} or omitted, nothing happens unless `request` is set.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `fixed_adj_label`: If specified, an adjective used to construct the defaults for the fixed labels specified by
`no_label`, `usually_no_label` and `sometimes_label`. Examples are "comparable" for a comparative and "countable"
for a plural.
* `no_label`: If the term is {"-"} and there are no other terms, insert a fixed label with this value. If
`fixed_adj_label` is given, defaults to {"not "} plus the adjective, else {"no "} plus the label.
* `usually_no_label`: If the term is {"-"} and there are other terms, insert a fixed label with this value. Defaults to
{"usually "} plus the value of `no_label`.
* `sometimes_label`: If the term is {"+-"}, insert a fixed label with this value. If `fixed_adj_label` is given,
defaults to {"sometimes "} plus the adjective, else {"sometimes with a(n) "} plus the label.
* `cats`: List of categories to insert when terms are given that are not {"-"}. Each category is a string naming a full
category to insert (including the appropriate language name prefixed).
* `no_cats`: List of categories to insert when a term is given as {"-"}.
* `usually_no_cats`: List of categories to insert when a term is given as {"-"} and additional terms are specified as
well (representing, e.g. for the inflection {"plural"}, a term which usually has no plural but does under some
circumstances). If omitted, both the categories in `cats` and `no_cats` are inserted.
* `sometimes_cats`: List of categories to insert when a term is given as {"+-"} (indicating that the inflection
sometimes exists and sometimes does not, normally depending on the precise sense involved). If omitted, both the
categories in `cats` and `no_cats` are inserted (same default as for `usually_no_cats`).
* `accel`: If specified, a full accelerator object to add to the inflections.
* `request`: If specified and no terms are given, insert a label with a request for inflections to be given.
* `enable_auto_translit`: If specified and terms are given, display automatic transliteration of the terms.
The return value indicates whether the inflection exists and how many terms are in it. It is an object with the
following fields:
* `exists`: {"yes"} if one or more terms were specified; {"no"} if the value was given as {"-"}; {"usually no"} if
the first value was given as {"-"} but additional terms were supplied; otherwise {nil}, indicating that the status
is unspecified.
* `numterms`: Number of terms in the inflection. Will be 0 unless `exists` has the value {"yes"} or {"usually no"}.
* `terms`: The terms that were inserted. If there are no terms, this is an empty list.
* `request`: True if no terms were specified but a term request was inserted into the inflection (because
`data.request` was specified). Otherwise {nil}.
]==]
function export.insert_inflection(data)
local headdata, terms, label = data.headdata, data.terms, data.label
local inflobj = data.inflobj or headdata
local retval = {}
local accel = data.accel
if data.accel_form then
if accel then
error("Internal error: can't specify both data.accel and data.accel_form")
end
if headdata.heads then
local lemmas = {}
local lemma_translits = {}
for i, headobj in ipairs(headdata.heads) do
lemmas[i] = headobj.term
if lemmas[i] == "+" then
error("Internal error: If you use data.accel_form, you should have resolved all occurrences of + in heads appropriately")
end
lemma_translits[i] = headobj.tr
end
accel = {
lemma = lemmas,
lemma_translit = lemma_translits,
form = data.accel_form,
}
else
accel = {
form = data.accel_form,
}
end
end
local function insert_cats(cats)
for _, cat in ipairs(cats) do
insert(headdata.categories, cat)
end
end
if terms and terms[1] then
terms = shallow_copy(terms)
if terms[1].term == "-" then
if terms[2] then
export.insert_fixed_inflection {
headdata = headdata,
inflobj = inflobj,
originating_term = terms[1],
label = data.usually_no_label or "thường không " .. label,
}
remove(terms, 1)
retval.numterms = #terms
retval.exists = "thường không"
if data.usually_no_cats then
insert_cats(data.usually_no_cats)
else
if data.no_cats then
insert_cats(data.no_cats)
end
if data.cats then
insert_cats(data.cats)
end
end
else
export.insert_fixed_inflection {
headdata = headdata,
inflobj = inflobj,
originating_term = terms[1],
label = data.no_label or "không " .. label,
}
retval.numterms = 0
retval.terms = {}
retval.exists = "không"
if data.no_cats then
insert_cats(data.no_cats)
end
return retval
end
else
retval.numterms = #terms
retval.exists = "có"
if data.cats then
insert_cats(data.cats)
end
end
if data.check_missing then
error("Internal error: check_missing support removed; use checkredlinks=true in [[Module:headword]]")
end
terms.label = export.replace_glossary_links_in_label(label)
if accel then
terms.accel = accel
end
terms.enable_auto_translit = data.enable_auto_translit
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, terms)
retval.terms = terms
elseif data.request then
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label),
request = true,
})
retval.numterms = 0
retval.terms = {}
-- retval.exists = nil
retval.request = true
else
retval.numterms = 0
retval.terms = {}
-- retval.exists = nil
end
return retval
end
--[==[
Parse raw arguments from `forms` for inline modifiers, and insert the resulting terms (which should not require
significant additional processing) into `headdata.inflections`. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. If {nil} or omitted, nothing happens.
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `paramname`: As in `parse_term_list_with_modifiers()`. Required.
* `label`: As in `insert_inflection()`. Required.
* `qualifiers`, `frob`, `include_mods`, `exclude_mods`, `is_head`, `splitchar`, `preserve_splitchar`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_list_with_modifiers()`.
* `accel`: As in `insert_inflection()`.
Return value is as in `insert_inflection()`.
]==]
function export.parse_and_insert_inflection(data)
local forms = data.forms
if forms and forms[1] then
data = shallow_copy(data)
data.forms = forms
data.terms = export.parse_term_list_with_modifiers(data)
return export.insert_inflection(data)
end
return {
numterms = 0
}
end
--[==[
Canonicalize a single term or term-like object or a list of either into a list of term-like objects. `abterms` is the
term or list to canonicalize, and `field` is the name of the field holding the term (defaulting to {"term"}). This
does the minimal work necessary, meaning that the return value may partly or completely share memory with the value
passed in. As a special case, if `abterms` is {nil}, {nil} is returned. If `origin` or `originating_term` are specified,
add fields `origin` and/or `originating_term` containing the specified value(s) to each resulting term-like object (in
this case, the object will be copied a necessary to avoid side-effecting the passed-in objects). `origin` is intended to
be a string indicating where the term originated from (e.g. {"default"} if a default value, {"resolve_special"} if
originating from a shortcut value such as {"+"}) and `originating_term` is the shortcut term itself, if any. (There is
generally no such term for default values.)
]==]
function export.canonicalize_termobj_list(abterms, field, origin, originating_term)
if abterms == nil then
return nil
end
field = field or "term"
if type(abterms) == "string" then
return {{[field] = abterms, origin = origin, originating_term = originating_term}}
elseif not abterms[1] then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy(abterms)
abterms.origin = origin
abterms.originating_term = originating_term
end
return {abterms}
else
-- Check if already in full list term and return directly if so (unless `origin_val` is given, in which case we
-- need to shallow-copy both the list and each term in it).
local must_convert = false
for _, term in ipairs(abterms) do
if type(term) == "string" then
must_convert = true
break
end
end
if not must_convert then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy(abterms)
for i, abterm in ipairs(abterms) do
abterms[i] = shallow_copy(abterm)
abterms[i].origin = origin
abterms[i].originating_term = originating_term
end
end
return abterms
end
end
local retval = {}
for _, term in ipairs(abterms) do
if type(term) == "string" then
insert(retval, {[field] = term, origin = origin, originating_term = originating_term})
else
if origin ~= nil or originating_term ~= nil then
term = shallow_copy(term)
term.origin = origin
term.originating_term = originating_term
end
insert(retval, term)
end
end
return retval
end
--[==[
Combine two sets of decorations. If either is {nil}, just return the other, and if both are {nil}, return {nil}.
]==]
function export.combine_decorations(decs1, decs2)
if not decs1 and not decs2 then
return nil
end
if not decs1 then
return decs2
end
if not decs2 then
return decs1
end
local combined = shallow_copy(decs1)
for _, dec in ipairs(decs2) do
insert_if_not(combined, dec)
end
return combined
end
function export.combine_qualifiers_or_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng combine_decorations")
end
--[==[
Combine the decorations (qualifiers, labels, references) and ID's of two term objects. `destobj` is the "destination
term object" into which the combined properties are written, and `srcobj` is the "source object" into which the
properties are merged. `destobj` is side-effected (but the lists inside of `destobj` are not); if this is undesirable,
make sure to shallow-copy `destobj` first. If both objects have values for a given decoration, the values of `destobj`
come first. If both objects have a value for `id`, the values must match or an error is thrown; otherwise, the resulting
value of `id` comes from whichever one is defined.
'''NOTE:''' This may not be the correct behavior when deduplicating a list of term objects. See
`insert_termobj_combining_duplicates` for a different approach.
]==]
function export.combine_termobj_decorations(destobj, srcobj)
destobj.q = export.combine_decorations(destobj.q, srcobj.q)
destobj.qq = export.combine_decorations(destobj.qq, srcobj.qq)
destobj.l = export.combine_decorations(destobj.l, srcobj.l)
destobj.ll = export.combine_decorations(destobj.ll, srcobj.ll)
destobj.refs = export.combine_decorations(destobj.refs, srcobj.refs)
if destobj.id and srcobj.id and destobj.id ~= srcobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(srcobj.id, destobj.id))
end
destobj.id = destobj.id or srcobj.id
return destobj
end
function export.combine_termobj_qualifiers_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng combine_termobj_decorations")
end
function export.termobj_has_decorations(obj)
return obj.q and obj.q[1] or obj.qq and obj.qq[1] or obj.l and obj.l[1] or obj.ll and obj.ll[1] or
obj.refs and obj.refs[1]
end
function export.termobj_has_qualifiers_or_labels(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng termobj_has_decorations")
end
local function one_decoration_equal(prop1, prop2)
local prop1_is_nil = not prop1 or not prop1[1]
local prop2_is_nil = not prop2 or not prop2[1]
if prop1_is_nil and prop2_is_nil then
return true
end
if prop1_is_nil or prop2_is_nil then
return false
end
return deep_equals(prop1, prop2)
end
function export.termobj_decorations_equal(obj1, obj2)
return one_decoration_equal(obj1.q, obj2.q) and
one_decoration_equal(obj1.qq, obj2.qq) and
one_decoration_equal(obj1.l, obj2.l) and
one_decoration_equal(obj1.ll, obj2.ll) and
one_decoration_equal(obj1.refs, obj2.refs) and
obj1.id == obj2.id
end
function export.termobj_ancillary_properties_equal(...)
-- FIXME: Đã thêm vào ngày 25 tháng 9 năm 2026.
error("Vui lòng dùng termobj_decorations_equal")
end
function export.convert_termobj_to_formobj(termobj)
local formobj = {
form = termobj.term,
translit = termobj.tr,
}
local footnotes
local function mods_to_footnote(mod_prefix, mod_vals)
if mod_vals and mod_vals[1] then
footnotes = footnotes or {}
for _, val in ipairs(mod_vals) do
insert(footnotes, "[" .. mod_prefix .. ":" .. val .. "]")
end
end
end
mods_to_footnote("q", termobj.q)
mods_to_footnote("qq", termobj.qq)
mods_to_footnote("l", termobj.l)
mods_to_footnote("ll", termobj.ll)
mods_to_footnote("ref", termobj.refs)
mods_to_footnote("id", termobj.id and {termobj.id} or nil)
formobj.footnotes = footnotes
return formobj
end
local recognized_multi_mods = {
q = "q",
qq = "qq",
l = "l",
ll = "ll",
ref = "refs",
}
local recognized_single_mods = {
id = "id",
}
function export.add_footnote_to_termobj(termobj, footnote)
local stripped_footnote = footnote:match("^%[(.*)%]$")
if not stripped_footnote then
error("Internal error: Footnote should be surrounded by brackets at this stage: " .. footnote)
end
local prefix, rest = stripped_footnote:match("^([a-z]+):(.+)$")
local field, is_multi
if prefix then
if recognized_multi_mods[prefix] then
field = recognized_multi_mods[prefix]
is_multi = true
elseif recognized_single_mods[prefix] then
field = recognized_single_mods[prefix]
is_multi = false
end
end
if not field then
rest = stripped_footnote
field = "l"
is_multi = true
end
if is_multi then
if not termobj[field] then
termobj[field] = {}
end
insert(termobj[field], rest)
else
if termobj[field] and termobj[field] ~= rest then
error(("Không thể đặt hai giá trị của '%s': '%s' và '%s'"):format(field, termobj[field], rest))
end
termobj[field] = rest
end
end
function export.convert_formobj_to_termobj(formobj)
local termobj = {
term = formobj.form,
tr = formobj.translit,
}
if formobj.footnotes then
for _, footnote in ipairs(formobj.footnotes) do
export.add_footnote_to_termobj(termobj, footnote)
end
end
return termobj
end
local function extract_termobj_field_modifiers(fieldval)
return fieldval:match("^([*+]?)(.*)$")
end
function export.remove_termobj_field_modifiers(termobj)
local function remove_field_modifiers(field)
if termobj[field] and termobj[field][1] then
local any_field_modifiers = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods ~= "" then
any_field_modifiers = true
break
end
end
local new_field = {}
if any_field_modifiers then
for _, val in ipairs(termobj[field]) do
local _, field_without_mods = extract_termobj_field_modifiers(val)
insert_if_not(new_field, field_without_mods)
end
termobj[field] = new_field
end
end
end
remove_field_modifiers("q")
remove_field_modifiers("qq")
remove_field_modifiers("l")
remove_field_modifiers("ll")
remove_field_modifiers("refs")
end
function export.insert_termobj_combining_duplicates(destobjs, termobj)
for _, destobj in ipairs(destobjs) do
if destobj.term == termobj.term and destobj.tr == termobj.tr then
-- Form already present; maybe combine footnotes.
local function combine_field_values(field)
if termobj[field] and termobj[field][1] then
-- Check to see if there are existing values with *; if so, remove them.
if destobj[field] and destobj[field][1] then
local any_values_with_asterisk = false
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%*") then
any_values_with_asterisk = true
break
end
end
if any_values_with_asterisk then
local filtered_values = {}
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if not field_mods:find("%*") then
insert(filtered_values, val)
end
end
if filtered_values[1] then
destobj[field] = filtered_values
else
destobj[field] = nil
end
end
end
local any_footnotes_with_plus = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
any_footnotes_with_plus = true
break
end
end
if any_footnotes_with_plus then
if not destobj[field] then
destobj[field] = {}
else
destobj[field] = shallow_copy(destobj[field])
end
for _, val in ipairs(termobj[field]) do
local already_seen = false
local field_mods, field_without_mods = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
for _, existing_val in ipairs(destobj[field]) do
local _, existing_field_without_mods =
extract_termobj_field_modifiers(existing_val)
if existing_field_without_mods == field_without_mods then
already_seen = true
break
end
end
if not already_seen then
insert(destobj[field], val)
end
end
end
end
end
end
combine_field_values("q")
combine_field_values("qq")
combine_field_values("l")
combine_field_values("ll")
combine_field_values("refs")
if destobj.id and termobj.id and destobj.id ~= termobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(termobj.id, destobj.id))
end
destobj.id = destobj.id or termobj.id
return
end
end
insert(destobjs, termobj)
end
export.allowed_special_indicators = {
["first"] = true,
["first-second"] = true,
["first-last"] = true,
["second"] = true,
["last"] = true,
["each"] = true,
["+"] = true, -- requests the default behavior with preposition handling
}
--[==[
Check for special indicators (values such as {"+first"} or {"+first-last"} that are used in a `pl`, `f`, etc. argument
and indicate how to inflect a multiword term). If `form` is such an indicator, the return value is `form` minus
the initial `+` sign; otherwise, if form begins with a `+` sign, an error is thrown; otherwise the return value is nil.
]==]
function export.get_special_indicator(form, noerror)
if form:find("^%+") then
form = form:gsub("^%+", "")
if not export.allowed_special_indicators[form] then
if noerror then
return nil
end
local indicators = {}
for indic, _ in pairs(export.allowed_special_indicators) do
insert(indicators, "+" .. indic)
end
sort(indicators)
error("Special inflection indicator beginning with '+' can only be " ..
mw.text.listToText(indicators) .. ": +" .. form)
end
return form
end
return nil
end
local function add_endings(bases, endings)
local retval = {}
if type(bases) ~= "table" then
bases = {bases}
end
if type(endings) ~= "table" then
endings = {endings}
end
for _, base in ipairs(bases) do
for _, ending in ipairs(endings) do
insert(retval, base .. ending)
end
end
return retval
end
--[==[
Inflect a possibly multiword or hyphenated term `form` using the function `inflect`, which is a function of one argument
that is called on a single word to inflect and should return either the inflected word or a list of inflected words.
`special` indicates how to inflect the multiword term and should be e.g. {"first"} to inflect only the first word,
{"first-last"} to inflect the first and last words, {"each"} to inflect each word, etc. See `allowed_special_indicators`
above for the possibilities. If `special` is `+`, or is omitted and the term is multiword (i.e. containing a space
character), and `prepositions` is supplied, the function checks for multiword or hyphenated terms containing the
prepositions in `prepositions`, e.g. Italian [[senso di marcia]] or [[medaglia d'oro]] or Portuguese
[[tartaruga-do-mar]]. If such a term is found, only the first word is inflected. Otherwise, the default is
{"first-last"}. `prepositions` is a list of Lua patterns matching prepositions. The patterns will automatically have the
separator character (space or hyphen) added to the left side but not the right side, so they should contain a space
character (which will automatically be converted to the appropriate separator) on the right side unless the preposition
is joined on the right side with an apostrophe. Examples of preposition patterns for Italian are {"di "}, {"sull'"} and
{"d?all[oae] "} (which matches {"dallo "}, {"dalle "}, {"alla "}, etc.).
The return value is always either a list of inflected multiword or hyphenated terms, or nil if `special` is omitted
and `form` is not multiword. (If `special` is specified and `form` is not multiword or hyphenated, an error results.)
]==]
function export.handle_multiword(form, special, inflect, prepositions, sep)
sep = sep or form:find(" ") and " " or "%-"
local raw_sep = sep == " " and " " or "-"
-- Used to add regex version of separator in the replacement portion of ugsub() or :gsub()
local sep_replacement = sep == " " and " " or "%%-"
-- Given a Lua pattern, replace space with the appropriate separator.
local function hack_re(re)
if sep == " " then
return re
end
return (re:gsub(" ", sep_replacement))
end
if special == "first" then
local first, rest = form:match(hack_re("^(.-)( .*)$"))
if not first then
error("Special indicator 'first' can only be used with a multiword term: " .. form)
end
return add_endings(inflect(first), rest)
elseif special == "second" then
local first, second, rest = form:match(hack_re("^([^ ]+ )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings({first}, inflect(second)), rest)
elseif special == "first-second" then
local first, space, second, rest = form:match(hack_re("^([^ ]+)( )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'first-second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings(add_endings(inflect(first), space), inflect(second)), rest)
elseif special == "each" then
local terms = split(form, sep)
if #terms < 2 then
error("Special indicator 'each' can only be used with a multiword term: " .. form)
end
for i, term in ipairs(terms) do
terms[i] = inflect(term)
if i > 1 then
terms[i] = add_endings(raw_sep, terms[i])
end
end
local result = ""
for _, term in ipairs(terms) do
result = add_endings(result, term)
end
return result
elseif special == "first-last" then
local first, middle, last = form:match(hack_re("^(.-)( .* )(.-)$"))
if not first then
first, middle, last = form:match(hack_re("^(.-)( )(.*)$"))
end
if not first then
error("Special indicator 'first-last' can only be used with a multiword term: " .. form)
end
return add_endings(add_endings(inflect(first), middle), inflect(last))
elseif special == "last" then
local rest, last = form:match(hack_re("^(.* )(.-)$"))
if not rest then
error("Special indicator 'last' can only be used with a multiword term: " .. form)
end
return add_endings(rest, inflect(last))
elseif special and special ~= "+" then
error("Unrecognized special=" .. special)
end
-- Only do default behavior if special indicator '+' explicitly given or separator is space; otherwise we will
-- break existing behavior with hyphenated words.
if (special == "+" or sep == " ") and form:find(sep) then
if prepositions then
-- check for prepositions in the middle of the word; do it this way so we can handle
-- more than one word before the preposition (and usually inflect each word)
for _, prep in ipairs(prepositions) do
local first, space_prep_rest = umatch(form, hack_re("^(.-)( " .. prep .. ".*)$"))
if first then
return add_endings(inflect(first), space_prep_rest)
end
end
end
-- multiword or hyphenated expressions default to first-last; we need to pass in the separator to avoid
-- problems with multiword terms containing hyphens in the individual words
return export.handle_multiword(form, "first-last", inflect, prepositions, sep)
end
return nil
end
local function link_hyphen_split_component(word, data)
if data.link_hyphen_split_component then
return data.link_hyphen_split_component(word)
else
return "[[" .. word .. "]]"
end
end
-- Default function to split a word on apostrophes. Don't split apostrophes at the beginning or end of a word (e.g.
-- [['ndrangheta]] or [[po']]). Handle multiple apostrophes correctly, e.g. [[l'altr'ieri]] -> [[l']][altr']][[ieri]].
function export.default_split_apostrophe(word, data)
local apostrophe_parts = split(word, "'", true, true)
local linked_apostrophe_parts = {}
local apostrophes_at_beginning = ""
local i = 1
-- Apostrophes at beginning get attached to the first word after (which will always exist but may
-- be blank if the word consists only of apostrophes).
while i < #apostrophe_parts do -- <, not <=, in case the word consists only of apostrophes
local apostrophe_part = apostrophe_parts[i]
i = i + 1
if apostrophe_part == "" then
apostrophes_at_beginning = apostrophes_at_beginning .. "'"
else
break
end
end
apostrophe_parts[i] = apostrophes_at_beginning .. apostrophe_parts[i]
-- Now, do the remaining parts. A blank part indicates more than one apostrophe in a row; we join
-- all of them to the preceding word.
while i <= #apostrophe_parts do
local apostrophe_part = apostrophe_parts[i]
if apostrophe_part == "" then
linked_apostrophe_parts[#linked_apostrophe_parts] =
linked_apostrophe_parts[#linked_apostrophe_parts] .. "'"
elseif i == #apostrophe_parts then
insert(linked_apostrophe_parts, apostrophe_part)
else
insert(linked_apostrophe_parts, apostrophe_part .. "'")
end
i = i + 1
end
for j, tolink in ipairs(linked_apostrophe_parts) do
linked_apostrophe_parts[j] = link_hyphen_split_component(tolink, data)
end
return concat(linked_apostrophe_parts)
end
--[=[
Auto-add links to a word that should not have spaces but may have hyphens and/or apostrophes. We split off final
punctuation, then split on hyphens if `data.split_hyphen` is given, and also split on apostrophes if
`data.split_apostrophe` is given. We only split on hyphens if they are in the middle of the word, not at the beginning
or end (hyphens at the beginning or end indicate suffixes or prefixes, respectively). `include_hyphen_prefixes`, if
given, is a set of prefixes (not including the final hyphen) where we should include the final hyphen in the prefix.
Hence, e.g. if "anti" is in the set, a Portuguese word like [[anti-herói]] "anti-hero" will be split [[anti-]][[herói]]
(whereas a word like [[código-fonte]] "source code" will be split as [[código]]-[[fonte]]).
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
]=]
local function add_single_word_links(space_word, data, term_has_spaces)
local space_word_no_punct, punct
local punct_pattern = data.punctuation
if punct_pattern and is_callable(punct_pattern) then
space_word_no_punct, punct = punct_pattern(space_word)
else
if punct_pattern == nil then
punct_pattern = "[,;:?!]"
end
space_word_no_punct, punct = umatch(space_word, "^(.*)(" .. punct_pattern .. ")$")
end
space_word_no_punct = space_word_no_punct or space_word
punct = punct or ""
local words
if space_word_no_punct:sub(1, 1) == "-" or space_word_no_punct:sub(-1) == "-" then
-- don't split prefixes and suffixes
words = {space_word_no_punct}
else
local splitter
if term_has_spaces then
splitter = data.split_hyphen_when_space
else
splitter = data.split_hyphen_when_no_space
end
if is_callable(splitter) then
words = splitter(space_word_no_punct)
if type(words) == "string" then
return words .. punct
end
end
end
if not words then
local split_hyphen
if term_has_spaces then
split_hyphen = data.split_hyphen_when_space
else
split_hyphen = data.split_hyphen_when_no_space
if split_hyphen == nil then -- default to true; use `false` to avoid this
split_hyphen = true
end
end
if split_hyphen then
words = split(space_word_no_punct, "-", true, true)
else
words = {space_word_no_punct}
end
end
local linked_words = {}
for j, word in ipairs(words) do
if j < #words and data.include_hyphen_prefixes and data.include_hyphen_prefixes[word] then
word = "[[" .. word .. "-]]"
elseif j > 1 and data.include_hyphen_suffixes and data.include_hyphen_suffixes[word] then
word = "[[-" .. word .. "]]"
else
-- Don't split on apostrophes if the word is in `no_split_apostrophe_words`.
if (not data.no_split_apostrophe_words or not data.no_split_apostrophe_words[word]) and
data.split_apostrophe and word:find("'", nil, true) then
if data.split_apostrophe == true then
word = export.default_split_apostrophe(word, data)
else -- custom apostrophe splitter/linker
word = data.split_apostrophe(word)
end
elseif word ~= "" then -- avoid -[[]]- (e.g. f--k)
word = link_hyphen_split_component(word, data)
end
if j < #words then
word = word .. "-"
end
end
insert(linked_words, word)
end
return concat(linked_words) .. punct
end
--[=[
Auto-add links to a multiword term. `data` contains fields customizing how to do this. By default we proceed as follows:
(1) If the term already has embedded links in it, they are left unchanged.
(2) Otherwise, if there are spaces present, we split on spaces and link each word separately.
(3) If a given space-separated component ends in punctuation (defaulting to [,;:?!]), it is separated off, the remainder
of the algorithm run, and the punctuation pasted back on.
(4) If there are hyphens in a given space-separated component, we may link each hyphenated term separately depending
on the settings in `data`. Normally the hyphens are not included in the linked terms, but this can be overridden
for specific prefixes and/or suffixes. By default, if there are spaces in the multiword term, we do not link
hyphenated components (because of cases like "boire du petit-lait" where "petit-lait" should be linked as a whole),
but do so otherwise (e.g. for "avant-avant-hier"); this can overridden for cases like "croyez-le ou non".
Cases where only some of the hyphens should be split can always be handled by explicitly specifying the head (e.g.
"Nord-Pas-de-Calais" given as head=[[Nord]]-[[Pas-de-Calais]]).
(5) If there are apostrophes in a given component, we may link each apostrophe-separated term separately depending
on the settings in `data`, including the apostrophe in the link to its left (so we split "de l'eau" as
"[[de]] [[l']][[eau]]").
The settings in `data` are as follows:
`split_hyphen_when_no_space`: Whether to split on hyphens when the term has no spaces. Defaults to true if set to `nil`.
This can be a function of one argument, to implement a custom splitting algorithm for hyphen-separated terms. If
this returns [FIXME: FINISH ME ...]
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
We don't always split on hyphens because of cases like "boire du petit-lait" where "petit-lait" should be linked as a
whole, but provide the option to do it for cases like "croyez-le ou non". If there's no space, however, then it makes
sense to split on hyphens by `no_split_apostrophe_words` and `include_hyphen_prefixes` allow for special-case handling
of particular words and are as described in the comment above add_single_word_links().
]=]
function export.add_links_to_multiword_term(term, data)
if term:match("[%[%]]") then
return term
end
local words = split(term, " ", true, true)
local term_has_spaces = #words > 1
local linked_words = {}
for _, word in ipairs(words) do
insert(linked_words, add_single_word_links(word, data, term_has_spaces))
end
local retval = concat(linked_words, " ")
-- If we ended up with a single link consisting of the entire term,
-- remove the link.
return retval:match("^%[%[([^%[%]]*)%]%]$") or retval
end
local function canonicalize_begin_end_spec(spec)
local from, to = spec:match("^(.-):(.*)$")
if not from then
from = spec
to = ""
end
return from, to
end
--[==[
Given a `linked_term` that is the output of add_links_to_multiword_term(), apply modifications as given in
`modifier_spec` to change the link destination of subterms (normally single-word non-lemma forms; sometimes
collections of adjacent words). This is usually used to link non-lemma forms to their corresponding lemma, but can
also be used to replace a span of adjacent separately-linked words to a single multiword lemma. The format of
`modifier_spec` is one or more semicolon-separated subterm specs, where each such spec is of the form
SUBTERM:DEST, where SUBTERM is one or more words in the `linked_term` but without brackets in them, and DEST is the
corresponding link destination to link the subterm to. Any occurrence of ~ in DEST is replaced with SUBTERM.
Alternatively, a single modifier spec can be of the form BEGIN[FROM:TO], which is equivalent to writing
BEGINFROM:BEGINTO (see example below).
For example, given the source phrase [[il bue che dice cornuto all'asino]] "the pot calling the kettle black"
(literally "the ox that calls the donkey horned/cuckolded"), the result of calling add_links_to_multiword_term()
is [[il]] [[bue]] [[che]] [[dice]] [[cornuto]] [[all']][[asino]]. With a modifier_spec of 'dice:dire', the result
is [[il]] [[bue]] [[che]] [[dire|dice]] [[cornuto]] [[all']][[asino]]. Here, based on the modifier spec, the
non-lemma form [[dice]] is replaced with the two-part link [[dire|dice]].
Another example: given the source phrase [[chi semina vento raccoglie tempesta]] "sow the wind, reap the whirlwind"
(literally (he) who sows wind gathers [the] tempest"). The result of calling add_links_to_multiword_term() is
[[chi]] [[semina]] [[vento]] [[raccoglie]] [[tempesta]], and with a modifier_spec of 'semina:~re; raccoglie:~re',
the result is [[chi]] [[seminare|semina]] [[vento]] [[raccogliere|raccoglie]] [[tempesta]]. Here we use the ~
notation to stand for the non-lemma form in the destination link.
A more complex example is [[se non hai altri moccoli puoi andare a letto al buio]], which becomes
[[se]] [[non]] [[hai]] [[altri]] [[moccoli]] [[puoi]] [[andare]] [[a]] [[letto]] [[al]] [[buio]] after calling
add_links_to_multiword_term(). With the following modifier_spec:
'hai:avere; altr[i:o]; moccol[i:o]; puoi: potere; andare a letto:~; al buio:~', the result of applying the spec is
[[se]] [[non]] [[avere|hai]] [[altro|altri]] [[moccolo|moccoli]] [[potere|puoi]] [[andare a letto]] [[al buio]].
Here, we rely on the alternative notation mentioned above for e.g. 'altr[i:o]', which is equivalent to 'altri:altro',
and link multiword subterms using e.g. 'andare a letto:~'. (The code knows how to handle multiword subexpressions
properly, and if the link text and destination are the same, only a single-part link is formed.)
]==]
function export.apply_link_modifiers(linked_term, modifier_spec, lang)
local split_modspecs = split(modifier_spec, "%s*;%s*")
for j, modspec in ipairs(split_modspecs) do
local id
if modspec:find("<") then
local rest
rest, id = modspec:match("^(.*)<id:(.-)>$")
if rest then
modspec = rest
end
end
local subterm, dest, otherlang
local begin_spec, rest, end_spec = modspec:match("^%[(.-)%]([^:]*)%[(.-)%]$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = begin_from .. rest .. end_from
dest = begin_to .. rest .. end_to
end
if not subterm then
rest, end_spec = modspec:match("^([^:]*)%[(.-)%]$")
if rest then
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = rest .. end_from
dest = rest .. end_to
end
end
if not subterm then
begin_spec, rest = modspec:match("^%[(.-)%]([^:]*)$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
subterm = begin_from .. rest
dest = begin_to .. rest
end
end
if not subterm then
subterm, dest = modspec:match("^(.-)%s*:%s*(.*)$")
if subterm and subterm ~= "^" and subterm ~= "$" then
local langdest
-- Parse off an initial language code (e.g. 'en:Higgs', 'la:minūtia' or 'grc:σκατός'). Also handle
-- Wikipedia prefixes ('w:Abatemarco' or 'w:it:Colle Val d'Elsa').
otherlang, langdest = dest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if otherlang == "w" then
local foreign_wikipedia, foreign_term = langdest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if foreign_wikipedia then
otherlang = otherlang .. ":" .. foreign_wikipedia
langdest = foreign_term
end
dest = ("%s:%s"):format(otherlang, langdest)
otherlang = nil
elseif otherlang then
otherlang = get_lang_by_code(otherlang, true, "allow etym")
dest = langdest
end
end
end
if not subterm then
if modspec == "?" or modspec == "!" then
subterm = "$"
dest = modspec
elseif modspec == "..." or modspec == "...?" then
subterm = "$"
dest = " " .. modspec
elseif modspec:find("^[A-Z]$") then
-- X, Y, etc. by themselves are unlinked, to help with snowclones
subterm = modspec
dest = "_"
else
subterm = modspec
dest = "~"
end
end
if subterm == "^" then
linked_term = dest:gsub("_", " ") .. linked_term
elseif subterm == "$" then
linked_term = linked_term .. dest:gsub("_", " ")
else
if subterm:find("[", nil, true) then
error(("Subterm '%s' in modifier spec '%s' cannot have brackets in it"):format(
escape_wikicode(subterm), escape_wikicode(modspec)))
end
local escaped_subterm = pattern_escape(subterm)
local subterm_re = "%[%[" .. escaped_subterm:gsub("(%%?[ ',%-])", "%%]*%1%%[*") .. "%]%]"
local expanded_dest
if dest:find("~", nil, true) then
expanded_dest = dest:gsub("~", replacement_escape(subterm))
else
expanded_dest = dest
end
if otherlang then
expanded_dest = expanded_dest .. "#" .. otherlang:getCanonicalName()
end
local subterm_replacement
if expanded_dest == "_" then
subterm_replacement = subterm
if id then
error("Can't supply <id:...> with an unlinked subterm")
end
if otherlang then
error("Can't supply prefixed language with an unlinked subterm")
end
elseif id or otherlang then
if id and expanded_dest:find("[", nil, true) then
error("Can't supply <id:...> with destination with embedded brackets")
end
subterm_replacement = require(links_module).language_link {
lang = otherlang or lang,
term = expanded_dest,
alt = subterm,
id = id,
}
elseif expanded_dest:find("[", nil, true) then
-- Use the destination directly if it has brackets in it (e.g. to put brackets around parts of a word).
subterm_replacement = expanded_dest
elseif expanded_dest == subterm then
subterm_replacement = "[[" .. subterm .. "]]"
else
subterm_replacement = "[[" .. expanded_dest .. "|" .. subterm .. "]]"
end
local escaped_subterm_replacement = replacement_escape(subterm_replacement)
local replaced_linked_term = ugsub(linked_term, subterm_re, escaped_subterm_replacement)
if replaced_linked_term == linked_term then
mw.log(("Attempted to replace %s with %s in %s"):format(subterm_re, escaped_subterm_replacement, linked_term))
error(("Subterm '%s' could not be located in %slinked expression %s, or replacement same as subterm"):format(
subterm, j > 1 and "intermediate " or "", escape_wikicode(linked_term)))
else
linked_term = replaced_linked_term
end
end
end
return linked_term
end
local inflection_to_cats_and_label = {
plural = {
filter_plpos = function(plpos)
-- plurals also occur with determiners, adjectives etc. and we don't want to generate categories like
-- 'countable determiners', 'countable adjectives', etc. Note that the passed-in `plpos` has `proper nouns`
-- converted to `nouns`.
return plpos == "Danh từ"
end,
cats = {"{plpos} đếm được"},
no_cats = {"{plpos} không đếm được"},
no_label = "<<không đếm được>>",
sometimes_label = "<<đếm được>> và <<không đếm được>>",
},
comparative = {
cats = {"{plpos} so sánh được"},
no_cats = {"{plpos} không so sánh được"},
fixed_adj_label = "so sánh được",
},
["female equivalent"] = {
cats = {"{plpos} with other-gender equivalents"},
},
["male equivalent"] = {
cats = {"{plpos} with other-gender equivalents"},
},
}
--[=[
Validate the items in `items` against the list or set of valid items in `valid_items`. If `field` is given, fetch the
item to check from that-named field of each object in `items`; otherwise use the items in `items` directly. If an error
occurs, `item_type` specifies the type of item to mention in the error message, which will also list the allowed items
(either taken directly from `valid_items` if a list, or from the sorted keys if a set).
]=]
local function validate_items(data)
local items, field, valid_items, item_type =
data.items, data.field, data.valid_items, data.item_type
local valid_set
if valid_items[1] then
valid_set = list_to_set(valid_items)
else
valid_set = valid_items
end
for _, item in ipairs(items) do
if field then
item = item[field]
end
if not valid_set[item] then
local valid_list
if valid_items[1] then
valid_list = valid_items
else
valid_list = {}
for valid_item, _ in pairs(valid_items) do
insert(valid_list, valid_item)
end
table.sort(valid_list)
end
error(("Invalid %s: %s; expected one of %s"):format(item_type, item, mw.text.listToText(valid_list)))
end
end
end
function export.has_plural_gender(genders)
local saw_p, saw_non_p
for _, val in ipairs(genders) do
local g = val.spec
if g:find("p$") then
saw_p = true
elseif g ~= "?" then
saw_non_p = true
end
end
return saw_p, saw_non_p
end
function export.is_plurale_tantum(genders)
local saw_p, saw_non_p = export.has_plural_gender(genders)
return saw_p and not saw_non_p
end
local Headdata = {}
function Headdata:get_simplified_plpos()
return export.simplify_pos(self.pos_category)
end
--[==[
Canonicalize a category. The category string will have the full language name (i.e. the name of the L2 language under
which an entry is inserted, which may a parent language if the language in question is an etymology-only language)
prepended to it, and any occurrences of `{plpos}` in the string replaced with the actual plural part of speech (with
some canonicalization; specifically, `proper nouns` is converted to `nouns` when replacing `{plpos}`). To specify a
full category and not have the language name prepended to it, precede it with {"Category:"}, which will be removed.
]==]
function Headdata:canonicalize_category(category)
if category:find("{plpos}") then
local plpos = self:get_simplified_plpos()
category = category:gsub("{plpos}", plpos)
end
if category:find("^Category:") then
return (category:gsub("^Thể loại:", ""))
else
return category.. " " .. self.langfullname
end
end
--[==[
Canonicalize a list of categories according to the process described in `Headdata:canonicalize_category`. This simply
loops over each category in `categories` and calls `Headdata:canonicalize_category` on each one.
]==]
function Headdata:canonicalize_categories(categories)
if not categories then
return categories
end
local canon_cats = {}
for _, cat in ipairs(categories) do
insert(canon_cats, self:canonicalize_category(cat))
end
return canon_cats
end
--[==[
Insert a category into the `categories` list in the headword `data` structure. `category` is normally a string naming
the category, which will have the full language name prepended to it and any occurrences of `{plpos}` in the string
replaced with the actual plural part of speech (with some canonicalization; specifically, `proper nouns` is converted to
`nouns` when replacing `{plpos}`). To specify a full category and not have the language name prepended to it, precede it
with {"Category:"}.
]==]
function Headdata:insert_category(category)
insert(self.categories, self:canonicalize_category(category))
end
--[==[
Validate the genders in `genders` (a list of gender spec objects, as produced by {type = "genders"} in
[[Module:parameters]] and accepted by [[Module:gender and number]]), checking that all specified genders are in the list
given in `valid_genders`. Optional `props` controls how the validation happens. In particular, unless `props.no_augment`
is given, then for any gender beginning with `m`, if a corresponding gender beginning with `f` occurs, analogous genders
beginning with `mf`, `mfbysense` and `mfequiv` are also allowed. For example, if `m-d` (masculine dual) and `f-d`
(feminine dual) both occur, genders `mf-d`, `mfbysense-d` and `mfequiv-d` are also allowed. If a disallowed gender is
given, an error occurs, giving the disallowed gender along with the list of all allowed genders.
]==]
function Headdata:validate_genders(genders, valid_genders, props)
if not genders then
return
end
props = props or {}
local gender_type, no_augment = props.gender_type, props.no_augment
gender_type = gender_type or "headword"
local valid_gender_set = list_to_set(valid_genders)
local augmented_gender_set
if no_augment then
augmented_gender_set = valid_gender_set
else
augmented_gender_set = {}
for g, _ in pairs(valid_gender_set) do
augmented_gender_set[g] = true
if g:find("^m") and not g:find("^mf") and valid_gender_set[g:gsub("^m", "f")] then
augmented_gender_set[g:gsub("^m", "mf")] = true
augmented_gender_set[g:gsub("^m", "mfbysense")] = true
augmented_gender_set[g:gsub("^m", "mfequiv")] = true
end
end
end
validate_items {
items = genders,
field = "spec",
valid_items = augmented_gender_set,
item_type = ("%s gender"):format(gender_type),
}
end
--[==[
Parse an inflection specified in `field`, the name of a parameter holding an inflection. If the parameter is numeric,
the field should be given as a number (as with the `params` structure passed to [[Module:parameters]]), not a string
containing the representation of a number. The field can specify multiple comma-separated terms, and each term can have
associated inline modifiers that will be parsed (unless there is top-level HTML in the parameter, i.e. HTML not
contained inside an inline modifier, e.g. as may be generated by using {{tl|l}} or similar template inside a parameter).
This is a wrapper around the top-level `parse_term_with_modifiers()` function. `props` is an optional structure
containing additional properties, including all additional properties documented for the top-level
`parse_term_with_modifiers()` function.
If the parameter in `field` is unspecified, the return value of this function will be an empty list, not {nil}, so it
is always safe to iterate over the return value.
By default, the allowed modifiers are the same as for `parse_term_with_modifiers()`, except that (normally) the
`<tr:...>` modifier will be allowed if `include_tr` was specified in the original call to `process_headword()`; likewise
for the `<ts:...>` modifier if `include_ts` was specified and the `<sc:...>` modifier if `include_sc` was specified. If
If you pass in your own `include_mods` list of additional allowed modifiers, it will (normally) automatically be
augmented with {"tr"}, {"ts"} and/or {"sc"} if `include_tr`, `include_ts` and/or `include_sc` was specified when calling
`process_headword()`. To disable automatic augmentation of these modifiers (whether or not you specify an `include_mods`
property), specify {no_augment_include_mods = true} in `props`.
]==]
function Headdata:parse_inflection(field, props)
local val = self.process_props.args[field]
if not val then
return {}
end
props = props and shallow_copy(props) or {}
local include_mods = props.include_mods
local calldata = self.process_props.calldata
if not props.no_augment_include_mods and (calldata.include_tr or calldata.include_ts or calldata.include_sc) then
include_mods = include_mods and shallow_copy(include_mods) or {}
if calldata.include_tr then
insert_if_not(include_mods, "tr")
end
if calldata.include_ts then
insert_if_not(include_mods, "ts")
end
if calldata.include_sc then
insert_if_not(include_mods, "sc")
end
end
props.val = val
props.paramname = field
props.splitchar = props.splitchar or ","
props.include_mods = include_mods
local orig_frob = props.frob
local function convert_tilde_to_pagename(term)
if orig_frob then
term = orig_frob(term)
end
if not term:find("~", nil, true) then
return term
end
term = term:gsub("\\~", "\1"):gsub("~", replacement_escape(self.pagename)):gsub("\1", "~")
return term
end
props.frob = convert_tilde_to_pagename
return export.parse_term_with_modifiers(props) or {}
end
--[==[
Insert previously-parsed terms into the `inflections` of the headword `data` structure. This is a wrapper around
the top-level `insert_inflection()` function. `terms` is the list of parsed terms. (If {nil}, nothing happens unless
`request` is set in `props`.) `label` is the the label that the inflections are given; any parts of the label surrounded
in `<<...>>` are linked to the glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.)
`props` is an optional structure containing additional properties, including all additional properties documented for
the top-level `insert_inflection()` function.
Unless `no_auto_cats` is given in `props`, certain labels automatically trigger the insertion of additional
categories in specific circumstances. This is controlled by the `inflection_to_cats_and_label` structure in
[[Module:headword utilities]]. For example, if the part of speech is {"nouns"} or {"proper nouns"} and the label (after
removing any links and `<<...>>` glossary specs) is {"plural"}, an additional category
<code><var>lang</var> countable nouns</code> will be added if a plural value is given (i.e. the value is not {"-"}). If
the value is {"-"} (which indicates that there is no plural and triggers the insertion of the fixed inflection label
{"no plural"}), <code><var>lang</var> uncountable nouns</code> will be inserted instead, and if both {"-"} and a value
are given (which triggers the insertion of the {"usually no plural"} fixed inflection label), both categories are added.
Similar categories are inserted when a comparative is given (with a label {"comparative"}), and if the label is
{"female equivalent"} or {"male equivalent"} and the value is not {"-"}, a category such as
<code><var>lang</var> nouns with other-gender equivalents</code> is inserted.
]==]
function Headdata:insert_inflection(terms, label, props)
props = props and shallow_copy(props) or {}
if not props.no_auto_cats then
local bare_label = props.label_for_cats_and_modes
if not bare_label then
bare_label = label
if bare_label:find("[[", nil, true) then
bare_label = require(links_module).remove_links(bare_label)
end
if bare_label:find("<<", nil, true) then
bare_label = bare_label:gsub("<<.-|(.-)>>", "%1"):gsub("<<(.-)>>", "%1")
end
end
local cats = inflection_to_cats_and_label[bare_label]
if cats then
if not cats.filter_plpos or cats.filter_plpos(self:get_simplified_plpos()) then
if props.cats == nil then
props.cats = self:canonicalize_categories(cats.cats)
end
if props.usually_no_cats == nil then
props.usually_no_cats = self:canonicalize_categories(cats.usually_no_cats)
end
if props.no_cats == nil then
props.no_cats = self:canonicalize_categories(cats.no_cats)
end
end
end
end
props.headdata = self
props.terms = terms
props.label = label
return export.insert_inflection(props)
end
--[==[
Insert a "fixed" inflection (a label without associated values) into the `inflections` table of the headword `data`
structure, labeled according to `label` (which can have glossary links in it specified using `<<...>>`, exactly as for
`:insert_inflection()`). An example label (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"},
specifying that the noun belongs to the hidden-''g'' declension. This is a direct wrapper around the top-level function
`insert_fixed_inflection()`; see that function for more details on optional `props`.
]==]
function Headdata:insert_fixed_inflection(label, props)
props = props and shallow_copy(props) or {}
props.headdata = self
props.label = label
export.insert_fixed_inflection(props)
end
--[==[
Parse the inflection(s) specified in `field` and insert them into the `inflections` table of the headword `data`
structure, labeled according to `label`. This is equivalent to calling {terms = data:parse_inflection(field, props)}
followed by {return data:insert_inflection(terms, label, props)} and behaves the same as the combination of those two
functions. See their documentation for more details.
]==]
function Headdata:parse_and_insert_inflection(field, label, props)
local terms = self:parse_inflection(field, props)
return self:insert_inflection(terms, label, props)
end
--[==[
Generate an inflection that may be specified explicitly or defaulted (which involves looping over the specified or
defaulted heads and determining the script of each one, since the formation of the default depends on the script).
`data` is the data object passed into the POS handler. `terms` is the list of terms to process. Those where the term
itself is not `+` will be returned unchanged, while those where the term is `+` will be handled by generating the
appropriate inflections from the headwords using `make_inflection` (which is passed three arguments, `head`, `tr` and
`sccode`, i.e. the script code of `head`) and should return two values, term and translit, either of which can be
nil. A nil head will be ignored, and otherwise the decorations specified on the `+` term will be combined with the
decorations specified on the head. The return value is a list of inflections where no requests for the default
inflection remain.
]==]
function Headdata:resolve_special(terms, handle_special, props)
props = props or {}
local infls = {}
local is_special = props.is_special or function(_data, infl) return infl.term == "+" end
for _, termobj in ipairs(terms) do
if not is_special(self, termobj) then
insert(infls, termobj)
else
for _, headobj in ipairs(self.heads) do
local head = headobj.term or self.pagename
local head_no_links
if props.with_links then
head = head:find("%[") and head or require(headword_module).add_multiword_links(head, not headobj.term)
head_no_links = require(links_module).remove_links(head)
else
head = require(links_module).remove_links(head)
head_no_links = head
end
local newterms = handle_special {
headdata = self,
head = head,
head_no_links = head_no_links,
tr = headobj.tr,
infl = termobj,
sc = self.lang:findBestScript(head_no_links),
}
if newterms then
newterms = export.canonicalize_termobj_list(newterms, "term", "resolve_special", termobj)
for _, newterm in ipairs(newterms) do
if not props.no_combine_handle_special_retval_with_origin then
export.combine_termobj_decorations(newterm, termobj)
end
if not props.no_combine_handle_special_retval_with_head then
export.combine_termobj_decorations(newterm, headobj)
end
insert(infls, newterm)
end
end
end
end
end
return infls
end
--[==[
Add the current page to a tracking page named `Wiktionary:Tracking/``lang``-headword/``page```, where ``lang`` is the
language code of the current language. For example, if the current language is `mak` and `page` is {"redundant-lon"},
the current page will get added to the tracking page `Wiktionary:Tracking/mak-headword/redundant-lon`. All pages added
to that tracking page can be seen by going to [[Special:WhatLinksHere/Wiktionary:Tracking/mak-headword/redundant-lon]].
This is typically used to track issues occurring in user-specified parameters that do not rise to the level of errors
(e.g. redundant parameters, deprecated usages or other dispreferred values).
]==]
function Headdata:track(page)
return require(debug_track_module)(self.langcode .. "-headword/" .. page)
end
local boolean_param = {type = "boolean"}
--[==[
Process an arbitrary headword in an arbitrary language, handling generic and language-specific arguments and calling
`full_headword()` in [[Module:headword]]. This is intended for use in implementing headword modules (e.g.
[[Module:uz-headword]] for Uzbek, [[Module:mn-headword]] for Uzbek, [[Module:gsw-headword]] for Alemannic German, etc.)
and provides a general implementation of such modules. On input, `data` is an object with the following fields:
* `lang`: The language object of the language being handled. '''Required.''' Use the special value {false} to indicate
that the language is specified by the user in {{para|1}}.
* `frame`: The frame object passed into the `show()` function of your module, which implements headword-handling for
all parts of speech in the module, including a generic POS-handling template (e.g. {{tl|uz-head}} or {{tl|mn-head}}),
which allows arbitrary parts of speech to be handled. '''Required.'''
* `pos_functions`: A table listing, for each part of speech requiring special handling, the extra parameters (if any)
that the part of speech accepts, along with how to handle them. See the examples below. '''Required.'''
* `validate_lang`: If {lang = true} is specified, this is a function of one argument (a language object, based on the
language specified in {{para|1}}) that should throw an error if the language object is disallowed. If omitted, all
languages are allowed.
* `numbered_head`: If true, explicit headwords are specified in a numbered param instead of in {{para|head}}. The param
used is usually {{para|1}}, but is {{para|2}} for generic POS templates such as {{tl|mn-head}} or for POS-specific
templates when {lang = true} is specified (e.g. {{tl|arb-noun}}), and is {{para|3}} for generic POS templates when
{lang = true} is spcified (e.g. {{tl|arb-head}}).
* `include_tr`: If true, allow explicit transliterations to be specified. The transliteration(s) for the headword(s)
themselves is/are specified in {{para|tr}} or through the {{cd|<tr:...>}} inline modifier on headwords, and
transliterations of inflections are specified through the {{cd|<tr:...>}} inline modifier. This should generally be
given when a headword for the language may be in a script other than Latin.
* `include_ts`: If true, allow explicit transcriptions to be specified. The transcription(s) for the headword(s)
themselves is/are specified in {{para|ts}} or through the {{cd|<ts:...>}} inline modifier on headwords, and
transcriptions of inflections are specified through the {{cd|<ts:...>}} inline modifier. This should generally only
be given for certain languages where the spelling is radically different from the pronunciation (e.g. in cuneiform
languages such as Hittite and Akkadian, and potentially in Tibetan), and represents a pronunciation-based rendering
(usually not direct IPA).
* `include_sc`: If true, allow an explicit script code to be specified. The overall script code for the headword(s)
themselves can be specified using {{para|sc}}, and per-headword or per-inflection script codes are specified using the
{{cd|<sc:...>}} inline modifier. This should generally be given when a language supports multiple scripts.
* `infls`: An inflections structure specifying extra generic parameters that apply to all parts of speech and how to
handle them. The format is the same as for the `infls` structure in `pos_functions`.
* `augment_params`: A callback function to add extra generic parameters, or modify existing generic parameters in the
`params` structure; but in general, extra generic parameters should be added through the `infls` structure instead.
This callback should not be used to add part-of-speech-specific parameters; those are handled through the appropriate
setting in `pos_functions`. It is passed two single arguments, the `headdata` object and the `params` table to be
augmented. See below for extra fields stored in the `process_props` structure of the `headdata` object. This function
is called after initializing the `params` table and processing the overall `infls` structure, but just before adding
part-of-speech-specific parameters (from `pos_functions`) to `params`. Thus, it can override any generic parameters
but may itself be overridden by a part-of-speech-specific parameter.
* `augment_headdata`: A callback function to modify the `headdata` object passed to `full_headword()` in
[[Module:headword]]. This should not be used to for part-of-speech-specific parameter handling; this is handled
through the appropriate setting in `pos_functions`. It is passed a single argument, the `headdata` object, as for
`augment_params`; but the `process_props` structure and other fields will be more filled out, as this callback is
called later. This can be used, for example, to override the value of a generic setting in `headdata` (e.g.
[[Module:uz-headword]] uses this to mark non-Latin terms as variant forms by setting `headdata.var`, being careful not
to override a value already set by the user). This function is called after initializing the `headdata` table with all
information taken from generic parameters and processing generic parameters specified in the overall `infls`
structure, and just before processing the appropriate part-of-speech-specific `infls` structure in `pos_functions`
(which in turn is followed by any handler function in `pos_functions`). Thus, it can override any value set during
generic parameter processing but may itself be overridden by a part-of-speech-specific parameter or handler.
* `force_cat`: If true, add the headword to the appropriate categories even on non-mainspace pages. This can be used for
testing category handling in sample template calls on userspace test pages or template documentation pages. It should
not be set in production code.
* `enable_auto_translit`: If true, turn on automatic transliteration of inflections at a global level (i.e. applying to
all inflections). This has no effect on headwords, which are automatically transliterated by default if in a non-Latin
script and automatic transliteration is available for the language. You can also set this value for particular
inflections in the `insert_inflection()` function.
The `headdata` headword data structure has an extra field in it called `process_props` that is specific to the
`process_headword()` function, containing various extra properies. As the operation of `process_headword()` proceeds,
this object gets filled out with more fields. For example, once parameter parsing happens, the resulting values are
available in the `args` field of `process_props`. The following fields are found in `process_props` (note that
`pos_category`, the canonicalized plural part of speech of the headword being processed, is *not* present here; it's
directly on `headdata`):
* `namespace`: The name of the current namespace; an empty string for the mainspace. This references the namespace of
the actual page and isn't affected by the {{para|pagename}} parameter.
* `indexing_pos`: The canonicalized part of speech of the headword used to index into `pos_functions`. This is the
same as `poscat` for specific part-of-speech templates such as {{tl|uz-noun}}, but has the value {"head"} for generic
part-of-speech templates such as {{tl|uz-head}}. (Note that `poscat` is directly available on `headdata`.)
* `generic_pos_template`: True if a generic POS templates like {{tl|uz-head}} or {{tl|mn-head}} was used. (This is
signaled by omitting the invocation parameter {{para|1}} to `process_headword`.)
* `lang_in_1`: True if the language code is to be fetched from {{para|1}}.
* `pos_param`: The parameter holding the part of speech, if a generic POS tempalte like {{tl|mn-head}} is being
processed (i.e. `generic_pos_template` is set). In such a case, it will have the value of {1} or {2}, depending on
whether the language code is being fetched from {{para|1}} (see `lang_in_1`). Otherwise it will be {nil}.
* `head_param`: The parameter holding the explicit headword. If `numbered_head` was specified (as for Mongolian headword
templates), this has the value {1}, {2} or {3} depending on whether the language code is being fetched from {{para|1}}
(see `lang_in_1`) and whether a generic POS template like {{tl|mn-head}} is being processed (see
`generic_pos_template`). Otherwise, it has the value {"head"}. Also see the `lang` and `numbered_head` properties in
the `data` structure sent to `process_headword()`.
* `is_suffix`: True if the current term is a suffix. This is set when processing the `suffix`, `nosuffix` and `clitic`
parameters; it is always {false} beforehand (i.e. during `augment_params` and processing of the general `infls`
structure).
* `insert_specs`: This is a table mapping parameter names to the return value of `Headdata:insert_inflection()`, filled
out as parameter values are processed. This lets a given parameter processing function in `infls` gain access to the
result of calling `insert_inflection()` on previous parameters (which indicates the number of items inserted as well
as whether `-` was specified).
The `pos_functions` table contains an entry for each part of speech needing special handling, where the key is the
canonical plural part of speech (e.g. {"adverbs"} or {"proper nouns"}). The value associated with each key is a table
normally containing a field `infls`, listing the extra part-of-speech-specific inflection and other parameters along
with how to handle them. The specs in `infls` are used in three ways:
# to augment the `params` object passed to the `process()` function in [[Module:parameters]], specifying how to parse
the appropriate inflectional parameters;
# to specify how to process any inflectional parameters given and insert them into the `headdata` object passed to
`full_headword()` in [[Module:headword]];
# to generate appropriate documentation for the parameters and other changes made by the headword template (e.g.
inserting categories).
Alternatively, you can separately control the augmentation of the `params` object and the procesing of the resulting
arguments. This is done by specifying two fields in place of `infls`, named `params` and `func`. `params` is a table
containing extra parameters to add to the overall `params` object passed to the `process()` function in
[[Module:parameters]]. `func` is a function of two arguments, normally called `data` (the headword data structure
`headdata`) and `args` (the processed arguments table). However, this alternative method is not normally recommended
because it leads to duplication between the `params and `func` fields and the documentation, which must be manually
specified.
A simple example, as used to handle pronouns for Turoyo, is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
infls = {
{2, type = "genders", validate = valid_genders},
{"f", label = "feminine"},
{"pl", label = "plural"},
},
}
}
The equivalent using `params` and `func` is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
params = {
[2] = {type = "genders"},
f = true,
pl = true,
},
func = function(data, args)
data:validate_genders(args[2], valid_genders)
data.genders = args[2]
data:parse_and_insert_inflection("f", "feminine")
data:parse_and_insert_inflection("pl", "plural")
end
}
}
Note how the version with separate `params and `func` is longer and splits information on the parameters between the
two fields. The `params` structure sets extra user-specifiable parameters {{para|2}} for genders (since the headword is
in {{para|1}}) as well a {{para|f}} and {{para|pl}}, and the `func` handler processes those parameters. Note how this is
done by calling methods on the headword `data` structure. Each such parameter can have multiple comma-separated values,
and each value can have inline modifiers attached to it to specify further properties of the value. The `infls` version
ends up making the same method calls, but does it for you instead of you having to do it yourself.
These methods are implemented through a metatable set on the headword `data` structure, which is removed before calling
`full_headword()` in [[Module:headword]]. The methods access extra information related to headword processing (such as
the `args` table) that is stored in the `process_props` field of the headword `data` strucuture. This field is also
removed prior to calling `full_headword()`.
The methods available on the headword `data` structure are as follows. Each one also has its own documentation.
* {parse_inflection(field, props)}: Parse value(s) specified in `field` (a user-specified parameter in the `args` table)
and return a list of term objects. Optional `props` specifies additional properties controlling the parsing.
* {insert_inflection(terms, label, props)}: Insert the terms in `terms` (a list of term objects as returned by
`parse_inflection()`) into the `inflections` list in the headword `data` structure, giving the inflection the label as
specified in `label`. Optional `props` specifies additional properties controlling the parsing.
* {parse_and_insert_inflection(field, label, props)}: A combination of `parse_inflection()` and `insert_inflection()`,
if no further processing of the parsed values needs to be done before insertion.
* {insert_fixed_inflection(label, props)}: Insert a "fixed" inflection (a label without associated values) into the
`inflections` table. An example (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"}, specifying
that the noun belongs to the hidden-''g'' declension.
* {resolve_special(terms, handle_special, props)}: Resolve "special" indicators as specified by the user in an inflection
parameter. A typical example is {"+"}, requesting a default value. `terms` is the list of parsed term objects and
`handle_special` is a handler function to process special indicators and convert them to their actual values.
* {validate_genders(genders, valid_genders, props)}: Validate that the user-specified genders in `genders` all belong to
the list given in `valid_genders`, throwing an error if not.
* {insert_category(category)}: Insert a category into the `categories` list in the headword `data` structure. `category`
is normally a string naming the category, which will have the language prepended to it and any occurrences of
`{plpos}` in the string replaced with the actual plural part of speech.
]==]
function export.process_headword(data)
local lang, frame, pos_functions, validate_lang, numbered_head, include_tr, include_ts, include_sc, force_cat,
enable_auto_translit, checkredlinks, infls, augment_params, augment_headdata =
data.lang, data.frame, data.pos_functions, data.validate_lang, data.numbered_head, data.include_tr,
data.include_ts, data.include_sc, data.force_cat, data.enable_auto_translit, data.checkredlinks, data.infls,
data.augment_params, data.augment_headdata
local iparams = {
[1] = true,
def = true,
}
local iargs = require(parameters_module).process(frame.args, iparams)
local parargs = frame:getParent().args
local langcode
if not lang then
error("Internal error: `data.lang` must be specified; either a language object or `true` for a user-specified language")
end
local lang_in_1
if lang == true then
lang_in_1 = true
langcode = ine(parargs[1])
if langcode then
langcode = mw.text.trim(langcode)
lang = require(languages_module).getByCode(langcode, 1, true)
if validate_lang then
validate_lang(lang)
end
else
error("Language code (see [[WT:Language codes]]) must be specified in 1=")
end
else
langcode = lang:getCode()
if validate_lang then
error("Internal error: `data.validate_lang` must not be specified if a language code is given in `data.lang`")
end
end
local template_indicated_pos = iargs[1]
local generic_pos_template = not template_indicated_pos
local pos_param
if generic_pos_template then
pos_param = lang_in_1 and 2 or 1
template_indicated_pos = ine(parargs[pos_param]) or
mw.title.getCurrentTitle().fullText == ("Bản_mẫu:%s-head"):format(langcode) and "interjection" or
error(("Part of speech must be specified in %s="):format(pos_param))
template_indicated_pos = require(headword_module).canonicalize_pos(template_indicated_pos)
end
local head_param = numbered_head and (generic_pos_template and lang_in_1 and 3 or
(generic_pos_template or lang_in_1) and 2 or 1) or "head"
local indexing_pos
if generic_pos_template then
indexing_pos = "head." .. template_indicated_pos
if not pos_functions[indexing_pos] then
indexing_pos = "head"
end
else
indexing_pos = template_indicated_pos
end
local namespace = mw.loadData(headword_data_module).page.namespace
-- Partly initialize headdata now for use in generic infls callbacks. Will be further initialized later after
-- processing parameters.
local headdata = {
lang = lang,
langcode = langcode,
langfullcode = lang:getFullCode(),
langname = lang:getCanonicalName(),
langfullname = lang:getFullName(),
process_props = {
namespace = namespace,
calldata = data,
-- preserve template-indicated POS in case we normalize it or change it to "suffix"
template_indicated_pos = template_indicated_pos,
indexing_pos = indexing_pos,
generic_pos_template = generic_pos_template,
lang_in_1 = lang_in_1,
pos_param = pos_param,
head_param = head_param,
is_suffix = false,
insert_specs = {},
},
-- We may change this below to "suffix" or normalize it.
pos_category = template_indicated_pos,
categories = {},
inflections = {enable_auto_translit = enable_auto_translit},
force_cat_output = force_cat,
no_redundant_head_cat = true,
}
setmetatable(headdata, {__index = Headdata})
local function resolve_prop(prop, ...)
if type(prop) == "function" then
prop = prop(headdata, ...)
end
return prop
end
local params = {
[head_param] = {template_default = iargs.def},
head2 = {replaced_by = false, instead = ("use comma-separated |%s="):format(head_param)},
id = true,
sort = true,
cat = true,
nolink = boolean_param,
nolinkhead = {type = "boolean", alias_of = "nolink"},
suffix = boolean_param,
nosuffix = boolean_param,
clitic = true,
addlpos = true,
var = {type = "boolean or string", set = {"both"}},
abbr = true,
json = boolean_param,
pagename = true, -- for testing
}
if include_sc then
params.sc = {type = "script"}
end
if include_tr then
params.tr = true
params.tr2 = {replaced_by = false, instead = "use comma-separated |tr= or <tr:...> inline modifier on head"}
end
if include_ts then
params.ts = true
params.ts2 = {replaced_by = false, instead = "use comma-separated |ts= or <ts:...> inline modifier on head"}
end
if lang_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
if generic_pos_template then
params[pos_param] = {required = true} -- required but ignored as already processed above
end
local function augment_params_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local param = infl[1]
if param then
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- We handle defaults as well as validation ourselves.
local typ = resolve_prop(infl.type) or "string"
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
params[param] = {type = typ, required = resolve_prop(infl.required), template_default = resolve_prop(infl.template_default)}
if typ ~= "boolean" then
local allow_and_ignore_list_params = resolve_prop(infl.allow_and_ignore_list_params)
local ignore_param
if type(allow_and_ignore_list_params) == "string" then
ignore_param = allow_and_ignore_list_params
elseif type(param) == "string" then
ignore_param = param
end
if ignore_param then
local old_list_param = allow_and_ignore_list_params and true or
{replaced_by = false, instead = ("use comma-separated |%s="):format(param)}
params[ignore_param .. "2"] = old_list_param
params[ignore_param .. "3"] = old_list_param
params[ignore_param .. "4"] = old_list_param
end
end
end
end
end
if infls then
augment_params_from_infls(infls)
end
if augment_params then
augment_params(headdata, params)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_params_from_infls(pos_infls)
end
local pos_params = pos_functions[indexing_pos].params
if pos_params then
for key, val in pairs(pos_params) do
params[key] = val
end
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData(headword_data_module).pagename
local sc = args.sc or lang:findBestScript(pagename)
headdata.pagename = pagename
headdata.process_props.args = args
headdata.sc = sc
headdata.id = args.id
headdata.sort = args.sort
-- No redundant script cat unless the user explicitly gave sc=
headdata.no_script_code_cat = not args.sc
headdata.var = args.var
local extra_term_mods = {}
if include_tr then
insert(extra_term_mods, "tr")
end
if include_ts then
insert(extra_term_mods, "ts")
end
if include_sc then
insert(extra_term_mods, "sc")
end
if not extra_term_mods[1] then
extra_term_mods = nil
end
local trs = args.tr and split_on_comma(args.tr) or {}
local num_trs = #trs
local tss = args.ts and split_on_comma(args.ts) or {}
local num_tss = #tss
local heads = args[head_param] and export.parse_term_with_modifiers {
val = args[head_param],
paramname = head_param,
splitchar = ",",
is_head = true,
include_mods = extra_term_mods,
} or {}
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 default automatic translit and '-' to stand for no translit"):format(
num_heads, num_heads > 1 and "s" or "", num_trs, num_trs > 1 and "s" or ""))
end
if num_heads > 0 and num_tss > 0 and num_heads ~= num_tss then
error(("%s head%s specified explicitly but %s transcription%s; they must match; use '+' to stand for the default head (the pagename) and '-' to stand for no transcription"):format(
num_heads, num_heads > 1 and "s" or "", num_tss, num_tss > 1 and "s" or ""))
end
if num_trs > 0 and num_tss > 0 and num_trs ~= num_tss then
error(("%s translit%s specified explicitly but %s transcription%s; they must match; use '+' to stand for default automatic translit and '-' to stand for no translit or transcription"):format(
num_trs, num_trs > 1 and "s" or "", num_tss, num_tss > 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.
local max_tr_ts = math.max(num_trs, num_tss)
if num_heads == 0 and max_tr_ts > 0 then
heads = {}
for i = 1, max_tr_ts do
heads[i] = {term = "+"}
end
end
if not heads[1] then
heads = {{term = "+"}}
end
for i, headobj in ipairs(heads) do
if headobj.tr and trs[i] then
if headobj.tr ~= trs[i] then
error(("Saw two different translits '%s' and '%s' for head #%s"):format(
headobj.tr, trs[i], i))
end
else
headobj.tr = headobj.tr or trs[i]
end
if headobj.tr == "+" then
headobj.tr = nil
end
if headobj.ts and tss[i] then
if headobj.ts ~= tss[i] then
error(("Saw two different transcriptions '%s' and '%s' for head #%s"):format(
headobj.ts, tss[i], i))
end
else
headobj.ts = headobj.ts or tss[i]
end
if headobj.ts == "-" then
headobj.ts = nil
end
if headobj.term == "+" then
headobj.term = args.nolink and pagename or nil
if headobj.term and namespace == "Reconstruction" then
headobj.term = "*" .. headobj.term
end
end
end
headdata.heads = heads
local pos_category = headdata.pos_category
-- Do this as late as possible in case the caller wants to conditionalize the primary categorizing POS on
-- arguments or even the presence or absence of explicit heads.
if pos_functions[indexing_pos] then
pos_category = resolve_prop(pos_functions[indexing_pos].pos_category) or pos_category
end
headdata.process_props.normalized_template_indicated_pos = pos_category
headdata.pos_category = pos_category
local function pagename_is_suffix()
if sc:getCode() == "Latn" then
-- shortcut Latin terms to avoid unnecessarily loading [[Module:affix]]
return pagename:find("^%-") and not pagename:find("%-$")
else
local affix_type, _, _, _ = require(affix_module).parse_term_for_affixes(pagename, lang, sc)
return affix_type == "Hậu tố"
end
end
local clitic_label
if args.clitic then
clitic_label = require(yesno_module)(args.clitic, args.clitic)
end
if clitic_label == true then
clitic_label = "clitic"
end
if clitic_label then
headdata:insert_category("clitics")
headdata:insert_fixed_inflection(clitic_label)
elseif args.suffix or (
not args.nosuffix and pagename_is_suffix() and pos_category ~= "Hậu tố" and pos_category ~= "Biến thể hình thái hậu tố"
) then
headdata.process_props.is_suffix = true
local function handle_suffix_pos(pos, is_first)
-- Use the actual POS for the label we insert, but simplify the POS for the category. We need to separately check
-- each of them to see if they end in 'forms' because e.g. 'comparative adjectives' gets simplified to
-- 'adjective forms'.
local form_type = pos:match("^Biến thể hình thái (.*)$")
if form_type then
headdata:insert_fixed_inflection("Dạng hậu tố " .. form_type)
else
local singular_pos = require(en_utilities_module).singularize(pos)
headdata:insert_category(("%s-forming suffixes"):format(singular_pos))
headdata:insert_fixed_inflection(singular_pos .. "-forming suffix")
end
local simplified_pos = export.simplify_pos(pos, "preserve_lemma_status", "preserve_proper_nouns")
local simplified_form_type = simplified_pos:match("^(.*) forms$")
if simplified_form_type then
headdata:insert_category(("%s suffix forms"):format(simplified_form_type))
else
local singular_simplified_pos = require(en_utilities_module).singularize(simplified_pos)
headdata:insert_category(("%s-forming suffixes"):format(singular_simplified_pos))
end
local postype = require(headword_module).pos_lemma_or_nonlemma(pos)
if not postype then
postype = require(headword_module).pos_lemma_or_nonlemma(simplified_pos)
end
if not postype then
error(("Unrecognized canonicalized part of speech '%s' in addlpos=, cannot determine whether lemma or non-lemma form"):format(
pos
))
end
local this_pos_category = postype == "Mục từ" and "Hậu tố" or "Biến thể hình thái hậu tố"
if is_first then
headdata.pos_category = this_pos_category
elseif headdata.pos_category ~= this_pos_category then
local singular_normalized_this_pos_category =
require(en_utilities_module).singularize(this_pos_category)
local singular_normalized_overall_pos_category =
require(en_utilities_module).singularize(headdata.pos_category)
error(("Cannot mix suffixes and suffix forms using addlpos=; '%s' is of a %s while overall POS " ..
"'%s' is a %s; use separate POS headers for the two"):format(pos,
singular_normalized_this_pos_category, pos_category, singular_normalized_overall_pos_category))
end
end
handle_suffix_pos(pos_category, true)
if args.addlpos then
for _, addlpos in ipairs(split(args.addlpos, "%s*,%s*")) do
addlpos = require(headword_module).canonicalize_pos(addlpos)
handle_suffix_pos(addlpos, false)
end
end
end
if args.cat then
for _, cat in ipairs(split_on_comma(args.cat)) do
headdata:insert_category(cat)
end
end
local function augment_headdata_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local function process_labelobjs(labelobjs, originating_term, handle_labelobj)
if labelobjs == nil then
return
end
if type(labelobjs) ~= "string" and type(labelobjs) ~= "table" then
interr(("Wrong type '%s' for label object(s) %s, expected string or table"):format(
type(labelobjs), dump(labelobjs)
))
end
if type(labelobjs) == "string" or type(labelobjs) == "table" and not labelobjs[1] then
labelobjs = {labelobjs}
end
for _, labelobj in ipairs(labelobjs) do
local label, termobj
if type(labelobj) == "string" then
label = labelobj
termobj = originating_term
elseif type(labelobj) ~= "table" then
interr(("Wrong type '%s' for label object %s, expected string or table"):format(
type(labelobj), dump(labelobj)
))
label = labelobj.term
if type(label) ~= "string" then
interr(("Wrong type '%s' for label %s from label object %s, expected string"):format(
type(label), dump(label), dump(labelobj)
))
end
termobj = labelobj
end
handle_labelobj(label, termobj)
end
end
local param = infl[1]
if param then
local vals
-- Fetch the param and make sure it's a string or number.
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- Fetch the type and validate.
local typ = resolve_prop(infl.type)
if typ == nil then
typ = "string"
end
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
-- Fetch the value(s).
if typ == "genders" or typ == "boolean" then
vals = args[param]
elseif typ == "string" then
local parse_inflection_props = resolve_prop(infl.parse_inflection_props)
local include_mods = resolve_prop(infl.include_mods)
local no_augment_include_mods = resolve_prop(infl.no_augment_include_mods)
if include_mods ~= nil or no_augment_include_mods ~= nil then
if parse_inflection_props == nil then
parse_inflection_props = {}
else
parse_inflection_props = shallow_copy(parse_inflection_props)
end
if include_mods ~= nil then
parse_inflection_props.include_mods = include_mods
end
if no_augment_include_mods ~= nil then
parse_inflection_props.no_augment_include_mods = no_augment_include_mods
end
end
vals = headdata:parse_inflection(param, parse_inflection_props)
-- Convert an empty list to nil for consistent checking below.
if not vals[1] then
vals = nil
end
else
interr(("Unrecognized type '%s"):format(typ))
end
-- If value(s) nil, fetch the default.
if vals == nil and infl.default ~= nil then
local default = resolve_prop(infl.default)
if typ == "genders" then
vals = export.canonicalize_termobj_list(default, "spec", "default")
elseif typ == "boolean" then
vals = default
elseif typ == "string" then
vals = export.canonicalize_termobj_list(default, "term", "default")
else
interr(("Unrecognized type '%s"):format(typ))
end
end
-- Resolve "special" values (special signals a string values, such as requesting the default with "+").
if vals ~= nil and infl.resolve_special then
if typ ~= "string" then
interr(("Cannot specify resolve_special= for type %s"):format(dump(typ)))
end
local resolve_special_props = resolve_prop(infl.resolve_special_props, vals)
if infl.is_special ~= nil then
if resolve_special_props == nil then
resolve_special_props = {}
else
resolve_special_props = shallow_copy(resolve_special_props)
end
resolve_special_props.is_special = infl.is_special
end
vals = headdata:resolve_special(vals, infl.resolve_special, resolve_special_props)
end
-- Validate the value(s).
if vals ~= nil and infl.validate ~= nil then
if typ == "boolean" then
interr('Cannot specify validate= when type is "boolean"')
elseif type(infl.validate) == "function" then
infl.validate(headdata, vals)
elseif typ == "genders" then
headdata:validate_genders(vals, infl.validate)
elseif typ == "string" then
validate_items {
items = vals,
field = "term",
valid_items = infl.validate,
item_type = ("values in |%s="):format(param),
}
else
interr(("Unrecognized type '%s"):format(typ))
end
end
-- Run the process_after_parse handler, if it exists.
if vals ~= nil and infl.process_after_parse ~= nil then
local intentionally_nil
vals, intentionally_nil = infl.process_after_parse(headdata, vals)
if vals == nil and not intentionally_nil then
interr("If you return nil from process_after_parse, you must return a second non-nil return " ..
"value to indicate that the nil return value was intentional")
end
end
-- "Implement" the values, if non-falsy (i.e. we don't want to fire on boolean false or empty list).
-- If a fixed label is specified, insert it. Then, depending on the type, attach the values to a label
-- as an inflection, set the `genders` field, or do nothing if boolean (throwing an error if there was
-- no fixed label).
local insert_request = resolve_prop(infl.request, vals)
if vals == true or type(vals) == "table" and vals[1] or insert_request then
if infl.fixed_label and infl.all_fixed_label then
interr("Cannot specify both fixed_label= and all_fixed_label=; specify one or the other")
end
local function check_fixed_label_references_val(label)
if type(label) == "table" and label[1] then
for _, lab in ipairs(label) do
if check_fixed_label_references_val(lab) then
return true
end
end
return false
end
if type(label) == "table" then
if not label.term then
interr(("Fixed label structure %s does not have a value for `.term`"):format(dump(label)))
end
label = label.term
end
if type(label) ~= "string" then
interr(("Wrong type for fixed label %s, should be string"):format(type(label)))
end
return not not label:find("{val}")
end
local fixed_label = infl.fixed_label
local all_fixed_label = infl.all_fixed_label
-- If the value being processed is boolean, there's only one value so treat a fixed_label as an
-- all_fixed_label and output only once; likewise if the caller specified a fixed_label without
-- {val} in it.
if fixed_label and (typ == "boolean" or type(fixed_label) ~= "function" and not
check_fixed_label_references_val(fixed_label)) then
all_fixed_label = fixed_label
fixed_label = nil
end
local inserted_fixed_label
if fixed_label then
if typ == "boolean" then
interr("Boolean fixed_label values should have been converted to all_fixed_label")
end
for _, valobj in ipairs(vals) do
local labelobjs = resolve_prop(fixed_label, valobj)
process_labelobjs(labelobjs, valobj, function(label, termobj)
if label:find("{val}") then
if typ ~= "string" then
interr(('Cannot specify {val} in fixed_label %s when type is "%s"'):format(dump(label), typ))
end
label = label:gsub("{val}", replacement_escape(valobj.term))
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
inserted_fixed_label = true
end)
end
elseif all_fixed_label then
local labelobjs = resolve_prop(all_fixed_label, vals)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{vals}") then
if typ ~= "string" then
interr(('Cannot specify {vals} in all_fixed_label %s when type is "%s"'):format(dump(label), typ))
end
local formatted_labels = {}
for _, valobj in ipairs(vals) do
insert(formatted_labels, add_decorations(valobj.term, valobj, lang))
end
label = label:gsub("{vals}", replacement_escape(serial_comma_join(formatted_labels)))
end
headdata:insert_fixed_inflection(label, termobj)
inserted_fixed_label = true
end)
end
local inserted_vals
if infl.label ~= nil then
if typ ~= "string" then
interr(("label=%s can only be specified for type 'string', not '%s'"):format(
dump(infl.label), typ
))
end
local label = resolve_prop(infl.label, vals)
if label ~= nil then
local insert_inflection_props = resolve_prop(infl.insert_inflection_props, vals)
local function copy_to_insert_inflection_props(field, val)
local fieldval = val or resolve_prop(infl[field], vals)
if fieldval ~= nil then
if insert_inflection_props == nil then
insert_inflection_props = {}
else
insert_inflection_props = shallow_copy(insert_inflection_props)
end
insert_inflection_props[field] = fieldval
end
end
copy_to_insert_inflection_props("label_for_cats_and_modes")
copy_to_insert_inflection_props("no_auto_cats")
copy_to_insert_inflection_props("accel")
copy_to_insert_inflection_props("accel_form")
if insert_request then
copy_to_insert_inflection_props("request", insert_request)
end
local insert_spec = headdata:insert_inflection(vals, label, insert_inflection_props)
headdata.process_props.insert_specs[param] = insert_spec
inserted_vals = true
end
end
if typ == "genders" then
headdata.genders = vals
end
local inserted_cat
if infl.cat then
local allcats = {}
for _, valobj in ipairs(vals) do
local cats = resolve_prop(infl.cat, valobj)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
cat = cat:gsub("{val}", replacement_escape(valobj.term))
end
insert_if_not(allcats, cat)
end
end
end
for _, cat in ipairs(allcats) do
headdata:insert_category(cat)
inserted_cat = true
end
end
if typ == "boolean" then
if not inserted_fixed_label and not inserted_cat then
interr(("User set boolean setting for %s= but no fixed label added and no category " ..
"inserted; if you took action in process_after_parse(), make sure to return " ..
"`nil, true`"):format(param))
end
elseif typ == "string" then
if not inserted_vals and not inserted_fixed_label and not inserted_cat then
interr(("User set value(s) %s for %s= but no inflection inserted and no fixed label " ..
"or category added; if you took action in process_after_parse(), make sure to " ..
"return `nil, true`"):format(dump(vals), param))
end
end
end
else -- no param specified
if infl.label or infl.all_fixed_label then
interr("Cannot have label= or all_fixed_label= without specifying a param")
end
if infl.fixed_label then
local labelobjs = resolve_prop(infl.fixed_label)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{val}") then
interr("Cannot specify {val} in a fixed_label= value without specifying a param")
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
end)
end
if infl.cat then
local cats = resolve_prop(infl.cat)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
interr("Cannot specify {val} in a cat= value without specifying a param")
end
headdata:insert_category(cat)
end
end
end
end
end
end
if infls then
augment_headdata_from_infls(infls)
end
if augment_headdata then
augment_headdata(headdata, args)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_headdata_from_infls(pos_infls)
end
local func = pos_functions[indexing_pos].func
if func then
func(headdata, args)
end
end
headdata:parse_and_insert_inflection("abbr", "abbreviation")
setmetatable(headdata, nil)
headdata.process_props = nil
if args.json then
return require("Module:JSON").toJSON(headdata)
end
return require(headword_module).full_headword(headdata)
end
return export
r8dahbbh9e6iw55tsxq6jmvgk3xkdbi
тиш
0
274099
2573131
2506845
2026-10-24T04:50:35Z
WhoAlone
40420
2573131
wikitext
text/x-wiki
{{-atv-}}
{{-noun-}}
{{head|atv|Danh từ}}
# [[răng]].
{{-ref-}}
* {{R:atv:Baskakov}}
{{-trk-dkh-}}
{{-translit-}}
* {{Latn}}: tiš
{{-noun-}}
{{pn}}
# [[răng]].
[[Thể loại:Danh từ tiếng Dukha]]
{{c|trk-dkh|Răng}}
{{-kir-}}
{{-noun-}}
{{kir-noun}}
# [[răng]].
{{-alt-}}
{{-noun-}}
{{head|alt|Danh từ}}
# [[răng]].
{{-ref-}}
* {{R:alt:Chumakaev}}
{{-uum-}}
{{-translit-}}
* {{Latn}}: tiš
{{-noun-}}
{{pn}}
# [[giấc mơ]].
# [[răng]].
[[Thể loại:Danh từ tiếng Urum]]
{{c|uum|Răng}}
0p5ij69r8k4e2bsjty14rwmuzdcvrai
Mô đun:place/placetypes
828
282248
2573018
2572974
2026-10-23T15:22:13Z
TheHighFighter2
42988
2573018
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
else
placetype = 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 `"territory"`
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 = "tên"
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 `"của"` 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 "của"
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 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 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
`"thành phố"` (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 == "thành phố" 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 "thành phố"',
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 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 "country", "state",
"tỉnh" 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", "district" 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"] = "quốc gia",
["can"] = "canton",
["carea"] = "council area",
["cc"] = "constituent country",
["cdblock"] = "community development block",
["cdep"] = "Crown dependency",
["CDP"] = "census-designated place",
["cdp"] = "census-designated place",
["clcity"] = "county-level city",
["co"] = "county",
["cobor"] = "county borough",
["colcity"] = "county-level city",
["coll"] = "collectivity",
["comm"] = "community",
["cont"] = "lục địa",
["continent"] = "lục địa",
["contr"] = "continental region",
["contregion"] = "continental region",
["cpar"] = "civil parish",
["damun"] = "direct-administered municipality",
["dep"] = "dependency",
["department capital"] = "departmental capital",
["dept"] = "department",
["depterr"] = "dependent territory",
["dist"] = "district",
["distmun"] = "district municipality",
["div"] = "division",
["emp"] = "empire",
["fpref"] = "French prefecture",
["gov"] = "governorate",
["govnat"] = "governorate",
["home-rule city"] = "home rule city",
["home-rule municipality"] = "home rule municipality",
["inner-city area"] = "inner city area",
["ires"] = "Indian reservation",
["isl"] = "island",
["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"] = "núi",
["mun"] = "municipality",
["mundist"] = "municipal district",
["nonmetropolitan county"] = "non-metropolitan county",
["obl"] = "oblast",
["okr"] = "okrug",
["p"] = "tỉnh",
["par"] = "parish",
["parmun"] = "parish municipality",
["pen"] = "peninsula",
["plcity"] = "prefecture-level city",
["plcolony"] = "Polish colony",
["pref"] = "prefecture",
["prefcity"] = "prefecture-level city",
["preflcity"] = "prefecture-level city",
["prov"] = "tỉnh",
["r"] = "region",
["range"] = "dãy núi",
["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"] = "state",
["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"] = "village",
["voi"] = "voivodeship",
["wcomm"] = "Welsh community",
}
local no_link_def_article = {link = false, article = ""}
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",
["country"] = "national capitals",
-- The following are not obviously different from 'county seats' but the latte terminology is used in the US.
["county"] = "county capitals",
["department"] = "departmental capitals",
["district"] = "district capitals",
["division"] = "division capitals",
["emirate"] = "emirate capitals",
["governorate"] = "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",
["tỉnh"] = "provincial capitals",
["raion"] = "raion capitals",
["regency"] = "regency capitals",
["region"] = "regional capitals",
["regional unit"] = "regional unit capitals",
["republic"] = "republic capitals",
["state"] = "state capitals",
["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",
},
["country"] = {
["Holy Roman Empire"] = "the",
},
["empire"] = {
["Holy Roman Empire"] = "the",
},
["island"] = {
["North Island"] = "the",
["South Island"] = "the",
},
["region"] = {
["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"] = {"^Vịnh của "},
["lake"] = {"^Hồ của "},
["country"] = {"^Republic of ", " Republic$"},
["republic"] = {"^Republic of ", " Republic$"},
["region"] = {"^Vùng của "},
["river"] = {"^Sông của "},
["local government area"] = {"^Shire of "},
["county"] = {"^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 = {
["region"] = {
["Eastern Europe"] = {"continent/Europe"},
["Central Europe"] = {"continent/Europe"},
["Western Europe"] = {"continent/Europe"},
["South Europe"] = {"continent/Europe"},
["Southern Europe"] = {"continent/Europe"},
["Northern Europe"] = {"continent/Europe"},
["Northeast Europe"] = {"continent/Europe"},
["Northeastern Europe"] = {"continent/Europe"},
["Southeast Europe"] = {"continent/Europe"},
["Southeastern Europe"] = {"continent/Europe"},
["North Caucasus"] = {"continent/Europe"},
["South Caucasus"] = {"continent/Asia"},
["South Asia"] = {"continent/Asia"},
["Southern Asia"] = {"continent/Asia"},
["East Asia"] = {"continent/Asia"},
["Eastern Asia"] = {"continent/Asia"},
["Central Asia"] = {"continent/Asia"},
["West Asia"] = {"continent/Asia"},
["Western Asia"] = {"continent/Asia"},
["Southeast Asia"] = {"continent/Asia"},
["North Asia"] = {"continent/Asia"},
["Northern Asia"] = {"continent/Asia"},
["Anatolia"] = {"continent/Asia"},
["Asia Minor"] = {"continent/Asia"},
["Mesopotamia"] = {"continent/Asia"},
["North Africa"] = {"continent/Africa"},
["Central Africa"] = {"continent/Africa"},
["West Africa"] = {"continent/Africa"},
["East Africa"] = {"continent/Africa"},
["Southern Africa"] = {"continent/Africa"},
["Central America"] = {"continent/Central America"},
["Caribbean"] = {"continent/North America"},
["Polynesia"] = {"continent/Oceania"},
["Micronesia"] = {"continent/Oceania"},
["Melanesia"] = {"continent/Oceania"},
["Siberia"] = {"country/Russia", "continent/Asia"},
["Russian Far East"] = {"country/Russia", "continent/Asia"},
["South Wales"] = {"constituent country/Wales", "continent/Europe"},
["Balkans"] = {"continent/Europe"},
["West Bank"] = {"country/Palestine", "continent/Asia"},
["Gaza"] = {"country/Palestine", "continent/Asia"},
["Gaza Strip"] = {"country/Palestine", "continent/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 = "thành phố",
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 của %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 của %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 của %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, "Thành phố thủ đô")
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, ("Địa danh của %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 "của"
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("^ ", "")
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.loadData("Module:headword/data").pagename)
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 "in" not "của", 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) .. " of " .. 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 " of " or " in ") ..
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["Hạt " .. unlinked_placename .. ", Ireland"] or
m_locations.northern_ireland_counties["Hạt " .. unlinked_placename .. ", Bắc Ireland"] then
return prefix_display_handler("Hạt", holonym_placename)
end
-- Display handler for Taiwanese counties. Taiwanese counties are displayed as e.g. "[[Chiayi]] County".
if m_locations.taiwan_counties[unlinked_placename .. ", Đài Loan"] then
return suffix_display_handler("Hạt", holonym_placename)
end
-- Display handler for Romanian counties. Romanian counties are displayed as e.g. "[[Cluj]] County".
if m_locations.romania_counties[unlinked_placename .. ", România"] then
return suffix_display_handler("Hạt", 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 .. ", Nhật Bản"] and "" or "prefecture"
return suffix_display_handler(suffix, holonym_placename)
end
-- Display handler for provinces of Bulgaria, 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.bulgaria_provinces[unlinked_placename .. ", Bulgaria"] or
m_locations.iran_provinces[unlinked_placename .. ", Iran"] or
m_locations.laos_provinces[unlinked_placename .. ", Lào"] or
m_locations.north_korea_provinces[unlinked_placename .. ", Cộng hòa Dân chủ Nhân dân Triều Tiên"] or
m_locations.south_korea_provinces[unlinked_placename .. ", Hàn Quốc"] or
m_locations.thailand_provinces[unlinked_placename .. ", Thái Lan"] or
m_locations.turkey_provinces[unlinked_placename .. ", Thổ Nhĩ Kỳ"] or
m_locations.vietnam_provinces[unlinked_placename .. ", Việt Nam"] then
return prefix_display_handler("tỉnh", 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[unlinked_placename .. ", Nigeria"] then
return suffix_display_handler("State", holonym_placename)
end
return holonym_placename
end
-- Display handler for voivodeships. Display as e.g. [[Subcarpathian Voivodeship]].
local function voivodesip_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/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 = "của"`, 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 `"in"`.
* `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 = "region"`.
* `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 "county" 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 = "của",
class = "subpolity",
},
["administrative capital"] = {
link = "w",
fallback = "capital city",
},
["administrative center"] = {
link = "w",
fallback = "non-city capital",
},
["administrative centre"] = {
link = "w",
fallback = "administrative center",
},
["administrative county"] = {
link = "w",
fallback = "county",
},
["administrative district"] = {
link = "w",
fallback = "district",
},
["administrative headquarters"] = {
link = "separately",
fallback = "administrative centre",
},
["administrative region"] = {
link = true,
preposition = "của",
suffix = "region", -- but prefix is still "administrative region (of)"
fallback = "region",
class = "subpolity",
},
["administrative seat"] = {
link = "w",
fallback = "administrative centre",
},
["administrative territory"] = {
link = "separately",
preposition = "của",
suffix = "territory", -- but prefix is still "administrative territory (of)"
fallback = "territory",
class = "subpolity",
},
["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 = "subpolity",
},
["administrative village"] = {
link = "w",
preposition = "của",
has_neighborhoods = true,
class = "settlement",
},
["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 = "confederation",
},
["archipelago"] = {
link = true,
fallback = "island",
},
["area"] = {
link = true,
preposition = "của",
fallback = "geographic and cultural area",
-- 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 = "subpolity",
former_type = "geographic region",
cat_handler = district_neighborhood_cat_handler,
},
["arm"] = {
link = true,
preposition = "của",
class = "natural feature",
default = {"Seas"},
},
["arrondissement"] = {
link = true,
preposition = "của",
-- 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 = "subpolity",
has_neighborhoods = true,
},
["associated province"] = {
link = "separately",
fallback = "tỉnh",
},
["rạn san hô vòng"] = {
-- 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 = "natural feature",
bare_category_parent = "islands",
default = {true},
},
["autonomous city"] = {
link = "w",
preposition = "của",
fallback = "thành phố",
has_neighborhoods = true,
},
["autonomous community"] = {
-- Spain; refers to regional entities, not village-like entities, as might be expected from "community"
link = true,
preposition = "của",
class = "subpolity",
},
["autonomous island"] = {
-- Comoros; seems like an administrative atoll of the Maldives.
link = "+w:autonomous islands of Comoros",
preposition = "của",
class = "subpolity",
},
["autonomous oblast"] = {
link = true,
preposition = "của",
affix_type = "Suf",
no_affix_strings = "oblast",
class = "subpolity",
},
["autonomous okrug"] = {
link = true,
preposition = "của",
affix_type = "Suf",
no_affix_strings = "okrug",
class = "subpolity",
},
["autonomous prefecture"] = {
link = true,
fallback = "prefecture",
},
["autonomous province"] = {
link = "w",
fallback = "tỉnh",
},
["autonomous region"] = {
link = "w",
preposition = "của",
fallback = "administrative region",
-- "administrative region" sets an affix of "region" but we want to display as "Tibet Autonomous Region"
-- if the user writes 'ar:Suf/Tibet'.
affix = "autonomous region",
},
["autonomous republic"] = {
link = "w",
preposition = "của",
class = "subpolity",
},
["autonomous territorial unit"] = {
-- Moldova; only two of them, one for Gagauzia and one for Transnistria.
link = "w",
preposition = "của",
class = "subpolity",
},
["autonomous territory"] = {
link = "w",
fallback = "dependent territory",
},
["bailiwick"] = {
-- Jersey, etc.
link = true,
fallback = "polity",
},
["barangay"] = {
-- Philippines
link = true,
class = "settlement",
-- Barangays are formal administrative divisions of a city rather than informal neighborhoods, but can use
-- some of the properties of a neighborhood.
fallback = "neighborhood",
default = {"Barangay"},
},
["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 = "lake",
},
["vịnh"] = {
link = true,
preposition = "của",
class = "natural feature",
addl_bare_category_parents = {"Vùng nước"},
default = {true},
},
["bãi biển"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"nước"},
default = {true},
},
["beach resort"] = {
link = "w",
fallback = "resort town",
},
["bishopric"] = {
link = true,
fallback = "polity",
},
["vùng nước!"] = {
-- 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 = "vùng nước",
class = "natural feature",
addl_bare_category_parents = {"địa mạo", "hệ thống sinh thái", "nước"},
},
["borough"] = {
link = true,
preposition = "của",
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 = "subpolity",
-- Grr, some boroughs are city-like but some (e.g. in Britain) may be larger.
},
["borough seat"] = {
link = true,
entry_placetype_use_the = true,
preposition = "của",
has_neighborhoods = true,
class = "capital",
},
["branch"] = {
link = true,
preposition = "của",
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 = "polity",
},
["canton"] = {
link = true,
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["cape"] = {
link = true,
fallback = "headland",
},
["thủ đô"] = {
link = true,
fallback = "thành phố thủ đô",
},
["thành phố thủ đô"] = {
link = true,
category_link = "[[thành phố]] [[thủ đô]]",
entry_placetype_use_the = true,
preposition = "của",
has_neighborhoods = true,
class = "capital",
bare_category_parent = "thành phố",
cat_handler = capital_city_cat_handler,
default = {"Thành phố thủ đô"},
-- 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 = "thành phố",
},
["caplc"] = {
link = "[[capital]] and [[large]]st [[city]]",
plural_link = false,
fallback = "capital city",
},
["captaincy"] = {
link = true,
preposition = "của",
class = "subpolity",
inherently_former = {"FORMER"},
},
["caravan city"] = {
link = "w",
fallback = "thành phố",
class = "settlement",
inherently_former = {"ANCIENT", "FORMER"},
},
["castle"] = {
link = true,
fallback = "building",
},
["cathedral city"] = {
link = true,
fallback = "thành phố",
},
["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 = "của",
class = "subpolity",
},
["census town"] = {
link = "w",
fallback = "town",
},
["central business district"] = {
link = true,
fallback = "neighborhood",
},
["cercle"] = {
-- Mali
link = "+w:cercles of Mali",
preposition = "của",
class = "subpolity",
},
["ceremonial county"] = {
link = true,
fallback = "county",
},
["chain of islands"] = {
link = "[[chain]] of [[island]]s",
plural = "chains of islands",
plural_link = "[[chain]]s of [[island]]s",
fallback = "island",
},
["channel"] = {
link = true,
fallback = "strait",
},
["charter community"] = {
-- Northwest Territories, Canada
link = "w",
fallback = "village",
},
["thành phố"] = {
link = true,
generic_before_non_cities = "của",
has_neighborhoods = true,
class = "settlement",
cat_handler = city_type_cat_handler,
default = {true},
},
["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 in +++", "Quốc gia của +++", "National capitals"},
default = {"City-states", "Cities", "Quốc gia", "National capitals"},
},
["civil parish"] = {
-- Mostly England; similar to municipalities
link = true,
preposition = "của",
affix_type = "suf",
has_neighborhoods = true,
class = "subpolity",
},
["claimed political division"] = {
link = "[[claim]]ed [[political]] [[division]]",
class = "subpolity",
default = {true},
},
["co-capital"] = {
link = "[[co-]][[capital]]",
fallback = "capital city",
},
["coal city"] = {
link = "+w:coal town",
fallback = "thành phố",
},
["coal town"] = {
link = "w",
fallback = "town",
},
["collectivity"] = {
link = "w",
preposition = "của",
-- No default; these are weird one-off governmental divisions in France (esp. for overseas collectivities)
class = "subpolity",
},
["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 = "của",
class = "subpolity",
},
["commandery"] = {
link = true,
preposition = "của",
class = "subpolity",
inherently_former = {"ANCIENT", "FORMER"},
},
["commonwealth"] = {
link = true,
preposition = "của",
-- No default; applies specifically to Puerto Rico
class = "subpolity",
},
["commune"] = {
link = true,
fallback = "municipality",
},
["community"] = {
link = true,
category_link = "[[community|communities]] of all sizes",
fallback = "village",
},
["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 = "subpolity",
},
["comune"] = {
-- Italy, Switzerland
link = true,
fallback = "municipality",
},
["condominium"] = {
link = true,
fallback = "polity",
},
["confederacy"] = {
link = true,
fallback = "confederation",
},
["confederation"] = {
link = true,
fallback = "polity",
},
["constituency"] = {
-- currently we have them as political divisions of Namibia but many countries have them
link = true,
preposition = "của",
class = "subpolity",
},
["constituent country"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["constituent part"] = {
link = "separately",
preposition = "của",
class = "subpolity",
},
["constituent republic"] = {
-- Of Russia, Yugoslavia, etc.
link = "separately",
preposition = "của",
class = "subpolity",
},
["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 = "subpolity",
},
["continent"] = {
link = true,
category_link = false, -- can't occur as a bare category
class = "natural feature",
default = {"Lục địa"},
},
["continental region"] = {
link = "separately",
category_link = false, -- can't occur as a bare category
class = "geographic region",
fallback = "continent",
},
["lục địa!"] = {
category_link = "[[continent]]s and [[continent]]-[[level]] [[region]]s (e.g. [[Polynesia]])",
class = "geographic region",
default = {"Lục địa"},
},
["council area"] = {
link = true,
-- in Scotland; similar to a county
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["quốc gia"] = {
link = true,
class = "polity",
["continent/*"] = {true, "Quốc gia"},
default = {"Quốc gia"},
},
["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 = "polity",
},
["county"] = {
link = true,
preposition = "của",
display_handler = county_display_handler,
class = "subpolity",
},
["county borough"] = {
link = true,
-- in Wales; similar to a county
preposition = "của",
affix_type = "suf",
fallback = "borough",
class = "subpolity",
},
["county seat"] = {
link = true,
entry_placetype_use_the = true,
preposition = "của",
has_neighborhoods = true,
class = "capital",
},
["county town"] = {
link = true,
entry_placetype_use_the = true,
preposition = "của",
fallback = "town",
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 = "thành phố",
has_neighborhoods = true,
class = "settlement",
},
["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 = "lake",
},
["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 = "geographic and cultural area",
},
["cultural region"] = {
link = "w",
fallback = "geographic and cultural area",
},
["delegation"] = {
-- Tunisia
link = "+w:delegations of Tunisia",
preposition = "của",
class = "subpolity",
},
["department"] = {
link = true,
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["departmental capital"] = {
link = "separately",
fallback = "capital city",
},
["dependency"] = {
link = true,
fallback = "dependent territory",
},
["dependent territory"] = {
link = "w",
preposition = "của",
class = "subpolity",
former_type = "dependent territory",
bare_category_parent = "political divisions",
["country/*"] = {true},
default = {true},
},
["hoang mạc"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"hệ thống sinh thái"},
default = {true},
},
["deserted mediaeval village"] = {
link = "w",
fallback = "deserted medieval village",
},
["deserted medieval village"] = {
link = "w",
fallback = "ANCIENT settlement",
},
["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 = "của",
fallback = "river",
},
["district"] = {
link = true,
preposition = "của",
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 "subpolity".
class = "subpolity",
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 = "subpolity",
},
["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 = "subpolity",
},
["district capital"] = {
link = "separately",
fallback = "capital city",
},
["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 = "của",
affix_type = "suf",
no_affix_strings = {"district", "municipality"},
fallback = "municipality",
class = "subpolity",
},
["division"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["division capital"] = {
link = "separately",
fallback = "capital city",
},
["dome"] = {
link = true,
fallback = "Núi",
},
["dormant volcano"] = {
link = true,
fallback = "volcano",
},
["duchy"] = {
link = true,
fallback = "polity",
},
["emirate"] = {
link = true,
preposition = "của",
-- FIXME: Can be subpolities (of the United Arab Emirates).
fallback = "polity",
},
["empire"] = {
link = true,
fallback = "polity",
},
["enclave"] = {
link = true,
preposition = "của",
-- Enclaves can theoretically be any size but assume a subpolity.
class = "subpolity",
},
["entity"] = {
-- Bosnia and Herzegovina
link = "+w:entities of Bosnia and Herzegovina",
preposition = "của",
class = "subpolity",
},
["escarpment"] = {
link = true,
fallback = "Núi",
},
["ethnographic region"] = {
-- used in Lithuania
link = "+w:ethnographic regions of Lithuania",
fallback = "geographic and cultural area",
},
["exclave"] = {
link = true,
preposition = "của",
-- exclaves can theoretically be any size but assume a subpolity.
class = "subpolity",
},
["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 = "của",
fallback = "thành phố",
},
["federal district"] = {
link = true,
preposition = "của",
-- Might have neighborhoods as federal districts are often cities (e.g. Mexico City)
has_neighborhoods = true,
class = "settlement",
},
["federal subject"] = {
-- In Russia; a generic term for first-level administrative divisions (republics, oblasts, okrugs, krais,
-- autonomous okrugs and autonomous oblasts).
link = "w",
preposition = "của",
class = "subpolity",
},
["federal territory"] = {
link = "w",
fallback = "territory",
},
["fictional location"] = {
link = "separately",
former_type = "!",
class = "hypothetical location",
bare_category_parent = "Địa danh",
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 = "subpolity",
},
["fjord"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"vùng nước"},
default = {true},
},
["footpath"] = {
link = true,
fallback = "road",
},
["rừng"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"hệ thống sinh thái", "lâm nghiệp"},
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 = "của",
has_neighborhoods = true,
class = "capital",
},
["geographic and cultural area"] = {
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 = "của",
preposition = "của",
class = "geographic region",
bare_category_parent = "Địa danh",
["country/*"] = {true},
["constituent country/*"] = {true},
["continent/*"] = {true},
default = {true},
},
["geographic area"] = {
link = "+w:geographic region",
fallback = "geographic and cultural area",
},
["geographic region"] = {
link = "w",
fallback = "geographic and cultural area",
},
["geographical area"] = {
link = "w",
fallback = "geographic and cultural area",
},
["geographical region"] = {
link = "w",
fallback = "geographic and cultural area",
},
["geopolitical zone"] = {
-- Nigeria
link = true,
preposition = "của",
class = "subpolity",
},
["gewog"] = {
-- Bhutan
link = true,
preposition = "của",
class = "subpolity",
},
["ghost town"] = {
link = true,
generic_before_non_cities = "in",
class = "non-admin settlement",
bare_category_parent = "former settlements",
cat_handler = city_type_cat_handler,
default = {true},
},
["glen"] = {
link = true,
fallback = "valley",
},
["governorate"] = {
link = true,
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["greater administrative region"] = {
-- China (former division)
link = "w",
preposition = "của",
class = "subpolity",
inherently_former = {"FORMER"},
},
["gromada"] = {
-- Poland (former division)
link = "w",
preposition = "của",
affix_type = "Pref",
class = "subpolity",
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",
},
["vịnh biển"] = {
link = true,
preposition = "của",
class = "natural feature",
addl_bare_category_parents = {"vùng nước"},
default = {true},
},
["hamlet"] = {
link = true,
fallback = "village",
},
["harbor city"] = {
link = "separately",
fallback = "thành phố",
},
["harbor town"] = {
link = "separately",
fallback = "town",
},
["harbour city"] = {
link = "separately",
fallback = "thành phố",
},
["harbour town"] = {
link = "separately",
fallback = "town",
},
["mũi đất"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"địa mạo"},
default = {true},
},
["headquarters"] = {
link = "w",
fallback = "administrative centre",
},
["bãi hoang"] = {
link = true,
fallback = "đồng hoang",
},
["hemisphere"] = {
link = true,
entry_placetype_use_the = true,
fallback = "continental region",
},
["highway"] = {
link = true,
fallback = "road",
},
["đồi"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"địa mạo"},
default = {true},
},
["hill station"] = {
link = "w",
fallback = "town",
},
["hill town"] = {
link = "w",
fallback = "town",
},
["historic region"] = {
-- provided only for the link
link = "+w:historical region",
fallback = "FORMER geographic region",
},
["historical county"] = {
-- needed for historical counties of England/etc.
link = "+w:historic county",
fallback = "FORMER subpolity",
},
["historical region"] = {
-- provided only for the link
link = "w",
fallback = "FORMER geographic region",
},
["home rule city"] = {
link = "w",
fallback = "thành phố",
},
["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 = "của",
affix_type = "suf",
class = "subpolity",
},
["inactive volcano"] = {
link = "w",
fallback = "dormant volcano",
},
["independent city"] = {
link = true,
fallback = "thành phố",
},
["independent town"] = {
link = "+independent city",
fallback = "town",
},
["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 = "của",
class = "subpolity",
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 = "của",
class = "subpolity",
default = {true},
},
["inland sea"] = {
-- note, we also have 'inland' as a qualifier
link = true,
fallback = "sea",
},
["inner city area"] = {
link = "[[inner city]] [[area]]",
fallback = "neighborhood",
},
["đảo"] = {
link = true,
preposition = "của",
class = "natural feature",
addl_bare_category_parents = {"địa mạo"},
default = {true},
},
["island country"] = {
-- FIXME: The following should map to both 'island' and 'country'.
link = "w",
fallback = "country",
},
["island group"] = {
link = "separately",
fallback = "island",
},
["island municipality"] = {
link = "w",
fallback = "municipality",
},
["islet"] = {
link = "w",
fallback = "island",
},
["Israeli settlement"] = {
link = "w",
class = "settlement",
default = {true},
},
["judicial capital"] = {
link = "w",
fallback = "capital city",
},
["khanate"] = {
link = true,
fallback = "polity",
},
["kibbutz"] = {
link = true,
plural = "kibbutzim",
class = "non-admin settlement",
default = {true},
},
["kingdom"] = {
link = true,
fallback = "monarchy",
},
["krai"] = {
link = true,
preposition = "của",
affix_type = "Suf",
class = "subpolity",
},
["hồ"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"vùng nước"},
default = {true},
},
["địa mạo!"] = {
category_link = "[[địa mạo]]",
bare_category_parent = "địa danh",
addl_bare_category_parents = {"Trái Đất"},
},
["largest city"] = {
link = "[[large]]st [[city]]",
entry_placetype_use_the = true,
fallback = "thành phố",
has_neighborhoods = true,
},
["league"] = {
link = true,
fallback = "confederation",
},
["legislative capital"] = {
link = "separately",
fallback = "capital city",
},
["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 = "của",
class = "subpolity",
},
["local council"] = {
-- Malta; similar to municipalities
link = "+w:local councils of Malta",
preposition = "của",
fallback = "municipality",
},
["local government district"] = {
link = "w",
preposition = "của",
affix_type = "suf",
affix = "district",
class = "subpolity",
},
["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 = "của",
affix_type = "suf",
affix = "district",
class = "subpolity",
},
["local urban district"] = {
link = "w",
fallback = "unincorporated community",
},
["locality"] = {
link = "+w:locality (settlement)",
-- not necessarily true, but usually is the case
fallback = "village",
},
["London borough"] = {
link = "w",
preposition = "của",
affix_type = "pref",
affix = "borough",
fallback = "local government district with borough status",
has_neighborhoods = true,
},
["macroregion"] = {
link = true,
fallback = "region",
},
["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 = "Địa danh",
},
["manor"] = {
-- FIXME: or is this more like a farm?
link = true,
fallback = "building",
},
["marginal sea"] = {
link = true,
preposition = "của",
fallback = "sea",
},
["market city"] = {
link = "+market town",
fallback = "thành phố",
},
["market town"] = {
link = true,
fallback = "town",
},
["massif"] = {
link = true,
fallback = "Núi",
},
["megacity"] = {
link = true,
fallback = "thành phố",
},
["metro station"] = {
link = true,
class = "man-made structure",
},
["metropolitan borough"] = {
link = true,
preposition = "của",
affix_type = "Pref",
no_affix_strings = {"borough", "thành phố"},
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 = "của",
affix_type = "Pref",
no_affix_strings = {"metropolitan", "thành phố"},
class = "subpolity",
},
["metropolitan county"] = {
link = true,
fallback = "county",
},
["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 = "của",
affix_type = "Suf",
no_affix_strings = {"metropolitan", "municipality"},
fallback = "municipality",
class = "subpolity",
},
["microdistrict"] = {
-- residential complex in post-Soviet states
link = true,
fallback = "neighborhood",
},
["micronations!"] = {
-- FIXME, merge with microstate
category_link = "[[micronation]]s",
bare_category_parent = "quốc gia",
},
["microstate"] = {
link = true,
fallback = "country",
},
["military base"] = {
link = "w",
class = "settlement", -- or "man-made structure"?
default = {true},
},
["minster town"] = {
-- England
link = "separately",
fallback = "town",
},
["monarchy"] = {
link = true,
fallback = "polity",
},
["đồng hoang"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"địa mạo", "hệ thống sinh thái"},
default = {true},
},
["thảo nguyên"] = {
link = true,
fallback = "đồng hoang",
},
["motorway"] = {
link = true,
fallback = "road",
},
["Núi"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"địa mạo"},
default = {true},
},
["mountain indigenous district"] = {
-- Taiwan
link = "+w:district (Taiwan)",
fallback = "district",
},
["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 = "natural feature",
addl_bare_category_parents = {"Núi"},
default = {true},
},
["dãy núi"] = {
link = true,
fallback = "Núi",
},
["mountainous region"] = {
link = "separately",
fallback = "region",
},
["mukim"] = {
-- Malaysia, Brunei, Indonesia, Singapore
link = true,
preposition = "của",
class = "subpolity",
},
["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 = "của",
affix_type = "Pref",
no_affix_strings = "district",
fallback = "municipality",
},
["municipality"] = {
link = true,
preposition = "của",
has_neighborhoods = true,
class = "subpolity",
},
["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",
},
["địa danh thần thoại"] = {
link = "địa danh thần thoại",
former_type = "!",
class = "hypothetical location",
bare_category_parent = "địa danh",
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"},
},
["national capital"] = {
link = "w",
fallback = "capital city",
},
["national park"] = {
link = true,
fallback = "park",
},
["đặc điểm tự nhiên!"] = {
category_link = "tổng hợp các yếu tố vật chất hình thành tồn tại",
bare_category_parent = "địa danh",
},
["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", "districts", "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 = "in",
generic_before_cities = "của",
-- 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 "của" before cities and "in" before non-cities regardless. (FIXME: We should change that.)
preposition = "của",
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 = "in",
class = "subpolity", --?
},
["new town"] = {
link = true,
fallback = "town",
},
["non-city capital"] = {
link = "[[capital]]",
entry_placetype_use_the = true,
preposition = "của",
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 = "county",
},
["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 = "in",
class = "subpolity",
["country/*"] = {true},
["continent/*"] = {true},
default = {true},
},
["non-sovereign monarchy"] = {
link = "w",
fallback = "non-sovereign kingdom",
},
["oblast"] = {
link = true,
preposition = "của",
affix_type = "Suf",
class = "subpolity",
},
["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 = "subpolity",
},
["đại dương"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"biển", "vùng nước"},
default = {true},
},
["okrug"] = {
link = true,
preposition = "của",
affix_type = "Suf",
class = "subpolity",
},
["overseas collectivity"] = {
link = "w",
fallback = "collectivity",
},
["overseas department"] = {
link = "w",
fallback = "department",
},
["overseas territory"] = {
link = "w",
fallback = "dependent territory",
},
["parish"] = {
link = true,
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["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 = "của",
fallback = "municipality",
has_neighborhoods = true,
},
["parish seat"] = {
link = true,
entry_placetype_use_the = true,
preposition = "của",
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 = "Núi",
},
["peninsula"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"landforms"},
default = {true},
},
["periphery"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["địa danh!"] = {
generic_before_non_cities = "của",
generic_before_cities = "của",
class = "generic place",
category_link = "[[place]]s of all sorts",
-- `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 = "[[geographical]] [[place]]s of all sorts; [[toponym]]s",
bare_category_parent = "tên",
},
["planned community"] = {
-- Include this so we don't categorize 'planned community' into villages, as 'community' does.
link = true,
class = "settlement",
has_neighborhoods = true,
},
["plateau"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"landforms"},
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 = "village",
has_neighborhoods = true,
},
["political divisions!"] = {
category_link = "[[political]] [[division]]s and [[subdivision]]s, such as [[state]]s, [[province]]s, [[county|counties]] or [[district]]s",
bare_category_parent = "Địa danh",
},
["tổ chức chính trị"] = {
link = true,
category_link = "[[independent]] or [[semi-]][[independent]] [[polity|polities]]",
class = "polity",
bare_category_parent = "địa danh",
default = {true},
},
["populated place"] = {
link = "+w:populated place",
-- not necessarily true, but usually is the case
fallback = "village",
},
["port"] = {
link = true,
class = "man-made structure",
default = {true},
},
["port city"] = {
-- FIXME: should categorize into "Ports" as well as "Cities"
link = true,
fallback = "thành phố",
},
["port town"] = {
-- FIXME: should categorize into "Ports" as well as "Towns"
link = "w",
fallback = "town",
},
["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 = "của",
display_handler = prefecture_display_handler,
class = "subpolity",
},
["prefecture-level city"] = {
-- China; they are huge entities with a central city; not cities themselves.
link = "w",
preposition = "của",
class = "subpolity",
},
["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 "counties" or "county boroughs"), of which there are 22.
link = "w",
preposition = "của",
class = "subpolity",
inherently_former = {"FORMER"},
},
["primary area"] = {
-- a grouping of "districts" (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",
},
["tỉnh"] = {
link = true,
preposition = "của",
display_handler = province_display_handler,
class = "subpolity",
},
["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 = "subpolity",
},
["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 = "subpolity",
},
["provincial capital"] = {
link = true,
fallback = "capital city",
},
["raion"] = {
link = true,
preposition = "của",
affix_type = "Suf",
class = "subpolity",
},
["ranch"] = {
link = true,
fallback = "farm",
},
["range"] = {
-- FIXME: Where is this used? Is it a mountain range?
link = true,
class = "natural feature",
},
["regency"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["region"] = {
link = true,
preposition = "của",
-- If 'region' isn't a specific administrative division, fall back to 'geographic and cultural area'
fallback = "geographic and cultural area",
-- "former region" is a subpolity but traditional/historic(al)/ancient/medieval/etc. is a geographic region
class = "geographic region",
},
["regional capital"] = {
link = "separately",
fallback = "capital city",
},
["regional county municipality"] = {
-- Quebec
link = "w",
preposition = "của",
affix_type = "Suf",
no_affix_strings = {"municipality", "county"},
fallback = "municipality",
},
["regional district"] = {
link = "w",
preposition = "của",
affix_type = "Pref",
no_affix_strings = "district",
fallback = "district",
},
["regional municipality"] = {
link = "w",
preposition = "của",
affix_type = "Pref",
no_affix_strings = "municipality",
fallback = "municipality",
},
["regional unit"] = {
link = "w",
preposition = "của",
affix_type = "suf",
class = "subpolity",
},
["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 = "county",
},
["republic"] = {
-- Of Russia, Yugoslavia, etc. "Republics" in general are sovereign but we use "country" 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 = "lake",
},
["residential area"] = {
link = "separately",
fallback = "neighborhood",
},
["resort city"] = {
link = "w",
fallback = "thành phố",
},
["resort town"] = {
link = "w",
fallback = "town",
},
["sông"] = {
link = true,
generic_before_non_cities = "của",
class = "natural feature",
addl_bare_category_parents = {"vùng nước"},
cat_handler = city_type_cat_handler,
["continent/*"] = {true},
default = {true},
},
["river island"] = {
link = "w",
fallback = "island",
},
["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 = "subpolity",
},
["royal borough"] = {
link = "w",
preposition = "của",
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 = "capital city",
},
["rural committee"] = {
-- Hong Kong; a group of villages
link = "w",
affix_type = "Suf",
has_neighborhoods = true,
class = "settlement",
},
["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 = "của",
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 = "của",
class = "subpolity",
inherently_former = {"ANCIENT", "FORMER"},
},
["biển"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"vùng nước"},
default = {"Biển"},
},
["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 = "của",
class = "subpolity",
},
["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",
},
["settlement"] = {
link = true,
category_link = "[[settlement]]s such as [[city|cities]], [[village]]s and [[farm]]s",
bare_category_parent = "Địa danh",
-- not necessarily true, but usually is the case
fallback = "village",
},
["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 = "district",
},
["sheep station"] = {
-- Australia
link = true,
fallback = "farm",
},
["shire"] = {
link = true,
fallback = "county",
},
["shire county"] = {
link = "w",
fallback = "county",
},
["shire town"] = {
link = true,
fallback = "county seat",
},
["ski resort city"] = {
link = "[[ski resort]] [[city]]",
fallback = "thành phố",
},
["ski resort town"] = {
link = "[[ski resort]] [[town]]",
fallback = "town",
},
["spa city"] = {
link = "+w:spa town",
fallback = "thành phố",
},
["spa town"] = {
link = "w",
fallback = "town",
},
["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 = "của",
class = "subpolity",
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 = "peninsula",
},
["spring"] = {
link = true,
class = "natural feature",
default = {true},
},
["star"] = {
link = true,
class = "natural feature",
default = {true},
},
["state"] = {
link = true,
preposition = "của",
class = "subpolity",
-- '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 = "polity",
},
["states 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 Australia.
category_link = "[[state]]s and [[territory|territories]]",
class = "subpolity",
},
["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 = "subpolity",
},
["state capital"] = {
link = true,
fallback = "capital city",
},
["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 = "thành phố",
},
["statutory town"] = {
link = "w",
fallback = "town",
},
["strait"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"bodies of water"},
default = {true},
},
["stream"] = {
link = true,
fallback = "river",
},
["street"] = {
link = true,
fallback = "road",
},
["strip"] = {
link = true,
fallback = "geographic region",
},
["strip of land"] = {
link = "[[strip]] of [[land]]",
plural = "strips of land",
plural_link = "[[strip]]s of [[land]]",
fallback = "geographic region",
},
["sub-metropolitan city"] = {
link = "+w:List of cities in Nepal#Sub-metropolitan cities",
fallback = "thành phố",
},
["sub-prefectural city"] = {
link = "w",
fallback = "subprovincial city",
},
["subdistrict"] = {
link = true,
preposition = "của",
has_neighborhoods = true, --?
-- FIXME: subdistricts can be neighborhood-like (of Jakarta) or larger (in China); need a handler
class = "subpolity",
default = {true},
},
["subdivision"] = {
link = true,
preposition = "của",
affix_type = "suf",
-- FIXME: subdivisions can be neighborhood-like or larger; need a handler
class = "subpolity",
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 = "của",
class = "subpolity",
},
["subprovince"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["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 = "của",
class = "subpolity",
},
["subregion"] = {
link = true,
fallback = "geographic region",
},
["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 "in" for non-cities and "của" for cities. (FIXME: Change this.)
generic_before_non_cities = "in",
generic_before_cities = "của",
preposition = "của",
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 "county" 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",
},
["supercontinent"] = {
link = true,
fallback = "continent",
},
["tehsil"] = {
link = true,
affix_type = "suf",
no_affix_strings = {"tehsil", "tahsil"},
class = "subpolity",
},
["temple"] = {
link = true,
fallback = "building",
},
["territorial authority"] = {
link = "w",
fallback = "district",
},
["territory"] = {
link = true,
preposition = "của",
class = "subpolity",
},
["theme"] = {
link = "+w:theme (Byzantine district)",
preposition = "của",
class = "subpolity",
},
["town"] = {
link = true,
generic_before_non_cities = "in",
has_neighborhoods = true,
class = "settlement",
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 = "town",
},
["township"] = {
link = true,
has_neighborhoods = true,
class = "settlement", --?
default = {true},
},
["township municipality"] = {
-- Quebec
link = "+w:township municipality (Quebec)",
preposition = "của",
fallback = "municipality",
has_neighborhoods = true, --?
},
["traditional county"] = {
link = true,
fallback = "county",
},
["traditional region"] = {
-- FIXME: Verify this works. Same for 'historic(al) region'.
-- provided only for the link
link = "w",
fallback = "FORMER geographic region",
},
["trail"] = {
link = true,
fallback = "road",
},
["treaty port"] = {
link = "w",
fallback = "thành phố",
class = "settlement",
inherently_former = {"FORMER"},
},
["tributary"] = {
link = true,
preposition = "của",
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 = "in",
class = "non-admin settlement",
},
["unincorporated territory"] = {
link = "w",
fallback = "territory",
},
["union territory"] = {
-- India
link = true,
preposition = "của",
entry_placetype_indefinite_article = "a",
class = "subpolity",
},
["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 = "polity",
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 = "thành phố",
},
["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 = "town",
},
["valley"] = {
link = true,
class = "natural feature",
addl_bare_category_parents = {"landforms", "water"},
default = {true},
},
["viceroyalty"] = {
-- in essence, a type of colony
link = true,
fallback = "dependent territory",
},
["village"] = {
link = true,
generic_before_non_cities = "in",
category_link = "[[village]]s, [[hamlet]]s, and other small [[community|communities]] and [[settlement]]s",
class = "settlement",
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 = "village",
},
["village municipality"] = {
-- Quebec
link = "+w:village municipality (Quebec)",
preposition = "của",
fallback = "municipality",
has_neighborhoods = true, --?
},
["voivodeship"] = {
-- Poland
link = true,
display_handler = voivodeship_display_handler,
preposition = "của",
class = "subpolity",
},
["volcano"] = {
link = true,
plural = "volcanoes",
class = "natural feature",
addl_bare_category_parents = {"landforms"},
default = {true, "Núi"},
},
["phường"] = {
link = true,
class = "settlement",
-- 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 = "của",
affix_type = "suf",
affix = "community",
has_neighborhoods = true,
class = "settlement",
},
["zone"] = {
-- administrative division of Ethiopia, Qatar, Nepal, India
link = "+w:zone#Place names",
preposition = "của",
class = "subpolity",
},
----------------------------------------------------------------------------------------------
-- Categories for former places --
----------------------------------------------------------------------------------------------
["ANCIENT capital"] = {
link = false,
entry_placetype_use_the = true,
preposition = "của",
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 settlement",
},
["ANCIENT settlement"] = {
link = false,
has_neighborhoods = true,
class = "settlement",
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 = "của",
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 county"] = {
-- For categorizing former counties and county-level cities of China
link = false,
fallback = "FORMER subpolity",
},
["FORMER county-level city"] = {
-- For categorizing former counties and county-level cities of China
link = false,
fallback = "FORMER subpolity",
},
["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 country"] = {
link = false,
class = "polity",
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 = "của",
class = "subpolity",
default = {"Former dependent territories"},
},
["former districts!"] = {
-- For categorizing former districts of China
category_link = "no-longer-existing [[district]]s",
bare_category_breadcrumb = "districts",
bare_category_parent = "former political divisions",
},
["FORMER district"] = {
-- For categorizing former districts of China
link = false,
fallback = "FORMER subpolity",
},
["FORMER geographic region"] = {
link = false,
fallback = "geographic and cultural area",
},
["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 subpolity",
},
["FORMER natural feature"] = {
link = false,
class = "natural feature",
default = {"Former natural features"},
},
["former natural features!"] = {
category_link = "natural features such as [[lake]]s, [[river]]s and [[island]]s that no longer exist",
bare_category_breadcrumb = "natural features",
bare_category_parent = "former places",
},
["FORMER non-admin settlement"] = {
link = false,
class = "non-admin settlement",
fallback = "FORMER settlement",
},
["former places!"] = {
category_link = "[[place]]s of all sorts that no longer exist",
bare_category_breadcrumb = "former",
bare_category_parent = "Địa danh",
},
["former political divisions!"] = {
category_link = "[[political]] [[division]]s (states, provinces, counties, etc.) that no longer exist",
bare_category_breadcrumb = "political divisions",
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 polity"] = {
link = false,
class = "polity",
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 subpolity",
},
["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 subpolity",
},
["former region"] = {
-- A former region is considered a former political division, but not a 'historical/traditional/etc.' region.
link = "separately",
preposition = "của",
inherently_former = {"FORMER"},
class = "subpolity",
},
["FORMER settlement"] = {
link = false,
has_neighborhoods = true,
class = "settlement",
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 subpolity"] = {
link = false,
preposition = "của",
class = "subpolity",
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 = "counties",
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 = "quốc gia",
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 = "districts",
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 = "quốc gia",
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 = "Địa danh",
},
["abbreviations of political divisions!"] = {
full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[political]] [[division]]s",
bare_category_breadcrumb = "political divisions",
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 = "regions",
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 = "states",
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 country"] = {
link = false,
default = {"Abbreviations of countries"},
},
["ABBREVIATION_OF county"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF department"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF district"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF division"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF FORMER country"] = {
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 subpolity",
},
["ABBREVIATION_OF province"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF region"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF state"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF subpolity"] = {
link = false,
default = {"Abbreviations of political divisions"},
},
["ABBREVIATION_OF territory"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
["ABBREVIATION_OF union territory"] = {
link = false,
fallback = "ABBREVIATION_OF subpolity",
},
---------- 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 = "Địa danh",
},
["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 = "Địa danh",
},
["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 = "Địa danh",
},
["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 = "quốc gia",
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 = "states",
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 "thành phố"
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 "thành phố" 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 = "Địa danh",
},
["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 = "quốc gia",
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 = "quốc gia",
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 = "Địa danh",
},
["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 = "political divisions",
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 country"] = {
link = false,
default = {"Former names of countries"},
},
["FORMER_NAME_OF place"] = {
link = false,
default = {"Former names of places"},
},
["FORMER_NAME_OF polity"] = {
link = false,
default = {"Former names of polities"},
},
["FORMER_NAME_OF region"] = {
link = false,
fallback = "FORMER_NAME_OF subpolity",
},
["FORMER_NAME_OF settlement"] = {
link = false,
default = {"Former names of settlements"},
},
["FORMER_NAME_OF subpolity"] = {
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 "thành phố"
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 "thành phố" 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 = "quốc gia",
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 = "quốc gia",
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 = "Địa danh",
},
["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 = "quốc gia",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"quốc gia"},
},
["nicknames for places!"] = {
full_category_link = "[[nickname]]s for [[place]]s",
bare_category_breadcrumb = "Địa danh",
bare_category_parent = "nicknames",
addl_bare_category_parents = {"Địa danh"},
},
["nicknames for states!"] = {
-- For categorizing nicknames for states of e.g. the United States
full_category_link = "[[nicknames]] for [[state]]s",
bare_category_breadcrumb = "states",
bare_category_parent = "nicknames for places",
addl_bare_category_parents = {"states"},
},
["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 "thành phố"
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 "thành phố" 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 = "Địa danh",
},
["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 = "quốc gia",
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 = "quốc gia",
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 = "Địa danh",
},
["OFFICIAL_NAME_OF country"] = {
link = false,
default = {"Official names of countries"},
},
["OFFICIAL_NAME_OF FORMER country"] = {
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 = {"states"},
},
["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
bvfu4grtb19muc2150pp14mkqat3vjb
Mô đun:place/locations
828
282249
2573002
2571783
2026-10-23T12:00:37Z
TheHighFighter2
42988
2573002
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"provinces", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "provinces", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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 = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Netherlands"] = {the = true, placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "provinces", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"provinces", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "provinces", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Netherlands",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
lappahlthbx5g0civgt4vd3loj79l9l
2573015
2573002
2026-10-23T15:07:31Z
TheHighFighter2
42988
2573015
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"provinces", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "provinces", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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 = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Netherlands"] = {the = true, placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "tỉnh", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"provinces", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "provinces", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Netherlands",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
fb90bm4qggc0wh6bv4sq0ul3eb1lz7q
2573016
2573015
2026-10-23T15:12:37Z
TheHighFighter2
42988
2573016
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"provinces", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "tỉnh", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", divs = {
{type = "tỉnh", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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", "tỉnh",
}, british_spelling = true},
["Gabon"] = {container = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Netherlands"] = {the = true, placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "tỉnh", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"tỉnh", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "provinces", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Netherlands",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
pqgbx5p6llan5o0rrmqaxshmkexwupl
2573017
2573016
2026-10-23T15:16:32Z
TheHighFighter2
42988
2573017
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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 = "tỉnh", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"tỉnh", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "tỉnh", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", divs = {
{type = "tỉnh", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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", "tỉnh",
}, british_spelling = true},
["Gabon"] = {container = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Netherlands"] = {the = true, placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "tỉnh", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"tỉnh", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"tỉnh", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "tỉnh", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Netherlands",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
51todcqdmrh8m0bh9im75c91i8rzkwa
2573019
2573017
2026-10-23T15:26:44Z
TheHighFighter2
42988
2573019
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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 = "tỉnh", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"tỉnh", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "tỉnh", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"tỉnh", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", divs = {
{type = "tỉnh", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", divs = {
{type = "tỉnh", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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", "tỉnh",
}, british_spelling = true},
["Gabon"] = {container = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Netherlands"] = {the = true, placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"provinces", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "tỉnh", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"tỉnh", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"tỉnh", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "tỉnh", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Netherlands",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Netherlands",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Netherlands",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
qbazfjn4w9t98xwj4lbeqnzwkx3ml0b
2573020
2573019
2026-10-23T15:31:05Z
TheHighFighter2
42988
2573020
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 string_utilities_module = "Module:string utilities"
local en_utilities_module = "Module:en-utilities"
local insert = table.insert
local concat = table.concat
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, Úc; 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", "State", "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 "County"
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. "quốc gia", "state", 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, Úc]] 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 == "thành phố"`, so that all cities get it set without explicitly needing to add a
group-level setting for this. Note that the condition `default_placetype == "thành phố"` 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, Nhật Bản]] 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 `"states"` 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 = "tỉnh", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"counties", "districts", "municipalities", "regional municipalities",
"rural municipalities", "parishes",
"Indian reserves",
"census divisions",
{type = "townships", prep = "in"},
}, ...},
}
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 = {
"counties",
{type = "regional county municipalities", container_parent_type = "regional municipalities"},
{type = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "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 = "counties"}`
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
`"quốc gia"`.
====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 == "thành phố"`, 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 == "thành phố" 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 == "quốc gia" or
defcon.placetype == "constituent country") 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 = "quốc gia"}
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 == "thành phố"` 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 == "thành phố")
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 "County" 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(", Anh$"),
```
or (when the political division is part of the key)
```
key_to_placename = make_key_to_placename(", Hàn Quốc$", "$")
```
]=]
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(", Anh")
```
(which will convert e.g. `"Hampshire"` into `"Hampshire, Anh"`)
or
```
placename_to_key = make_placename_to_key(", Hàn Quốc", " County")
```
(which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon, Hàn Quốc"`).
]=]
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 = {
["Trái Đất"] = {placetype = "planet", addl_parents = {"tự nhiên"},
fulldesc = "=là hành tinh thứ ba tính từ Mặt Trời", commonscat = "Earth"},
["châu Phi"] = {placetype = "continent", commonscat = "Africa", container = {key = "Trái Đất", placetype = "planet"}},
["châu Mỹ"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined",
wp = "Châu Mỹ"},
["Americas"] = {alias_of = "châu Mỹ"},
["America"] = {alias_of = "châu Mỹ"},
["Bắc Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["Caribe"] = {the = true, placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Trung Mỹ"] = {placetype = {"continental region", "region"}, container = {key = "Bắc Mỹ", placetype = "continent"}},
["Nam Mỹ"] = {placetype = "continent", container = {key = "châu Mỹ", placetype = "supercontinent"}},
["châu Nam Cực"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"},
fulldesc = "=lục địa nằm xa về phía nam và tây nhất trên Trái Đất, chứa Cực Nam địa lý và nằm trong Vùng Nam Cực của Nam Bán cầu"},
["Đại lục Á Âu"] = {placetype = {"supercontinent", "continent"}, container = {key = "Trái Đất", placetype = "planet"},
keydesc = "một khu vực đất đai rộng lớn, bao gồm châu Âu và châu Á"},
["châu Á"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Âu"] = {placetype = "continent", container = {key = "Đại lục Á Âu", placetype = "supercontinent"}},
["châu Đại Dương"] = {placetype = "continent", container = {key = "Trái Đất", placetype = "planet"}},
["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "châu Đại Dương", placetype = "continent"}},
}
export.continents_group = {
default_overriding_bare_label_parents = {}, -- container parents should be used
default_divs = {{type = "quốc gia", prep = "của"}},
-- 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 "continent" 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 = "châu Á", divs = {"provinces", "districts"}},
["Albania"] = {container = "châu Âu", divs = {"counties", "municipalities", "communes",
{type = "administrative units", cat_as = "communes"},
}, british_spelling = true},
["Algeria"] = {container = "châu Phi", divs = {"tỉnh", "communes", "districts", "municipalities"}},
["Andorra"] = {container = "châu Âu", divs = {"parishes"}, british_spelling = true},
["Angola"] = {container = "châu Phi", divs = {"provinces", "municipalities"}},
["Antigua and Barbuda"] = {container = "Caribe", divs = {"provinces"}, british_spelling = true},
["Argentina"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Armenia"] = {container = {"châu Âu", "châu Á"}, divs = {"provinces", "districts", "municipalities"},
british_spelling = true},
["Republic of Armenia"] = {alias_of = "Armenia"}, -- differs in "the"
-- Both a country and continent
["Úc"] = {container = "châu Đại Dương", divs = {
{type = "states", cat_as = "states and territories"},
{type = "territories", cat_as = "states and territories"},
{type = "ABBREVIATION_OF states", 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},
["Australia"] = {alias_of = "Úc"},
["Áo"] = {container = "châu Âu", divs = {"states", "districts", "municipalities"}, british_spelling = true},
["Azerbaijan"] = {container = {"châu Âu", "châu Á"}, divs = {"districts", "municipalities"}, british_spelling = true},
["Bahamas"] = {the = true, container = "Caribe", divs = {"districts"}, british_spelling = true, wp = "The %l"},
["Bahrain"] = {container = "châu Á", divs = {"governorates"}},
["Bangladesh"] = {container = "châu Á", divs = {"divisions", "districts", "municipalities"}, british_spelling = true},
["Barbados"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Belarus"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Bỉ"] = {container = "châu Âu", divs = {"regions", "tỉnh", "municipalities"}, british_spelling = true},
["Belize"] = {container = "Trung Mỹ", divs = {"districts"}, british_spelling = true},
["Benin"] = {container = "châu Phi", divs = {"departments", "communes"}},
["Bhutan"] = {container = "châu Á", divs = {"districts", "gewogs"}},
["Bolivia"] = {container = "Nam Mỹ", divs = {"provinces", "departments", "municipalities"}},
["Bosna và Hercegovina"] = {container = "châu Âu", divs = {"entities", "cantons", "municipalities"}, british_spelling = true},
["Bosnia and Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia và Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Herzegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia-Hercegovina"] = {alias_of = "Bosna và Hercegovina", display = true},
["Bosnia"] = {alias_of = "Bosna và Hercegovina", display = true},
["Botswana"] = {container = "châu Phi", divs = {"districts", "subdistricts"}, british_spelling = true},
["Brasil"] = {container = "Nam Mỹ", divs = {
"states", "municipalities", "macroregions",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Brazil"] = {alias_of = "Brasil", display = true},
["Brunei"] = {container = "châu Á", divs = {"districts", "mukims"}, british_spelling = true},
["Bulgaria"] = {container = "châu Âu", divs = {"provinces", "municipalities"}, british_spelling = true},
["Burkina Faso"] = {container = "châu Phi", divs = {"regions", "departments", "provinces"}},
["Burundi"] = {container = "châu Phi", divs = {"provinces", "communes"}},
["Campuchia"] = {container = "châu Á", divs = {"tỉnh", "districts"}},
["Cameroon"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Canada"] = {container = "Bắc Mỹ", divs = {
{type = "tỉnh", 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"},
"counties", "districts", "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 = "in"},
},
british_spelling = true},
["Cape Verde"] = {container = "châu Phi", divs = {"municipalities", "parishes"}},
["Cabo Verde"] = {alias_of = "Cape Verde", display = true},
["Cộng hòa Trung Phi"] = {container = "châu Phi", divs = {"prefectures", "subprefectures"}},
["CAR"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["C.A.R"] = {alias_of = "Cộng hòa Trung Phi", display = true},
["Tchad"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Chad"] = {alias_of = "Tchad", display = true},
["Chile"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "communes"}},
["Trung Quốc"] = {container = "châu Á", divs = {
{type = "tỉnh", 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 = "counties", 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.
"districts",
{type = "FORMER districts", cat_as = "former districts"},
"subdistricts",
"townships",
"municipalities",
{type = "direct-administered municipalities", cat_as = "municipalities"},
}},
["People's Republic of China"] = {alias_of = "Trung Quốc"}, -- differs in "the"
["Colombia"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Comoros"] = {the = true, container = "châu Phi", divs = {"autonomous islands"}},
["Costa Rica"] = {container = "Trung Mỹ", divs = {"provinces", "cantons"}},
["Croatia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Cuba"] = {container = "Caribe", divs = {"provinces", "municipalities"}},
["Cyprus"] = {container = {"châu Âu", "châu Á"}, divs = {"districts"}, british_spelling = true},
["Czech Republic"] = {the = true, container = "châu Âu", divs = {"regions", "districts", "municipalities"}, british_spelling = true},
["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the"
["Democratic Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"provinces", "territories"}},
["Congo"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["DRC"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["D.R.C"] = {alias_of = "Democratic Republic of the Congo", display = true, the = true},
["Đan Mạch"] = {container = "châu Âu", divs = {"regions", "municipalities", "dependent territories"},
british_spelling = true,
-- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country)
},
["Djibouti"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Dominica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Dominican Republic"] = {the = true, container = "Caribe", divs = {"provinces", "municipalities"},
keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"},
["Đông Timor"] = {container = "châu Á", divs = {"municipalities"}, wp = "Timor-Leste"},
["Timor-Leste"] = {alias_of = "Đông Timor", display = true},
["Ecuador"] = {container = "Nam Mỹ", divs = {"provinces", "cantons"}},
["Ai Cập"] = {container = "châu Phi", divs = {"governorates", "regions"}, british_spelling = true},
["El Salvador"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea Xích Đạo"] = {container = "châu Phi", divs = {"provinces"}},
["Eritrea"] = {container = "châu Phi", divs = {"regions", "subregions"}},
["Estonia"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Eswatini"] = {container = "châu Phi", british_spelling = true},
["Swaziland"] = {alias_of = "Eswatini", display = true},
["Ethiopia"] = {container = "châu Phi", divs = {"regions", "zones"}},
["Federated States of Micronesia"] = {the = true, container = "Micronesia", divs = {"states"}},
["Micronesia"] = {alias_of = "Federated States of Micronesia"},
["Fiji"] = {container = "Melanesia", divs = {"divisions", "provinces"}, british_spelling = true},
["Phần Lan"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Pháp"] = {container = "châu Âu", divs = {"regions", "cantons", "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", "tỉnh",
}, british_spelling = true},
["Gabon"] = {container = "châu Phi", divs = {"provinces", "departments"}},
["Gambia"] = {the = true, container = "châu Phi", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"},
["Gruzia"] = {container = {"châu Âu", "châu Á"}, divs = {"regions", "districts"},
keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l"},
["Georgia"] = {alias_of = "Gruzia"},
["Đức"] = {container = "châu Âu", divs = {
"states",
-- 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.
"regions",
"municipalities", "districts"}, british_spelling = true},
["Ghana"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Hy Lạp"] = {container = "châu Âu", divs = {"regions", "regional units", "municipalities",
{type = "peripheries", cat_as = {"regions"}},
}, british_spelling = true},
["Grenada"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Guatemala"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Guinea"] = {container = "châu Phi", divs = {"regions", "prefectures"}},
["Guinea-Bissau"] = {container = "châu Phi", divs = {"regions"}},
["Guyana"] = {container = "Nam Mỹ", divs = {"regions"}, british_spelling = true},
["Haiti"] = {container = "Caribe", divs = {"departments", "arrondissements"}},
["Honduras"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Hungary"] = {container = "châu Âu", divs = {"counties", "districts"}, british_spelling = true},
["Iceland"] = {container = "châu Âu", divs = {"regions", "municipalities", "counties"}, british_spelling = true},
["Ấn Độ"] = {container = "châu Á", divs = {
{type = "states", cat_as = "states and union territories"},
{type = "union territories", cat_as = "states and union territories"},
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states and union territories"},
{type = "ABBREVIATION_OF union territories", cat_as = "abbreviations of states and union territories"},
"divisions", "districts", "municipalities",
}, british_spelling = true},
["Indonesia"] = {container = "châu Á", divs = {"regencies", "provinces",
{type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"},
}},
["Iran"] = {container = "châu Á", divs = {"provinces", "counties"}},
["Iraq"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Ireland"] = {container = "châu Âu", addl_parents = {"British Isles"},
divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"},
["Republic of Ireland"] = {alias_of = "Ireland"}, -- differs in "the"
["Israel"] = {container = "châu Á", divs = {"districts"}},
["Ý"] = {container = "châu Âu", divs = {
"regions", "provinces", "metropolitan cities", "municipalities",
{type = "autonomous regions", cat_as = "regions"},
}, british_spelling = true},
["Bờ Biển Ngà"] = {container = "châu Phi", divs = {"districts", "regions"}},
-- 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 = "Bờ Biển Ngà"},
["Jamaica"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Nhật Bản"] = {container = "châu Á", divs = {"prefectures", "subprefectures", "municipalities"}},
["Jordan"] = {container = "châu Á", divs = {"governorates"}},
["Kazakhstan"] = {container = {"châu Á", "châu Âu"}, divs = {"regions", "districts"}},
["Kenya"] = {container = "châu Phi", divs = {"counties"}, british_spelling = true},
["Kiribati"] = {container = "Micronesia", british_spelling = true},
["Kosovo"] = {container = "châu Âu", divs = {"districts", "municipalities"}, british_spelling = true},
["Kuwait"] = {container = "châu Á", divs = {"governorates", "areas"}},
["Kyrgyzstan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Lào"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Latvia"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Lebanon"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Lesotho"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Liberia"] = {container = "châu Phi", divs = {"counties", "districts"}},
["Libya"] = {container = "châu Phi", divs = {"districts", "municipalities"}},
["Liechtenstein"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["Litva"] = {container = "châu Âu", divs = {"counties", "municipalities"}, british_spelling = true},
["Luxembourg"] = {container = "châu Âu", divs = {"cantons", "districts"}, british_spelling = true},
["Madagascar"] = {container = "châu Phi", divs = {"regions", "districts"}},
["Malawi"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Malaysia"] = {container = "châu Á", divs = {"states", "federal territories", "districts"}, british_spelling = true},
["Maldives"] = {container = "châu Á", divs = {"provinces", "administrative atolls"}, british_spelling = true},
["Mali"] = {container = "châu Phi", divs = {"regions", "cercles"}},
["Malta"] = {container = "châu Âu", divs = {"regions", "local councils"}, british_spelling = true},
["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}},
["Mauritania"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Mauritius"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Mexico"] = {container = "Bắc Mỹ", addl_parents = {"Trung Mỹ"}, divs = {
"states", "municipalities",
{type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"},
}},
["Moldova"] = {container = "châu Âu", divs = {
{type = "districts", 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 = {"city-state", "quốc gia"}, container = "châu Âu",
-- 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 = "quốc gia", prep = "của"},
is_city = true, british_spelling = true},
["Mông Cổ"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Montenegro"] = {container = "châu Âu", divs = {"municipalities"}},
["Maroc"] = {container = "châu Phi", divs = {"regions", "prefectures", "provinces"}},
["Mozambique"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Myanmar"] = {container = "châu Á",
divs = {"regions", "states", "union territories",
{type = "self-administered zones", cat_as = "self-administered areas"},
{type = "self-administered divisions", cat_as = "self-administered areas"},
"districts"}},
["Burma"] = {alias_of = "Myanmar"}, -- not display-canonicalizing; has political connotations
["Namibia"] = {container = "châu Phi", divs = {"regions", "constituencies"}, british_spelling = true},
["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true},
["Nepal"] = {container = "châu Á", divs = {"provinces", "districts"}},
["Hà Lan"] = {placetype = {"quốc gia", "constituent country"}, container = "châu Âu",
divs = {"tỉnh", "municipalities",
{type = "FORMER municipalities", cat_as = "former municipalities"},
"dependent territories", "constituent countries"}, british_spelling = true,
-- Wikipedia separates [[w:Netherlands]] (constituent country) from [[w:Kingdom of the Netherlands]]
-- (country)
},
["New Zealand"] = {container = "Polynesia", divs = {
"regions", "dependent territories", "territorial authorities",
{type = "districts", cat_as = "territorial authorities"},
},
british_spelling = true},
["Nicaragua"] = {container = "Trung Mỹ", divs = {"departments", "municipalities"}},
["Niger"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Nigeria"] = {container = "châu Phi", divs = {
"states",
-- 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 = "federal territories", cat_as = "states"},
"local government areas",
}, british_spelling = true},
["Cộng hòa Dân chủ Nhân dân Triều Tiên"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties"}},
["North Macedonia"] = {container = "châu Âu", divs = {"regions", "municipalities"}, british_spelling = true},
["Macedonia"] = {alias_of = "North Macedonia", display = true},
["Republic of North Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Republic of Macedonia"] = {alias_of = "North Macedonia"}, -- differs in "the"
["Na Uy"] = {container = "châu Âu",
divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"},
british_spelling = true},
["Oman"] = {container = "châu Á", divs = {"governorates", "provinces"}},
["Pakistan"] = {container = "châu Á", divs = {
{type = "provinces", cat_as = "provinces and territories"},
{type = "administrative territories", cat_as = "provinces and territories"},
{type = "federal territories", cat_as = "provinces and territories"},
{type = "territories", cat_as = "provinces and territories"},
"divisions", "districts",
}, british_spelling = true},
["Palau"] = {container = "Micronesia", divs = {"states"}},
["Palestine"] = {container = "châu Á", divs = {"governorates"}},
["State of Palestine"] = {alias_of = "Palestine"}, -- differs in "the"
["Panama"] = {container = "Trung Mỹ", divs = {"provinces", "districts"}},
["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true},
["Paraguay"] = {container = "Nam Mỹ", divs = {"departments", "districts"}},
["Peru"] = {container = "Nam Mỹ", divs = {"regions", "provinces", "districts"}},
["Philippines"] = {the = true, container = "châu Á", divs = {"regions", "tỉnh", "districts", "municipalities", "barangays"}},
["Ba Lan"] = {divs = {"voivodeships", "counties",
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
}, container = "châu Âu", british_spelling = true},
["Bồ Đào Nha"] = {container = "châu Âu", divs = {
{type = "autonomous regions", cat_as = "districts and autonomous regions"},
{type = "districts", cat_as = "districts and autonomous regions"},
"provinces", "municipalities"}, british_spelling = true},
["Qatar"] = {container = "châu Á", divs = {"municipalities", "zones"}},
["Republic of the Congo"] = {the = true, container = "châu Phi", divs = {"departments", "districts"}},
["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true},
["Romania"] = {container = "châu Âu", divs = {
"regions", "counties", "communes",
{type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"},
}, british_spelling = true},
["Nga"] = {container = {"châu Âu", "châu Á"}, divs = {
"federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities",
"districts", "federal districts"},
british_spelling = true},
["Rwanda"] = {container = "châu Phi", divs = {"provinces", "districts"}},
["Saint Kitts and Nevis"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true},
["Saint Lucia"] = {container = "Caribe", divs = {"districts"}, british_spelling = true},
["Saint Vincent and the Grenadines"] = {container = "Caribe", divs = {"parishes"}, british_spelling = true},
["Saint Vincent"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["SVG"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["S.V.G"] = {alias_of = "Saint Vincent and the Grenadines", display = true},
["Samoa"] = {container = "Polynesia", divs = {"districts"}, british_spelling = true},
["San Marino"] = {container = "châu Âu", divs = {"municipalities"}, british_spelling = true},
["São Tomé and Príncipe"] = {container = "châu Phi", divs = {"districts"}},
["São Tome and Principe"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tomé"] = {alias_of = "São Tomé and Príncipe", display = true},
["São Tome"] = {alias_of = "São Tomé and Príncipe", display = true},
["Ả Rập Xê Út"] = {container = "châu Á", divs = {"provinces", "governorates"}},
["Senegal"] = {container = "châu Phi", divs = {"regions", "departments"}},
["Serbia"] = {container = "châu Âu", divs = {"districts", "municipalities", "autonomous provinces"}},
["Seychelles"] = {container = "châu Phi", divs = {"districts"}, british_spelling = true},
["Sierra Leone"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Singapore"] = {container = "châu Á", divs = {"districts", "regions"}, british_spelling = true},
["Slovakia"] = {container = "châu Âu", divs = {"regions", "districts"}, british_spelling = true},
["Slovenia"] = {container = "châu Âu", divs = {"statistical regions", "municipalities"}, british_spelling = true},
-- Note: While the official name does not include "the" at the beginning,
-- it sounds strange in English to leave it out and it's commonly included.
["Solomon Islands"] = {the = true, container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Somalia"] = {container = "châu Phi", divs = {"regions", "districts"}},
["South Africa"] = {container = "châu Phi", divs = {
"provinces",
"districts",
{type = "district municipalities", cat_as = "districts"},
{type = "metropolitan municipalities", cat_as = "districts"},
"municipalities",
}, british_spelling = true},
["Hàn Quốc"] = {container = "châu Á", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}},
["Nam Sudan"] = {container = "châu Phi", divs = {"regions", "states", "counties"}, british_spelling = true},
["Tây Ban Nha"] = {container = "châu Âu", divs = {"autonomous communities", "provinces", "municipalities",
"comarcas", "autonomous cities"},
british_spelling = true},
["Sri Lanka"] = {container = "châu Á", divs = {"provinces", "districts"}, british_spelling = true},
["Sudan"] = {container = "châu Phi", divs = {"states", "districts"}, british_spelling = true},
["Suriname"] = {container = "Nam Mỹ", divs = {"districts"}},
["Thụy Điển"] = {container = "châu Âu", divs = {"tỉnh", "counties", "municipalities"}, british_spelling = true},
["Switzerland"] = {container = "châu Âu", divs = {"cantons", "municipalities", "districts"}, british_spelling = true},
["Syria"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Đài Loan"] = {container = "châu Á", divs = {"counties", "districts", "townships", "special municipalities"}},
["Republic of China"] = {alias_of = "Đài Loan"}, -- differs in "the", different political connotations
["Tajikistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Tanzania"] = {container = "châu Phi", divs = {"regions", "districts"}, british_spelling = true},
["Thái Lan"] = {container = "châu Á", divs = {"provinces", "districts", "subdistricts"}},
["Togo"] = {container = "châu Phi", divs = {"provinces", "prefectures"}},
["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true},
["Trinidad and Tobago"] = {container = "Caribe", divs = {"regions", "municipalities"}, british_spelling = true},
["Tunisia"] = {container = "châu Phi", divs = {"governorates", "delegations"}},
["Thổ Nhĩ Kỳ"] = {container = {"châu Âu", "châu Á"}, divs = {"tỉnh", "districts"}},
-- Foreign names generally get display-canonicalized.
["Türkiye"] = {alias_of = "Thổ Nhĩ Kỳ", display = true},
["Turkmenistan"] = {container = "châu Á", divs = {
-- The 5 regions are often also called provinces
"regions", {type = "tỉnh", cat_as = "regions"}, "districts"},
},
["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true},
["Uganda"] = {container = "châu Phi", divs = {"districts", "counties"}, british_spelling = true},
["Ukraina"] = {container = "châu Âu", 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 = "châu Á", 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 = "châu Âu", addl_parents = {"British Isles"},
divs = {"constituent countries", "counties", "districts", "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},
["Hoa Kỳ"] = {container = "Bắc Mỹ",
divs = {"counties", "county seats", "states", "territories", "dependent territories",
{type = "ABBREVIATION_OF states", 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 = "in"}, -- exist in Pennsylvania and New Jersey
"municipalities", -- these exist politically at least in Colorado and Connecticut
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
-- 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 = "Hoa Kỳ", display = true, the = true},
["U.S."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["USA"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["U.S.A."] = {alias_of = "Hoa Kỳ", display = true, the = true},
["United States of America"] = {alias_of = "Hoa Kỳ", display = true, the = true},
["Uruguay"] = {container = "Nam Mỹ", divs = {"departments", "municipalities"}},
["Uzbekistan"] = {container = "châu Á", divs = {"regions", "districts"}},
["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true},
["Vatican City"] = {placetype = {"city-state", "quốc gia"}, container = "châu Âu",
-- First placetype should be 'city-state' for to shown up in its description,
-- Its parent should still be "countries in Europe".
bare_category_parent_type = {type = "quốc gia", prep = "của"},
addl_parents = {"Rome"}, is_city = true, british_spelling = true},
["Vatican"] = {alias_of = "Vatican City"}, -- differs in "the"
["Venezuela"] = {container = "Nam Mỹ", divs = {"states", "municipalities"}},
["Việt Nam"] = {container = "châu Á", divs = {"tỉnh", "districts", "municipalities"}},
["Western Sahara"] = {placetype = {"territory", "quốc gia"}, container = "châu Phi",
bare_category_parent_type = {type = "quốc gia", prep = "của"},
},
-- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara
["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara"},
["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true},
["Yemen"] = {container = "châu Á", divs = {"governorates", "districts"}},
["Zambia"] = {container = "châu Phi", divs = {"provinces", "districts"}, british_spelling = true},
["Zimbabwe"] = {container = "châu Phi", divs = {"provinces", "districts"}, 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 = {"+++", "quốc gia"},
default_placetype = "quốc gia",
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", "châu Âu", "châu Á"},
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 = "Hoa Kỳ",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Anguilla"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Georgia
["Abkhazia"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Úc",
addl_parents = {"châu Á"},
},
-- constituent country of the Netherlands
["Aruba"] = {
placetype = {"constituent country", "quốc gia"},
container = "Hà Lan",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- British Overseas Territory
["Bermuda"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Bonaire"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Hà Lan",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- British Overseas Territory
["British Indian Ocean Territory"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Á"},
british_spelling = true,
},
-- British Overseas Territory
["British Virgin Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Norwegian dependent territory
["Bouvet Island"] = {
placetype = {"dependent territory", "territory"},
container = "Na Uy",
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Cayman Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- Australian external territory
["Christmas Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = "Pháp",
addl_parents = {"Bắc Mỹ"},
},
-- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands
["Cocos Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Á"},
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 = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- constituent country of the Netherlands
["Curaçao"] = {
placetype = {"constituent country", "quốc gia"},
container = "Hà Lan",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special territory of Chile
["Easter Island"] = {
placetype = {"special territory", "territory"},
container = "Chile",
addl_parents = {"Polynesia"},
},
-- British Overseas Territory
["Falkland Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- autonomous territory of Denmark
["Faroe Islands"] = {
the = true,
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- overseas department and region of France
["French Guiana"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Nam Mỹ"},
british_spelling = true,
},
-- overseas collectivity of France
["French Polynesia"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- French overseas territory
["French Southern and Antarctic Lands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "Pháp",
addl_parents = {"châu Phi"},
},
-- British Overseas Territory
["Gibraltar"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"châu Âu"},
is_city = true,
british_spelling = true,
},
-- autonomous territory of Denmark
["Greenland"] = {
placetype = {"autonomous territory", "territory"},
container = "Đan Mạch",
addl_parents = {"Bắc Mỹ"},
divs = {"municipalities"},
british_spelling = true,
},
-- overseas department and region of France
["Guadeloupe"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
addl_parents = {"Caribe"},
divs = {"communes"},
british_spelling = true,
},
-- unincorporated territory of the United States
["Guam"] = {
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- 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", "châu Âu"},
british_spelling = true,
wp = "Bailiwick of %l",
},
["Bailiwick of Guernsey"] = {alias_of = "Guernsey"},
-- Australian external territory
["Heard Island and McDonald Islands"] = {
the = true,
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"châu Phi"},
},
-- special administrative region of China
["Hồng Kông"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
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", "châu Âu"},
british_spelling = true,
},
-- Norwegian unincorporated area
["Jan Mayen"] = {
placetype = {"unincorporated area", "dependent territory", "territory", "island"},
container = "Na Uy",
addl_parents = {"châu Âu"},
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", "châu Âu"},
british_spelling = true,
},
["Bailiwick of Jersey"] = {alias_of = "Jersey"},
-- special administrative region of China
["Ma Cao"] = {
placetype = {"special administrative region", "thành phố"},
container = "Trung Quốc",
is_city = true,
british_spelling = true,
},
-- overseas department and region of France
["Martinique"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas department and region of France
["Mayotte"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- British Overseas Territory
["Montserrat"] = {
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- special collectivity of France
["New Caledonia"] = {
placetype = {"special collectivity", "collectivity"},
container = "Pháp",
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 = {"Antarctica"},
british_spelling = true,
},
-- self-governing but in free association with New Zealand
["Niue"] = {
placetype = {"quốc gia"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- Australian external territory
["Norfolk Island"] = {
placetype = {"external territory", "territory"},
container = "Úc",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Cyprus
["Northern Cyprus"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Cyprus", "Thổ Nhĩ Kỳ", "châu Âu", "châu Á"},
divs = {"districts"},
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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- British Overseas Territory
["Pitcairn Islands"] = {
the = true,
placetype = {"overseas territory", "territory"},
container = "United Kingdom",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- commonwealth of the United States
["Puerto Rico"] = {
placetype = {"commonwealth", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
divs = {"municipalities"},
},
-- overseas department and region of France
["Réunion"] = {
placetype = {"overseas department", "department", "administrative region", "region"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"châu Phi"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Saba"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Hà Lan",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- overseas collectivity of France
["Saint Barthélemy"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Caribe"},
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", "châu Phi"},
british_spelling = true,
},
-- constituent parts of the combined oveseas territory
["Ascension Island"] = {
placetype = {"constituent part", "territory", "island"},
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", "island"},
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 = "Pháp",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- overseas collectivity of France
["Saint Pierre and Miquelon"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
divs = {"communes"},
addl_parents = {"Bắc Mỹ"},
british_spelling = true,
},
-- special municipality of the Netherlands
["Sint Eustatius"] = {
placetype = {"special municipality", "municipality", "overseas territory", "territory"},
container = "Hà Lan",
addl_parents = {"Caribe"},
is_city = true,
british_spelling = true,
},
-- constituent country of the Netherlands
["Sint Maarten"] = {
placetype = {"constituent country", "quốc gia"},
container = "Hà Lan",
addl_parents = {"Caribe"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Somalia
["Somaliland"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Somalia", "châu Phi"},
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", "quốc gia"},
addl_parents = {"Georgia", "châu Âu", "châu Á"},
keydesc = "the de-facto independent state of [[South Ossetia]], internationally recognized as part of the country of [[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 = "Na Uy",
addl_parents = {"châu Âu"},
british_spelling = true,
},
-- dependent territory of New Zealand
["Tokelau"] = {
placetype = {"dependent territory", "territory"},
container = "New Zealand",
addl_parents = {"Polynesia"},
british_spelling = true,
},
-- de-facto independent state, internationally recognized as part of Moldova
["Transnistria"] = {
placetype = {"unrecognized country", "quốc gia"},
addl_parents = {"Moldova", "châu Âu"},
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 = {"Caribe"},
british_spelling = true,
},
-- unincorporated territory of the United States
["United States Minor Outlying Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribe"},
},
-- 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 = "Hoa Kỳ",
addl_parents = {"Micronesia"},
},
-- unincorporated territory of the United States
["United States Virgin Islands"] = {
the = true,
placetype = {"unincorporated territory", "overseas territory", "territory"},
container = "Hoa Kỳ",
addl_parents = {"Caribe"},
},
["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 and Futuna"] = {
placetype = {"overseas collectivity", "collectivity"},
container = "Pháp",
addl_parents = {"Polynesia"},
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, "quốc gia"),
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", "quốc gia"},
addl_parents = {"Azerbaijan", "châu Âu", "châu Á"},
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 = "châu Âu", british_spelling = true},
["East Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["North Vietnam"] = {container = "châu Á", addl_parents = {"Vietnam"}},
["Persia"] = {placetype = {"empire", "quốc gia"}, container = "châu Á", divs = {"provinces"}},
["Byzantine Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"},
addl_parents = {"Ancient Europe", "Ancient Near East"},
divs = {
"provinces", "themes",
}},
["Roman Empire"] = {
the = true, placetype = {"empire", "quốc gia"}, container = {"châu Âu", "châu Phi", "châu Á"}, addl_parents = {"Rome"},
divs = {
"provinces",
{type = "FORMER provinces", cat_as = "provinces"},
}},
["Việt Nam Cộng hòa"] = {container = "châu Á", commonscat = "South Vietnam", addl_parents = {"Việt Nam"}},
["Soviet Union"] = {
the = true, container = {"châu Âu", "châu Á"}, divs = {"republics", "autonomous republics"},
british_spelling = true},
["West Germany"] = {container = "châu Âu", addl_parents = {"Đức"}, british_spelling = true},
["Yugoslavia"] = {container = "châu Âu", divs = {"districts"},
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 = "quốc gia",
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 = {
["Lãnh thổ Thủ đô Úc, Úc"] = {placetype = "territory"},
["Jervis Bay Territory, Úc"] = {placetype = "territory"},
["New South Wales, Úc"] = {},
["Northern Territory, Úc"] = {placetype = "territory"},
["Queensland, Úc"] = {},
["South Australia, Úc"] = {},
["Tasmania, Úc"] = {},
["Victoria, Úc"] = {},
["Western Australia, Úc"] = {},
}
-- states and territories of Australia
export.australia_group = {
default_container = "Úc",
default_placetype = "state",
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 = "Áo",
default_placetype = "state",
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 = "districts",
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 = "state",
default_divs = "municipalities",
data = export.brazil_states,
}
-- provinces (a.k.a. oblasts) of Bulgaria
export.bulgaria_provinces = {
["Blagoevgrad Province, Bulgaria"] = {},
["Burgas Province, Bulgaria"] = {},
["Dobrich Province, Bulgaria"] = {},
["Gabrovo Province, Bulgaria"] = {},
["Haskovo Province, Bulgaria"] = {},
["Kardzhali Province, Bulgaria"] = {},
["Kyustendil Province, Bulgaria"] = {},
["Lovech Province, Bulgaria"] = {},
["Montana Province, Bulgaria"] = {},
["Pazardzhik Province, Bulgaria"] = {},
["Pernik Province, Bulgaria"] = {},
["Pleven Province, Bulgaria"] = {},
["Plovdiv Province, Bulgaria"] = {},
["Razgrad Province, Bulgaria"] = {},
["Ruse Province, Bulgaria"] = {},
["Shumen Province, Bulgaria"] = {},
["Silistra Province, Bulgaria"] = {},
["Sliven Province, Bulgaria"] = {},
["Smolyan Province, Bulgaria"] = {},
["Sofia City Province, Bulgaria"] = {},
["Sofia Province, Bulgaria"] = {},
["Stara Zagora Province, Bulgaria"] = {},
["Targovishte Province, Bulgaria"] = {},
["Varna Province, Bulgaria"] = {},
["Veliko Tarnovo Province, Bulgaria"] = {},
["Vidin Province, Bulgaria"] = {},
["Vratsa Province, Bulgaria"] = {},
["Yambol Province, Bulgaria"] = {},
}
export.bulgaria_group = {
key_to_placename = make_key_to_placename(", Bulgaria$", " Province$"),
placename_to_key = make_placename_to_key(", Bulgaria", " Province"),
default_container = "Bulgaria",
--== source: https://en.wikipedia.org/wiki/NUTS_statistical_regions_of_Bulgaria ==
divs = {"regions", "planning regions", "provinces", "municipalities", "settlements"},
default_placetype = "province",
data = export.bulgaria_provinces,
}
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 = {"counties", "parishes", {type = "civil parishes", cat_as = "parishes"}}},
["Newfoundland and Labrador, Canada"] = {},
["Northwest Territories, Canada"] = {the = true, placetype = "territory"},
["Nova Scotia, Canada"] = {divs = {"counties", "regional municipalities"}},
["Nunavut, Canada"] = {placetype = "territory"},
["Ontario, Canada"] = {divs = {"counties", "regional municipalities", {type = "townships", prep = "in"}}},
["Prince Edward Island, Canada"] = {divs = {"counties", "parishes", "rural municipalities"}},
["Saskatchewan, Canada"] = {divs = {"rural municipalities"}},
["Quebec, Canada"] = {divs = {
"counties",
{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 = "regions", container_parent_type = false},
{type = "townships", prep = "in"},
{type = "parish municipalities", cat_as = {{type = "parishes", container_parent_type = "counties"}, "municipalities"}},
{type = "township municipalities", cat_as = {{type = "townships", prep = "in"}, "municipalities"}},
{type = "village municipalities", cat_as = {{type = "villages", prep = "in"}, "municipalities"}},
}},
["Yukon, Canada"] = {placetype = "territory"},
["Yukon Territory, Canada"] = {alias_of = "Yukon, Canada"},
}
-- 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 = "Trung Quốc",
default_placetype = "province",
default_divs = {
"prefectures", "prefecture-level cities",
"districts", "subdistricts", "townships",
{type = "counties", 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", "thành phố"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de
["Changshu"] = {container = "Jiangsu"}, -- 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", "thành phố"}}, -- 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"] = {container = "Fujian"}, -- 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", "thành phố"}}, -- 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", "thành phố"}}, -- 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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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"] = {container = "Zhejiang"}, -- 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 = "district", container = {key = "Chongqing", placetype = "direct-administered municipality"}, divs = {"subdistricts", "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 "county" 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 = "county", container = {key = "Suqian", placetype = "prefecture-level city"}, divs = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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 = {"subdistricts", "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"] = {container = "Jiangsu"}, -- 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Trung Quốc",
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", "thành phố"},
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.
"districts", "subdistricts", "townships",
{type = "counties", 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 = "Phần Lan",
default_placetype = "region",
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 = "Pháp",
-- Canonically these are 'administrative regions' but also treat as 'region' ('administrative region' falls back
-- to 'region').
default_placetype = "region",
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"}, -- 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", "region"),
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 = "Đức",
default_placetype = "state",
default_divs = {"districts", "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", "region"}, wp = "Monastic community of Mount Athos"},
}
-- regions of Greece
export.greece_group = {
default_container = "Hy Lạp",
default_placetype = "region",
data = export.greece_regions,
}
local india_polity_with_divisions = {"divisions", "districts"}
local india_polity_without_divisions = {"districts"}
-- 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 = "Ấn Độ",
default_placetype = "state",
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 = "counties",
-- 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 = "county",
data = export.ireland_counties,
}
export.italy_administrative_regions = {
["Abruzzo, Italy"] = {},
["Aosta Valley, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Apulia, Italy"] = {},
["Basilicata, Italy"] = {},
["Calabria, Italy"] = {},
["Campania, Italy"] = {},
["Emilia-Romagna, Italy"] = {},
["Friuli-Venezia Giulia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Lazio, Italy"] = {},
["Liguria, Italy"] = {},
["Lombardy, Italy"] = {},
["Marche, Italy"] = {},
["Molise, Italy"] = {},
["Piedmont, Italy"] = {},
["Sardinia, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Sicily, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Trentino-Alto Adige, Italy"] = {placetype = {"autonomous region", "administrative region", "region"}},
["Tuscany, Italy"] = {},
["Umbria, Italy"] = {},
["Veneto, Italy"] = {},
}
-- administrative regions of Italy
export.italy_group = {
default_container = "Ý",
default_placetype = "region",
data = export.italy_administrative_regions,
}
-- table of Japanese prefectures; interpolated into the main 'places' table, but also needed separately
export.japan_prefectures = {
["Aichi, Nhật Bản"] = {},
["Akita, Nhật Bản"] = {},
["Aomori, Nhật Bản"] = {},
["Chiba, Nhật Bản"] = {},
["Ehime, Nhật Bản"] = {},
["Fukui, Nhật Bản"] = {},
["Fukuoka, Nhật Bản"] = {},
["Fukushima, Nhật Bản"] = {},
["Gifu, Nhật Bản"] = {},
["Gunma, Nhật Bản"] = {},
["Hiroshima, Nhật Bản"] = {},
["Hokkaidō, Nhật Bản"] = {divs = "subprefectures", wp = "Hokkaidō"},
["Hyōgo, Nhật Bản"] = {},
["Hyogo, Nhật Bản"] = {alias_of = "Hyōgo, Nhật Bản", display = true},
["Ibaraki, Nhật Bản"] = {},
["Ishikawa, Nhật Bản"] = {},
["Iwate, Nhật Bản"] = {},
["Kagawa, Nhật Bản"] = {},
["Kagoshima, Nhật Bản"] = {},
["Kanagawa, Nhật Bản"] = {},
["Kōchi, Nhật Bản"] = {},
["Kochi, Nhật Bản"] = {alias_of = "Kōchi, Nhật Bản", display = true},
["Kumamoto, Nhật Bản"] = {},
["Kyoto, Nhật Bản"] = {},
["Mie, Nhật Bản"] = {},
["Miyagi, Nhật Bản"] = {},
["Miyazaki, Nhật Bản"] = {},
["Nagano, Nhật Bản"] = {},
["Nagasaki, Nhật Bản"] = {},
["Nara, Nhật Bản"] = {},
["Niigata, Nhật Bản"] = {},
["Ōita, Nhật Bản"] = {},
["Oita, Nhật Bản"] = {alias_of = "Ōita, Nhật Bản", display = true},
["Okayama, Nhật Bản"] = {},
["Okinawa, Nhật Bản"] = {},
["Ōsaka, Nhật Bản"] = {},
["Osaka, Nhật Bản"] = {alias_of = "Ōsaka, Nhật Bản", display = true},
["Saga, Nhật Bản"] = {},
["Saitama, Nhật Bản"] = {},
["Shiga, Nhật Bản"] = {},
["Shimane, Nhật Bản"] = {},
["Shizuoka, Nhật Bản"] = {},
["Tochigi, Nhật Bản"] = {},
["Tokushima, Nhật Bản"] = {},
["Tottori, Nhật Bản"] = {},
["Toyama, Nhật Bản"] = {},
["Wakayama, Nhật Bản"] = {},
["Yamagata, Nhật Bản"] = {},
["Yamaguchi, Nhật Bản"] = {},
["Yamanashi, Nhật Bản"] = {},
}
-- prefectures of Japan
export.japan_group = {
key_to_placename = make_key_to_placename(", Nhật Bản$", " $"),
placename_to_key = make_placename_to_key(", Nhật Bản", ""),
default_container = "Nhật Bản",
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 = "Lào",
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 = "governorate",
data = export.lebanon_governorates,
}
export.malaysia_states = {
["Johor, Malaysia"] = {},
["Kedah, Malaysia"] = {},
["Kelantan, Malaysia"] = {},
["Malacca, 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 = "state",
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 = "region",
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 = "state",
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", "region"}}, -- 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", "region"}}, -- capital [[Tiraspol]]
["Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova"},
}
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 = {"district", "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 = "Maroc",
default_placetype = "region",
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 = "Ai Cập",
default_placetype = "governorate",
data = export.egypt_governorates,
}
export.netherlands_provinces = {
["Drenthe, Netherlands"] = {},
["Flevoland, Netherlands"] = {},
["Friesland, Netherlands"] = {},
["Gelderland, Netherlands"] = {},
["Groningen, Netherlands"] = {wp = "%l (province)"},
["Limburg, Netherlands"] = {wp = "%l (%c)"},
["North Brabant, Netherlands"] = {},
-- Foreign forms get display-canonicalized.
["Noord-Brabant, Netherlands"] = {alias_of = "North Brabant, Netherlands", display = true},
["North Holland, Netherlands"] = {},
["Noord-Holland, Netherlands"] = {alias_of = "North Holland, Netherlands", display = true},
["Overijssel, Netherlands"] = {},
["South Holland, Netherlands"] = {},
["Zuid-Holland, Netherlands"] = {alias_of = "South Holland, Netherlands", display = true},
["Utrecht, Netherlands"] = {wp = "%l (province)"},
["Zeeland, Netherlands"] = {},
}
-- provinces of the Netherlands
export.netherlands_group = {
default_container = "Hà Lan",
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 = {"region", "district"}, 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 = {"region", "district"}, wp = "%l District"}, -- ISO 3166-2 code NZ-TAS, number 10, capital [[Richmond, New Zealand|Richmond]]
["Nelson, New Zealand"] = {placetype = {"region", "thành phố"}, wp = "%l, %c", is_city = true}, -- ISO 3166-2 code NZ-NSN, number 11, capital [[Nelson, New Zealand|Nelson]]
["Marlborough, New Zealand"] = {placetype = {"region", "district"}, 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 = "region",
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 = {"federal territory", "territory", "state"}, 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 = "state",
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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên",
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 = "Na Uy",
default_placetype = "county",
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 = {"federal territory", "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, Philippines"] = {wp = "%l (province)"},
["Agusan del Norte, Philippines"] = {},
["Agusan del Sur, Philippines"] = {},
["Aklan, Philippines"] = {},
["Albay, Philippines"] = {},
["Antique, Philippines"] = {wp = "%l (province)"},
["Apayao, Philippines"] = {},
["Aurora, Philippines"] = {wp = "%l (province)"},
["Basilan, Philippines"] = {},
["Bataan, Philippines"] = {},
["Batanes, Philippines"] = {},
["Batangas, Philippines"] = {},
["Benguet, Philippines"] = {},
["Biliran, Philippines"] = {},
["Bohol, Philippines"] = {},
["Bukidnon, Philippines"] = {},
["Bulacan, Philippines"] = {},
["Cagayan, Philippines"] = {},
["Camarines Norte, Philippines"] = {},
["Camarines Sur, Philippines"] = {},
["Camiguin, Philippines"] = {},
["Capiz, Philippines"] = {},
["Catanduanes, Philippines"] = {},
["Cavite, Philippines"] = {},
["Cebu, Philippines"] = {},
["Cotabato, Philippines"] = {},
["Davao de Oro, Philippines"] = {},
["Davao del Norte, Philippines"] = {},
["Davao del Sur, Philippines"] = {},
["Davao Occidental, Philippines"] = {},
["Davao Oriental, Philippines"] = {},
["Dinagat Islands, Philippines"] = {the = true},
["Eastern Samar, Philippines"] = {},
["Guimaras, Philippines"] = {},
["Ifugao, Philippines"] = {},
["Ilocos Norte, Philippines"] = {},
["Ilocos Sur, Philippines"] = {},
["Iloilo, Philippines"] = {},
["Isabela, Philippines"] = {wp = "%l (province)"},
["Kalinga, Philippines"] = {wp = "%l (province)"},
["La Union, Philippines"] = {},
["Laguna, Philippines"] = {wp = "%l (province)"},
["Lanao del Norte, Philippines"] = {},
["Lanao del Sur, Philippines"] = {},
["Leyte, Philippines"] = {wp = "%l (province)"},
["Maguindanao del Norte, Philippines"] = {},
["Maguindanao del Sur, Philippines"] = {},
["Marinduque, Philippines"] = {},
["Masbate, Philippines"] = {},
["Misamis Occidental, Philippines"] = {},
["Misamis Oriental, Philippines"] = {},
["Mountain Province, Philippines"] = {},
["Negros Occidental, Philippines"] = {},
["Negros Oriental, Philippines"] = {},
["Northern Samar, Philippines"] = {},
["Nueva Ecija, Philippines"] = {},
["Nueva Vizcaya, Philippines"] = {},
["Occidental Mindoro, Philippines"] = {},
["Oriental Mindoro, Philippines"] = {},
["Palawan, Philippines"] = {},
["Pampanga, Philippines"] = {},
["Pangasinan, Philippines"] = {},
["Quezon, Philippines"] = {},
["Quirino, Philippines"] = {},
["Rizal, Philippines"] = {wp = "%l (province)"},
["Romblon, Philippines"] = {},
["Samar, Philippines"] = {wp = "%l (province)"},
["Sarangani, Philippines"] = {},
["Siquijor, Philippines"] = {},
["Sorsogon, Philippines"] = {},
["South Cotabato, Philippines"] = {},
["Southern Leyte, Philippines"] = {},
["Sultan Kudarat, Philippines"] = {},
["Sulu, Philippines"] = {},
["Surigao del Norte, Philippines"] = {},
["Surigao del Sur, Philippines"] = {},
["Tarlac, Philippines"] = {},
["Tawi-Tawi, Philippines"] = {},
["Zambales, Philippines"] = {},
["Zamboanga del Norte, Philippines"] = {},
["Zamboanga del Sur, Philippines"] = {},
["Zamboanga Sibugay, Philippines"] = {},
-- not a province but treated as one; allow it to be referred to as a province in holonyms
["Metro Manila, Philippines"] = {placetype = {"region", "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 = "Ba Lan",
default_placetype = "voivodeship",
default_divs = {
-- "counties", -- not enough of them currently
{type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}},
},
data = export.poland_voivodeships,
}
export.portugal_districts_and_autonomous_regions = {
["Azores, Portugal"] = {the = true, placetype = {"autonomous region", "region"}},
["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", "region"}},
["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 = "district",
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 = "county",
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, Russia"] =
{the = true, placetype = {"autonomous oblast", "oblast"},
bare_category_parent_type = {"federal subjects", "autonomous oblasts"}},
-- autonomous okrugs
["Chukotka Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Chukotka, Russia"] = {alias_of = "Chukotka Autonomous Okrug, Russia"},
["Khanty-Mansi Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Khanty-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Khantia-Mansia, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Yugra, Russia"] = {alias_of = "Khanty-Mansi Autonomous Okrug, Russia"},
["Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Nenetsia, Russia"] = {alias_of = "Nenets Autonomous Okrug, Russia"},
["Yamalo-Nenets Autonomous Okrug, Russia"] = russia_autonomous_okrug_the,
["Yamalia, Russia"] = {alias_of = "Yamalo-Nenets Autonomous Okrug, Russia"},
-- krais
["Altai Krai, Russia"] = russia_krai,
["Kamchatka Krai, Russia"] = russia_krai,
["Khabarovsk Krai, Russia"] = russia_krai,
["Krasnodar Krai, Russia"] = russia_krai,
["Krasnoyarsk Krai, Russia"] = russia_krai,
["Perm Krai, Russia"] = russia_krai,
["Primorsky Krai, Russia"] = russia_krai,
["Stavropol Krai, Russia"] = russia_krai,
["Zabaykalsky Krai, Russia"] = russia_krai,
-- oblasts
["Amur Oblast, Russia"] = russia_oblast,
["Arkhangelsk Oblast, Russia"] = russia_oblast,
["Astrakhan Oblast, Russia"] = russia_oblast,
["Belgorod Oblast, Russia"] = russia_oblast,
["Bryansk Oblast, Russia"] = russia_oblast,
["Chelyabinsk Oblast, Russia"] = russia_oblast,
["Irkutsk Oblast, Russia"] = russia_oblast,
["Ivanovo Oblast, Russia"] = russia_oblast,
["Kaliningrad Oblast, Russia"] = russia_oblast,
["Kaluga Oblast, Russia"] = russia_oblast,
["Kemerovo Oblast, Russia"] = russia_oblast,
["Kirov Oblast, Russia"] = russia_oblast,
["Kostroma Oblast, Russia"] = russia_oblast,
["Kurgan Oblast, Russia"] = russia_oblast,
["Kursk Oblast, Russia"] = russia_oblast,
["Leningrad Oblast, Russia"] = russia_oblast,
["Lipetsk Oblast, Russia"] = russia_oblast,
["Magadan Oblast, Russia"] = russia_oblast,
["Moscow Oblast, Russia"] = russia_oblast,
["Murmansk Oblast, Russia"] = russia_oblast,
["Nizhny Novgorod Oblast, Russia"] = russia_oblast,
["Novgorod Oblast, Russia"] = russia_oblast,
["Novosibirsk Oblast, Russia"] = russia_oblast,
["Omsk Oblast, Russia"] = russia_oblast,
["Orenburg Oblast, Russia"] = russia_oblast,
["Oryol Oblast, Russia"] = russia_oblast,
["Penza Oblast, Russia"] = russia_oblast,
["Pskov Oblast, Russia"] = russia_oblast,
["Rostov Oblast, Russia"] = russia_oblast,
["Ryazan Oblast, Russia"] = russia_oblast,
["Sakhalin Oblast, Russia"] = russia_oblast,
["Samara Oblast, Russia"] = russia_oblast,
["Saratov Oblast, Russia"] = russia_oblast,
["Smolensk Oblast, Russia"] = russia_oblast,
["Sverdlovsk Oblast, Russia"] = russia_oblast,
["Tambov Oblast, Russia"] = russia_oblast,
["Tomsk Oblast, Russia"] = russia_oblast,
["Tula Oblast, Russia"] = russia_oblast,
["Tver Oblast, Russia"] = russia_oblast,
["Tyumen Oblast, Russia"] = russia_oblast,
["Ulyanovsk Oblast, Russia"] = russia_oblast,
["Vladimir Oblast, Russia"] = russia_oblast,
["Volgograd Oblast, Russia"] = russia_oblast,
["Vologda Oblast, Russia"] = russia_oblast,
["Voronezh Oblast, Russia"] = russia_oblast,
["Yaroslavl Oblast, Russia"] = 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, Russia"] = russia_republic_no_the,
["Republic of Adygea, Russia"] = {alias_of = "Adygea, Russia"},
["Bashkortostan, Russia"] = russia_republic_no_the,
["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"},
["Buryatia, Russia"] = russia_republic_no_the,
["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia"},
["Dagestan, Russia"] = russia_republic_no_the,
["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia"},
["Ingushetia, Russia"] = russia_republic_no_the,
["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia"},
["Kalmykia, Russia"] = russia_republic_no_the,
["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia"},
["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"),
["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia"},
["Khakassia, Russia"] = russia_republic_no_the,
["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia"},
["Mordovia, Russia"] = russia_republic_no_the,
["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia"},
["North Ossetia-Alania, Russia"] = make_russia_federal_subject_spec("republic", nil, "North Ossetia–Alania"), -- with en-dash
["Republic of North Ossetia-Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia"},
["North Ossetia, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Alania, Russia"] = {alias_of = "North Ossetia-Alania, Russia", display = true},
["Tatarstan, Russia"] = russia_republic_no_the,
["Republic of Tatarstan, Russia"] = {alias_of = "Tatarstan, Russia"},
["Altai Republic, Russia"] = russia_republic_the,
["Chechnya, Russia"] = russia_republic_no_the,
["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia"},
["Chuvashia, Russia"] = russia_republic_no_the,
["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia"},
["Kabardino-Balkaria, Russia"] = russia_republic_no_the,
["Kabardino-Balkariya, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = true},
["Kabardino-Balkarian Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia"},
["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia",
display = "Kabardino-Balkarian Republic, Russia"},
["Karachay-Cherkessia, Russia"] = russia_republic_no_the,
["Karachay-Cherkess Republic, Russia"] = {alias_of = "Karachay-Cherkessia, Russia"},
["Komi, Russia"] = make_russia_federal_subject_spec("republic", nil, "Komi Republic"),
["Komi Republic, Russia"] = {alias_of = "Komi, Russia"},
["Mari El, Russia"] = russia_republic_no_the,
["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia"},
["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"),
["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutia, Russia"] = {alias_of = "Sakha, Russia"},
["Yakutiya, Russia"] = {alias_of = "Sakha, Russia", display = "Yakutia, Russia"},
["Republic of Yakutia (Sakha), Russia"] = {alias_of = "Sakha, Russia", display = "Sakha Republic, Russia",
the = true},
["Tuva, Russia"] = russia_republic_no_the,
["Tyva, Russia"] = {alias_of = "Tuva, Russia", display = true},
["Tuva Republic, Russia"] = {alias_of = "Tuva, Russia"},
["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia"},
["Udmurtia, Russia"] = russia_republic_no_the,
["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia"},
-- Not included due to being unrecognized and only partly controlled:
-- ["Crimea, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Crimea (Russia)")
-- ["Donetsk People's Republic, Russia"] = russia_republic_the,
-- ["Luhansk People's Republic, Russia"] = russia_republic_the,
-- ["Zaporozhye Oblast, Russia"] = make_russia_federal_subject_spec("oblast", nil, "Russian occupation of Zaporizhzhia Oblast"),
-- ["Kherson Oblast, Russia"] = 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 = "Nga",
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, Saudi Arabia"] = {},
["Mecca Province, Saudi Arabia"] = {},
-- Name is too generic to assume it's in Saudi Arabia if not specified.
["Eastern Province, Saudi Arabia"] = {no_auto_augment_container = true, wp = "%l, %c"},
["Medina Province, Saudi Arabia"] = {wp = "%l (%c)"},
["Aseer Province, Saudi Arabia"] = {wp = "Asir"},
["Asir Province, Saudi Arabia"] = {alias_of = "Aseer Province, Saudi Arabia", display = true},
["Jazan Province, Saudi Arabia"] = {},
["Qassim Province, Saudi Arabia"] = {wp = "Al-Qassim Province"},
["Al-Qassim Province, Saudi Arabia"] = {alias_of = "Qassim Province, Saudi Arabia", display = true},
["Tabuk Province, Saudi Arabia"] = {},
["Hail Province, Saudi Arabia"] = {wp = "Ḥa'il Province"},
["Ha'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Ḥa'il Province, Saudi Arabia"] = {alias_of = "Hail Province, Saudi Arabia", display = true},
["Al-Jouf Province, Saudi Arabia"] = {wp = "Al-Jawf Province"},
["Al-Jawf Province, Saudi Arabia"] = {alias_of = "Al-Jouf Province, Saudi Arabia", display = true},
["Najran Province, Saudi Arabia"] = {},
["Northern Borders Province, Saudi Arabia"] = {},
["Al-Bahah Province, Saudi Arabia"] = {},
}
-- provinces of Saudi Arabia
export.saudi_arabia_group = {
key_to_placename = make_key_to_placename(", Saudi Arabia$", " Province$"),
placename_to_key = make_placename_to_key(", Saudi Arabia", " Province"),
default_container = "Ả Rập Xê Út",
default_placetype = "province",
data = export.saudi_arabia_provinces,
}
export.south_africa_provinces = {
["Eastern Cape, South Africa"] = {the = true},
["Free State, South Africa"] = {the = true, wp = "%l (province)"},
["Gauteng, South Africa"] = {},
["KwaZulu-Natal, South Africa"] = {},
["Limpopo, South Africa"] = {},
["Mpumalanga, South Africa"] = {},
-- per Wikipedia and other sources, `North West` doesn't normally have `the` before it
["North West, South Africa"] = {wp = "%l (South African province)"},
["Northern Cape, South Africa"] = {the = true},
["Western Cape, South Africa"] = {the = true},
}
-- provinces of South Africa
export.south_africa_group = {
default_container = "South Africa",
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 = "Hàn Quốc",
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"},
}
-- autonomous communities of Spain
export.spain_group = {
default_container = "Tây Ban Nha",
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 = "Đài Loan",
default_placetype = "county",
default_divs = {"districts", "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$", " Province$"),
placename_to_key = make_placename_to_key(", Thailand", " Province"),
default_container = "Thái Lan",
default_placetype = "province",
default_divs = "districts",
-- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province'
default_wp = "%e province",
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 = "Thổ Nhĩ Kỳ",
default_placetype = "province",
default_divs = "districts",
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 = "Ukraina",
default_placetype = "oblast",
default_divs = {"raions", "hromadas"},
data = export.ukraine_oblasts,
}
export.united_kingdom_constituent_countries = {
["England"] = {divs = {
"counties",
"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"}},
{type = "civil parishes", container_parent_type = false},
}},
["Northern Ireland"] = {
placetype = {"constituent country", "province", "quốc gia"},
divs = {"counties", "districts"},
},
["Scotland"] = {divs = {
{type = "council areas", container_parent_type = false},
"districts",
}},
["Wales"] = {divs = {
"counties",
{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 = {"constituent country", "quốc gia"},
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 = "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",
},
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 = "constituent country"},
default_placetype = "county",
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 = "constituent country"},
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 = "thành phố"},
["Carmarthenshire, Wales"] = {placetype = "county"},
["Ceredigion, Wales"] = {placetype = "county"},
["Conwy, Wales"] = {wp = "%l County Borough"},
["Denbighshire, Wales"] = {placetype = "county"},
["Flintshire, Wales"] = {placetype = "county"},
["Gwynedd, Wales"] = {placetype = "county"},
["Isle of Anglesey, Wales"] = {the = true, placetype = "county"},
["Anglesey, Wales"] = {alias_of = "Isle of Anglesey, Wales"}, -- differs in "the"
["Merthyr Tydfil, Wales"] = {wp = "%l County Borough"},
["Monmouthshire, Wales"] = {placetype = "county"},
["Neath Port Talbot, Wales"] = {},
-- ["Newport, Wales"] = {placetype = "thành phố", wp = "%l, %c"},
["Pembrokeshire, Wales"] = {placetype = "county"},
["Powys, Wales"] = {placetype = "county"},
["Rhondda Cynon Taf, Wales"] = {},
-- ["Swansea, Wales"] = {placetype = "thành phố"},
["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 = "constituent country"},
default_placetype = "county borough",
data = export.wales_principal_areas,
}
export.united_states_states = {
["Alabama, USA"] = {},
["Alaska, USA"] = {divs = {
{type = "boroughs", container_parent_type = "counties"},
{type = "borough seats", container_parent_type = "county seats"},
}},
["Arizona, USA"] = {},
["Arkansas, USA"] = {},
["California, USA"] = {},
["Colorado, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Connecticut, USA"] = {divs = {"counties", "county seats", "municipalities"}},
["Delaware, USA"] = {},
["Florida, USA"] = {},
["Georgia, USA"] = {wp = "%l (U.S. state)"},
["Hawaii, USA"] = {addl_parents = {"Polynesia"}},
["Idaho, USA"] = {},
["Illinois, USA"] = {},
["Indiana, USA"] = {},
["Iowa, USA"] = {},
["Kansas, USA"] = {},
["Kentucky, USA"] = {},
["Louisiana, USA"] = {divs = {
{type = "parishes", container_parent_type = "counties"},
{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 = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["New Mexico, USA"] = {},
["New York, USA"] = {wp = "%l (state)"},
["North Carolina, USA"] = {},
["North Dakota, USA"] = {},
["Ohio, USA"] = {},
["Oklahoma, USA"] = {},
["Oregon, USA"] = {},
["Pennsylvania, USA"] = {divs = {
"counties", "county seats",
{type = "boroughs", prep = "in"},
}},
["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 = "Hoa Kỳ",
default_placetype = "state",
default_divs = {"counties", "county seats"},
addl_divs = {
{type = "census-designated places", prep = "in"},
{type = "unincorporated communities", prep = "in"},
},
data = export.united_states_states,
}
export.vietnam_provinces = {
-- [[Northeast (Vietnam)|Northeast]] region
["Bắc Giang, Việt Nam"] = {}, -- capital [[Bắc Giang]]
["Bắc Kạn, Việt Nam"] = {}, -- capital [[Bắc Kạn]]
["Cao Bằng, Việt Nam"] = {}, -- capital [[Cao Bằng]]
["Hà Giang, Việt Nam"] = {}, -- capital [[Hà Giang]]
["Lạng Sơn, Việt Nam"] = {}, -- capital [[Lạng Sơn]]
["Phú Thọ, Việt Nam"] = {}, -- capital [[Việt Trì]]
["Quảng Ninh, Việt Nam"] = {}, -- capital [[Hạ Long]]
["Thái Nguyên, Việt Nam"] = {}, -- capital [[Thái Nguyên]]
["Tuyên Quang, Việt Nam"] = {}, -- capital [[Tuyên Quang]]
-- [[Northwest (Vietnam)|Northwest]] region
["Lào Cai, Việt Nam"] = {}, -- capital [[Lào Cai]]
["Yên Bái, Việt Nam"] = {}, -- capital [[Yên Bái]]
["Điện Biên, Việt Nam"] = {}, -- capital [[Điện Biên Phủ]]
["Hòa Bình, Việt Nam"] = {},
["Lai Châu, Việt Nam"] = {}, -- capital [[Lai Châu]]
["Sơn La, Việt Nam"] = {}, -- capital [[Sơn La]]
-- [[Red River Delta]] region
["Bắc Ninh, Việt Nam"] = {}, -- capital [[Bắc Ninh]]
["Hà Nam, Việt Nam"] = {}, -- capital [[Phủ Lý]]
["Hải Dương, Việt Nam"] = {}, -- capital [[Hải Dương]]
["Hưng Yên, Việt Nam"] = {}, -- capital [[Hưng Yên]]
["Nam Định, Việt Nam"] = {}, -- capital [[Nam Định]]
["Ninh Bình, Việt Nam"] = {}, -- capital [[Ninh Bình|Hoa Lư]]
["Thái Bình, Việt Nam"] = {}, -- capital [[Thái Bình]]
["Vĩnh Phúc, Việt Nam"] = {}, -- capital [[Vĩnh Yên]]
-- ["Hanoi"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hoàn Kiếm district]]
-- ["Haiphong"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hồng Bàng district]]
-- [[North Central Coast]] region
["Hà Tĩnh, Việt Nam"] = {}, -- capital [[Hà Tĩnh]]
["Nghệ An, Việt Nam"] = {}, -- capital [[Vinh]]
["Quảng Bình, Việt Nam"] = {}, -- capital [[Đồng Hới]]
["Quảng Trị, Việt Nam"] = {}, -- capital [[Đông Hà]]
["Thanh Hóa, Việt Nam"] = {},
-- ["Hue"] = {placetype = {"municipality", "thành phố"}, wp = "Huế"}, -- capital [[Thuận Hoá district]]
-- [[Central Highlands (Vietnam)|Central Highlands]] region
["Đắk Lắk, Việt Nam"] = {}, -- capital [[Buôn Ma Thuột]]
["Đăk Nông, Việt Nam"] = {}, -- capital [[Gia Nghĩa]]
["Gia Lai, Việt Nam"] = {}, -- capital [[Pleiku]]
["Kon Tum, Việt Nam"] = {}, -- capital [[Kon Tum]]
["Lâm Đồng, Việt Nam"] = {}, -- capital [[Đà Lạt]]
-- [[South Central Coast]] region
["Bình Định, Việt Nam"] = {}, -- capital [[Quy Nhon]]
["Bình Thuận, Việt Nam"] = {}, -- capital [[Phan Thiết]]
["Khánh Hòa, Việt Nam"] = {},
["Ninh Thuận, Việt Nam"] = {}, -- capital [[Phan Rang–Tháp Chàm]]
["Phú Yên, Việt Nam"] = {}, -- capital [[Tuy Hoà]]
["Quảng Nam, Việt Nam"] = {}, -- capital [[Tam Kỳ]]
["Quảng Ngãi, Việt Nam"] = {}, -- capital [[Quảng Ngãi]]
-- ["Da Nang"] = {placetype = {"municipality", "thành phố"}}, -- capital [[Hải Châu district]]
-- [[Southeast (Vietnam)|Southeast]] region
["Bà Rịa–Vũng Tàu, Việt Nam"] = {}, -- capital [[Bà Rịa]]
["Bình Dương, Việt Nam"] = {}, -- capital [[Thủ Dầu Một]]
["Bình Phước, Việt Nam"] = {}, -- capital [[Đồng Xoài]]
["Đồng Nai, Việt Nam"] = {}, -- capital [[Biên Hoà]]
["Tây Ninh, Việt Nam"] = {}, -- capital [[Tây Ninh]]
-- ["Thành phố Hồ Chí Minh"] = {placetype = {"municipality", "thành phố"}}, -- capital [[District 1, Thành phố Hồ Chí Minh|'''District 1''']]
-- [[Mekong Delta]] region
["An Giang, Việt Nam"] = {}, -- capital [[Long Xuyên]]
["Bạc Liêu, Việt Nam"] = {}, -- capital [[Bạc Liêu]]
["Bến Tre, Việt Nam"] = {}, -- capital [[Bến Tre]]
["Cà Mau, Việt Nam"] = {}, -- capital [[Cà Mau]]
["Đồng Tháp, Việt Nam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]]
["Hậu Giang, Việt Nam"] = {}, -- capital [[Vị Thanh]]
["Kiên Giang, Việt Nam"] = {}, -- capital [[Rạch Giá]]
["Long An, Việt Nam"] = {}, -- capital [[Tân An]]
["Sóc Trăng, Việt Nam"] = {}, -- capital [[Sóc Trăng]]
["Tiền Giang, Việt Nam"] = {}, -- capital [[Mỹ Tho]]
["Trà Vinh, Việt Nam"] = {}, -- capital [[Trà Vinh]]
["Vĩnh Long, Việt Nam"] = {}, -- capital [[Vĩnh Long]]
-- ["Can Tho"] = {placetype = {"municipality", "thành phố"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]]
}
-- provinces of Vietnam
export.vietnam_group = {
key_to_placename = make_key_to_placename(", Việt Nam$", "$"),
placename_to_key = make_placename_to_key(", Việt Nam", ""),
default_container = "Việt Nam",
default_placetype = "tỉnh",
-- 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",
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 = "Lãnh thổ Thủ đô Úc, Úc", 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(", Úc", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "thành phố",
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", "region"),
default_placetype = "thành phố",
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 = "Đức",
canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "subdistricts", 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 = "thành phố",
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
["Rome"] = {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(", Italy", "region"),
default_placetype = "thành phố",
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 = {"thành phố", "tỉnh"},
divs = {
{type = "quận đặc biệt", container_parent_type = false},
{type = "thành phố", prep = "của"},
},
},
["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894
["Ōsaka"] = {container = "Ōsaka"}, -- 2,668,586
["Osaka"] = {alias_of = "Ōsaka"},
["Nagoya"] = {container = "Aichi"}, -- 2,283,289
-- FIXME, Hokkaido is handled specially.
["Sapporo"] = {container = "Hokkaidō"}, -- 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 = "Ōsaka"}, -- 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 = "Nhật Bản",
canonicalize_key_container = make_canonicalize_key_container(", Nhật Bản", "prefecture"),
default_placetype = "thành phố",
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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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", "state"),
default_placetype = "thành phố",
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 = "federal territory"}}, -- 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 = "thành phố",
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 = "region"}},
-- 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 = "region"}},
["Davao City"] = {container = "Davao del Sur"},
["Davao"] = {alias_of = "Davao City"},
["Caloocan"] = {container = {key = "Metro Manila, Philippines", placetype = "region"}},
["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 = "thành phố",
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)
["Sankt-Peterburg"] = {}, -- 6,350,000 (Agglomeration)
["Saint Petersburg"] = {alias_of = "Sankt-Peterburg"},
["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 = "Nga",
default_placetype = "thành phố",
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 = "thành phố",
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 = "Hàn Quốc",
canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"),
default_placetype = "thành phố",
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 = "thành phố",
data = export.spain_cities,
}
export.taiwan_cities = {
["Tân Bắc"] = {},
["New Taipei"] = {alias_of = "Tân Bắc", display = true},
["Đài Trung"] = {},
["Cao Hùng"] = {wp = "%l, Đài Loan"},
["Đài Bắc"] = {},
["Đào Viên"] = {},
["Đài Nam"] = {},
-- these last three are not special municipalities
["Gia Nghĩa"] = {placetype = "thành phố"},
["Tân Trúc"] = {placetype = "thành phố"},
["Cơ Long"] = {placetype = "thành phố"},
}
export.taiwan_cities_group = {
placename_to_key = false, -- don't add ", Taiwan" to make the key
canonicalize_key_container = make_canonicalize_key_container(", Taiwan", "county"),
default_container = "Đài Loan",
default_placetype = {"special municipality", "municipality", "thành phố"},
default_is_city = true,
default_divs = {"districts"},
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 = "constituent country"}},
["Cardiff"] = {container = {key = "Wales", placetype = "constituent country"}},
["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 = "constituent country"}},
["Newport"] = {container = {key = "Wales", placetype = "constituent country"}, wp = "Newport, Wales"},
}
export.united_kingdom_cities_group = {
canonicalize_key_container = make_canonicalize_key_container(", England", "county"),
default_placetype = "thành phố",
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 = "Hoa Kỳ",
canonicalize_key_container = make_canonicalize_key_container(", USA", "state"),
default_placetype = "thành phố",
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 = "thành phố"},
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.
["Thành phố Hồ Chí Minh"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa)
["Sài Gòn"] = {alias_of = "Thành phố Hồ Chí Minh"},
["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 = "thành phố", 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},
["Huế"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]]
["Hue"] = {alias_of = "Hue", display = true},
}
export.vietnam_cities_group = {
placename_to_key = false, -- don't add ", Vietnam" to make the key
default_container = "Việt Nam",
canonicalize_key_container = make_canonicalize_key_container(" , Việt Nam", "tỉnh"),
-- 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", "thành phố"},
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 = "Central African Republic"}, -- 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)
["Cairo"] = {container = "Ai Cập"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima)
["Alexandria"] = {container = "Ai Cập"}, -- 6,250,000 (Agglomeration)
["Giza"] = {container = "Ai Cập"}, -- 4,458,135 (2023 from citypopulation.de)
["Shubra El Kheima"] = {container = "Ai Cập"}, -- 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 = "Ethiopia"}, -- 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 = "Bờ Biển Ngà"}, -- 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 = "region"}}, -- 4,450,000 (Municipality (urban population))
["Rabat"] = {container = {key = "Rabat-Sale-Kenitra, Morocco", placetype = "region"}}, -- 2,125,000 (Municipality (urban population))
["Tangier"] = {container = {key = "Tangier-Tetouan-Al Hoceima, Morocco", placetype = "region"}}, -- 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 = "region"}, 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 = "region"}}, -- 1,270,000 (Municipality (urban population))
["Marrakesh"] = {container = {key = "Marrakesh-Safi, Morocco", placetype = "region"}}, -- 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 = "Republic of the Congo"}, -- 2,475,000 (Agglomeration)
["Pointe-Noire"] = {container = "Republic of the 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 = "Campuchia"}, -- 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 "châu Á" and list Israel and Palestine as additional parents for
-- categorization purposes.
["Jerusalem"] = {container = {key = "châu Á", placetype = "continent"},
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 = "Penang, Malaysia", placetype = "state"}, wp = "%l, %c"}, -- 2,075,000 (Agglomeration)
["George Town"] = {alias_of = "George Town, Malaysia"},
["Ulaanbaatar"] = {container = "Mông Cổ"}, -- 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 = "Cộng hòa Dân chủ Nhân dân Triều Tiên"}, -- 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 = "Thái Lan"}, -- 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 = {"thành phố", "province"}, divs = {"districts"}, container = "Thổ Nhĩ Kỳ"}, -- 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 = "Áo"}, -- 2,375,000 (Agglomeration)
["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated)
["Brussels"] = {container = "Bỉ"}, -- 2,800,000 (Consolidated Urban Area)
["Antwerp"] = {container = "Bỉ"}, -- 1,270,000 (Consolidated Urban Area)
["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration)
["Zagreb"] = {container = "Croatia"},
["Prague"] = {container = "Czech Republic"}, -- 1,470,000 (Agglomeration)
["Brno"] = {container = "Czech Republic"}, -- 729,405 (metro area per Wikipedia as of 2024-01-01 Czech Statistical Office)
["Olomouc"] = {container = "Czech Republic"}, -- 102,293 (city; included only because someone went crazy creating Olomouc-related terms)
["Copenhagen"] = {container = "Đan Mạch"}, -- 1,800,000 (Consolidated Urban Area)
["Helsinki"] = {container = {key = "Uusimaa, Finland", placetype = "region"}}, -- 1,560,000 (Consolidated Urban Area)
["Tbilisi"] = {container = "Georgia"}, -- 1,430,000 (Agglomeration)
["Athens"] = {container = "Hy Lạp"},
["Thessaloniki"] = {container = "Hy Lạp"},
["Budapest"] = {container = "Hungary"},
-- FIXME, per Wikipedia "County Dublin" is now the "Dublin Region"
["Dublin"] = {container = {key = "County Dublin, Ireland", placetype = "county"}},
["Riga"] = {container = "Latvia"},
["Amsterdam"] = {container = {key = "North Holland, Netherlands", placetype = "province"}},
["Rotterdam"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
["The Hague"] = {container = {key = "South Holland, Netherlands", placetype = "province"}},
-- Christchurch (metro 546,600) and Wellington (metro 439,800) are too small to make it.
["Auckland"] = {container = {key = "Auckland, New Zealand", placetype = "region"}},
["Oslo"] = {container = {key = "Oslo, Norway", placetype = "county"}},
["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 = "district"}},
["Porto"] = {container = {key = "Porto District, Portugal", placetype = "district"}},
["Oporto"] = {alias_of = "Porto", display = true},
["Bucharest"] = {container = "Romania"},
["Belgrade"] = {container = "Serbia"},
["Stockholm"] = {container = "Thụy Điển"},
["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 = "Ukraina"}, -- 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, "quốc gia"),
default_placetype = "thành phố",
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.bulgaria_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
hlyfl0uuwrmrgyne7mm5ruwr1sxfe6l
чегет
0
282461
2573157
2102957
2026-10-24T08:00:19Z
Hiyuune
50834
2573157
wikitext
text/x-wiki
=={{langname|krc}}==
==={{section|noun}}===
{{head|krc|Danh từ}}
# [[rừng|Rừng]].
qdszh5kxcl1wvtadc1dcuvb0137y42s
diş
0
289727
2573138
2156770
2026-10-24T04:53:23Z
WhoAlone
40420
2573138
wikitext
text/x-wiki
=={{langname|gag}}==
==={{ĐM|noun}}===
{{head|gag|Danh từ}}
# [[răng]].
=={{langname|qxq}}==
==={{ĐM|noun}}===
{{head|qxq|Danh từ}}
# [[răng]].
lhxvh4goqbi3mla723h2xsktvr68hc0
2573139
2573138
2026-10-24T04:53:35Z
WhoAlone
40420
2573139
wikitext
text/x-wiki
=={{langname|gag}}==
==={{ĐM|noun}}===
{{head|gag|Danh từ}}
# [[răng]].
{{c|gag|Răng}}
=={{langname|qxq}}==
==={{ĐM|noun}}===
{{head|qxq|Danh từ}}
# [[răng]].
{{c|qxq|Răng}}
9wjf2d3cimhwpvv8faujcr0g4sn2ruf
hơnĕng
0
310955
2573078
2212684
2026-10-24T04:12:19Z
WhoAlone
40420
2573078
wikitext
text/x-wiki
{{-ren-}}
{{-noun-}}
{{head|ren|Danh từ}}
# [[răng]].
=={{langname|tdr}}==
==={{ĐM|noun}}===
{{head|tdr|Danh từ}}
# {{label|tdr|Didrá}} [[răng]].
==={{ĐM|ref}}===
* Gregerson, Kenneth J. và Smith, Kenneth D. (1973). ''The development of Todrah register''. SIL International.
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng]].
#:{{ux|sed|huăn '''hơněng'''|Mọc '''răng'''}}
==={{section|ref}}===
* {{R:VOV}}
2bcbwpykeec6e022brltynpfde1dtwn
2573079
2573078
2026-10-24T04:12:46Z
WhoAlone
40420
2573079
wikitext
text/x-wiki
{{-ren-}}
{{-noun-}}
{{head|ren|Danh từ}}
# [[răng]].
{{c|ren|Răng}}
=={{langname|tdr}}==
==={{ĐM|noun}}===
{{head|tdr|Danh từ}}
# {{label|tdr|Didrá}} [[răng]].
==={{ĐM|ref}}===
* Gregerson, Kenneth J. và Smith, Kenneth D. (1973). ''The development of Todrah register''. SIL International.
{{c|tdr|Răng}}
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng]].
#:{{ux|sed|huăn '''hơněng'''|Mọc '''răng'''}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
577zpgfkx8gdu029wfybmjc90km556r
kapo
0
326409
2573000
2216701
2026-10-23T11:59:13Z
WhoAlone
40420
2573000
wikitext
text/x-wiki
=={{langname|ncb}}==
==={{ĐM|pron}}===
* {{IPA4|ncb|/kapo/}}
==={{ĐM|noun}}===
{{head|ncb|Danh từ}}
# {{label|ncb|Nancowry}} [[gia súc]].
==={{ĐM|ref}}===
* [http://www.sealang.net/monkhmer/database/retrieve.pl?language=Nancowry&sort=gloss&format=html Tiếng Nicobar Trung (Nancowry)] tại Cơ sở Dữ liệu Môn-Khmer.
{{c|ncb|Gia súc}}
=={{langname|sea}}==
==={{ĐM|pron}}===
* {{IPA4|sea|/kapõ/}}
==={{ĐM|noun}}===
{{head|sea|Danh từ}}
# [[má]].
#:{{synonym|sea|kaming|kameng}}
{{-ref-}}
* [https://web.archive.org/web/20220922224210/http://sealang.net/monkhmer/database/retrieve.pl?language=Semai&sort=gloss&format=html Tiếng Semai] tại Cơ sở Dữ liệu Môn-Khmer.
jk98p2k17bmndrfozohp7f8qayd8qvc
kapâ
0
332084
2573001
2216719
2026-10-23T11:59:27Z
WhoAlone
40420
2573001
wikitext
text/x-wiki
=={{langname|ncb}}==
==={{ĐM|pron}}===
* {{IPA4|ncb|/kapa/}}
==={{ĐM|noun}}===
{{head|ncb|Danh từ}}
# {{label|ncb|Nancowry}} {{alternative spelling of|ncb|kabâ}}
==={{ĐM|ref}}===
* [http://www.sealang.net/monkhmer/database/retrieve.pl?language=Nancowry&sort=gloss&format=html Tiếng Nicobar Trung (Nancowry)] tại Cơ sở Dữ liệu Môn-Khmer.
{{c|ncb|Hiện tượng khí quyển}}
06tec9et5j7ibbiabjmoo7md45lg97c
in-cheūölö
0
332308
2573045
2217091
2026-10-23T15:52:38Z
WhoAlone
40420
2573045
wikitext
text/x-wiki
=={{langname|ncb}}==
==={{ĐM|pron}}===
* {{IPA4|ncb|/ʔincɯːəlɛ/}}
==={{ĐM|noun}}===
{{head|ncb|Danh từ}}
# {{label|ncb|Nancowry}} [[thùng]] để đựng đồ lấy từ ngọn cây.
==={{ĐM|ref}}===
* V.R. Rajasingh. (2019) ''[https://drive.google.com/open?id=1sJ_kFSvTHaxp24iH3Sx90jPm83fBXV8l Nicobarese-Hindi-English Dictionary (Pū-Sanënyö-Luröö-Mūöt-Lamôngsĕ-Tökahāṅilāhngö-Hindi-English)]''
{{c|ncb|Dụng cụ}}
7gngvrmtlx6i4ccoavrp6y72bhw2h0v
human right
0
343551
2573073
2569360
2026-10-24T01:39:56Z
Hiyuune
50834
2573073
wikitext
text/x-wiki
=={{langname|en}}==
==={{ĐM|pron}}===
* {{audio|en|LL-Q1860 (eng)-Vealhurl-human right.wav|a=Southern England}}
==={{ĐM|n}}===
{{en-noun}}
# [[nhân quyền|Nhân quyền]].
#: {{ux|en|'''Human rights''' in Vietnam.|Nhân quyền tại Việt Nam.}}
===={{ĐM|rel}}====
{{col3|en
|absolute right
|animal rights
|civil right
|fundamental right
|human rights
|natural right
|neuroright
}}
==={{ĐM|further}}===
* {{pedia|Human rights|lang=en}}
{{C|en|Luật pháp}}
2cl25fqru5wmx4pf87dm5ai3xke8x5d
kobieta
0
406213
2573190
2572865
2026-10-24T09:13:10Z
Hiyuune
50834
/* Tiếng Ba Lan */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2573190
wikitext
text/x-wiki
{{also|kobieta|kobietą|kobiéta|kòbiéta|kòbiétą|kòbiétã|kóbieta}}
=={{langname|pl}}==
{{wp|pl:}}
{{img
|image1=Woman Montage (1).jpg|caption1={{lang|pl|kobiety}}
}}
==={{section|etym}}===
{{etymon|pl|id=phụ nữ}}
{{rfe|pl}}
==={{section|pron}}===
{{pl-pr|a=Pl-#.ogg;LL-Q809 (pol)-Gower-#.wav|mp=[ét]|CGP=#|pdl=#|MB=#|WL=#|low=#|kra=#|mas=#}}
==={{section|n}}===
{{pl-noun|f|dim=kobietka|aug=kobiecisko|adj=kobiecy,kobiecki<l:obsolete>}}
# [[phụ nữ|Phụ nữ]].
#: {{syn|pl|białogłowa|dama|facetka<q:thông tục>|niewiasta|kobiałka<q:hài hước>|żona<q:không còn dùng>}}
#: {{cot|pl|mężczyzna}}
# {{lb|pl|colloquial|or|dialectal|Krajna|Wielkopolska |Masuria|Jabłonka|Bogacko|Podlachia|Tykocin|Gwary Mazowsza|Czersk|Łowicz|Lubelszczyzny Zachodniej|Chmielnik|Rzeczyca Księża}} [[phụ nữ|Phụ nữ]] ([[vợ]] hoặc [[người yêu]]).
===={{section|decl}}====
{{pl-ndecl|kobieta<f>}}
Tiếng Ba Lan trung đại:
{{pl-mid-decl-noun
|noms=kobieta
|gens=kobiety/kobietę
|dats=kobiecie
|accs=-
|inss=-
|locs=-
|vocs=-
|nomp=kobiety
|genp=-
|datp=-
|accp=kobiety
|insp=kobietami
|locp=kobietach
|vocp=-
}}
===={{section|syn}}====
{{dial syn|pl}}
===={{section|drv}}====
{{col|pl|title=danh từ|kobieta fatalna|kobieta luksusowa|kobieta publiczna|kobieta sukcesu|kobieta z przeszłością|kobieciarz|kobieciątko|kobiecina|kobieton}}
{{pl-derived verbs|-/być kobietą}}
===={{section|rel}}====
{{col|pl|title=phó từ|kobieco}}
{{col|pl|title=danh từ|kobieciarstwo|kobiecinka|kobiecość}}
===={{section|desc}}====
* {{desc|be|кабе́та|bor=1}}
* {{desc|csb|kòbiéta|bor=1}}
* {{desc|szl|kobiyta|bor=1}}
* {{desc|zlw-slv|kôbjéta|bor=1}}
* {{desc|uk|кобі́та|bor=1}}
==={{section|further}}===
* Tiếng Ba Lan hiện tại tiêu chuẩn:
** {{R:pl:WSJP||3950}}
** {{R:pl:PWN}}
** {{R:pl:PSWP}}
** {{R:pl:SGJP|+|8306}}
** {{R:pl:USJP}}
** {{R:pl:NFJP}}
** {{R:pl:SPP||135}}
* Tiếng Ba Lan trung đại:
** {{R:pl:SXVII|KOBIETA|19831||13.03.2023}}
* Từ điển lịch sử:
** {{R:pl:SJP1807}}
** {{R:pl:SJP1861}}
** {{R:pl:SJP1900||383|2}}
* Từ điển phương ngữ:
** {{R:pl:SGP1900||387|2}}
** {{R:pl:Świderska:1929|kob́eta|106}}
** {{R:pl:Kęcińska:2004||45}}
** {{R:pl:SgOWiM|kobieta|233|3}}
5oejt0ca2zdl781dwf5tiihl1tc3uw6
akata
0
417482
2573031
2565466
2026-10-23T15:43:05Z
TheHighFighter2
42988
/* Tiếng Akan */
2573031
wikitext
text/x-wiki
=={{langname|ak}}==
==={{ĐM|noun}}===
{{ak-head|noun}}
# [[người nước ngoài|Người nước ngoài]], thường là người [[da]] [[đen]].
8hbwd7fxj881likj39fif1kazpusr07
2573046
2573031
2026-10-23T15:52:59Z
Hiyuune
50834
/* Tiếng Akan */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2573046
wikitext
text/x-wiki
=={{langname|ak}}==
==={{ĐM|noun}}===
{{ak-head|noun}}
# [[người nước ngoài|Người nước ngoài]], thường là người [[da]] [[đen]].
=={{langname|srm}}==
==={{ĐM|n}}===
{{head|srm|Danh từ}}
# {{alternative spelling of|srm|àkàtà}}
# {{alternative spelling of|srm|akáta}}
8jpk23ag2pul5wys93j1c8xcl9oj3dh
Bản mẫu:ak-head
10
417483
2573027
2565467
2026-10-23T15:40:50Z
TheHighFighter2
42988
TheHighFighter2 đã đổi [[Bản mẫu:ak-noun]] thành [[Bản mẫu:ak-head]] (đã tắt đổi hướng)
2565467
wikitext
text/x-wiki
{{head|ak|Danh từ|head={{{head|}}}|{{#if:{{{pl|}}}|số nhiều}}|{{{pl|}}}|{{#if:{{{pl|}}}|{{#if:{{{pl2|}}}|hoặc}}}}|{{{pl2|}}}}}<!--
--><noinclude>{{documentation}}</noinclude>
fonyctivw73kvxhbz7x6qsr37ird1f4
2573029
2573027
2026-10-23T15:42:18Z
TheHighFighter2
42988
/* */
2573029
wikitext
text/x-wiki
{{#invoke:ak-headword|show}}<!--
--><noinclude>{{documentation}}</noinclude>
njx3b8bvoxhf3z7yozv12bqbpqbjrhq
いちやう
0
419125
2573162
2568403
2026-10-24T08:07:09Z
Hiyuune
50834
/* Tiếng Nhật */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2573162
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|公孫樹}}
{{cln|ja|Mục từ|Danh từ}}
q4reu7bgzxu9w754tpnqa0nw9imd6wv
Mô đun:zlw-lch-decl
828
421108
2573186
2572862
2026-10-24T09:04:00Z
Hiyuune
50834
2573186
Scribunto
text/plain
--[==[ intro:
This module implements the declension tables of the Lechitic languages: {{tl|pl-ndecl}} for Polish nouns and
{{tl|pl-adecl}} for Polish adjectives (both with their Middle Polish, Standard Kurpie and dialectal tables), and
{{tl|zlw-opl-ndecl}} for Old Polish nouns.
The following terminology is helpful to understand:
* The '''lemma''' is the word being declined, normally the nominative singular, or the nominative plural of a plurale
tantum. In a call it's followed by an inline spec of indicators in angle brackets, e.g.
`{{pl-ndecl|<m.anml.*.datu>}}` (the page name as an animal noun with a mobile ''e'' and the dative in ''-u'') or
`{{pl-ndecl|Morze<n.sg> Bałtyckie<+>}}`.
* A '''slot''' is a particular combination of case and number, e.g. `nom_s` or `loc_p`. Each slot is one cell of a
table.
* The '''stem''' is the lemma minus its nominative ending. A '''group''' is the set of nouns that share one set of
rules; a '''rule''' gives the forms of a slot for the stems that end in particular letters; and a '''copy''' is a
slot that takes its forms from another one. See [[Module:zlw-lch-decl/data/pl]] for the details.
* An '''alternation''' is a change to the stem that a rule asks for: dropping or inserting the mobile ''e'', ''ó''/''o''
and ''ą''/''ę'', and the palatalizations.
* A '''base''' is what [[Module:inflection utilities]] calls the parsed spec of a single word: its lemma, indicators and
overrides, plus its forms once it has been declined.
Authorship: [[User:Fenakhay]]
]==]
local export = {}
local M = require("Module:module loader").init {
require = {
inflection_table = "Module:inflection-table",
inflection_utilities = "Module:inflection utilities",
JSON = "Module:JSON",
labels = "Module:labels",
languages = "Module:languages",
links = "Module:links",
parameters = "Module:parameters",
parse_utilities = "Module:parse utilities",
utilities = "Module:utilities",
},
loadData = {
data = "Module:zlw-lch-decl/data",
headword_data = "Module:headword/data",
},
}
-- Return the data module of the language `code` (`Module:zlw-lch-decl/data/CODE`) and its language object. `entry` is
-- the entry point being invoked (`noun` or `adjective`); throw an error if `languages` in [[Module:zlw-lch-decl/data]]
-- doesn't list that entry for the language.
local function language_of(code, entry)
local language = code and M.data.languages[code]
if not language or not language[entry] then
local codes = {}
for known, entries in pairs(M.data.languages) do
if entries[entry] then
table.insert(codes, known)
end
end
table.sort(codes)
error(("The #invoke needs lang= with one of %s"):format(table.concat(codes, ", ")), 0)
end
return mw.loadData("Module:zlw-lch-decl/data/" .. code), M.languages.getByCode(code)
end
------------------------------------------------------------------------------------------------------------------------
-- Spec --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the indicators of a single word, i.e. the `<...>` after its lemma, e.g. `<m.anml.*.datu>`. `Spec.parse`
is the `parse_indicator_spec` callback passed to [[Module:inflection utilities]]; it returns the base of the word, with
its indicators by group and its overrides by slot. The indicators each template knows are listed under `indicators` in
the language's data module, and an unknown one is an error that lists the known ones.
]==]
local Spec = {}
Spec.__index = Spec
local function spec_error(message, text)
error(message .. " in the spec '" .. text .. "'.", 0)
end
-- Return the footnotes in a group that `split_alternating_runs` produced from a bracketed run, i.e. the bracketed
-- segments after the first segment. Throw an error if any text follows a footnote.
local function fetch_footnotes(group, text)
local footnotes
for i = 2, #group - 1, 2 do
if group[i + 1] ~= "" then
spec_error("Only another footnote can follow a footnote", text)
end
footnotes = footnotes or {}
table.insert(footnotes, group[i])
end
return footnotes
end
--[==[
Parse an override of one or more slots of a noun. There are two kinds of overrides:
* Endings, written `CASE[pl]ENDING:ENDING...`, e.g. `genu` or `insplami:mi`. These go on the stem that the slot's rule
uses; an ending that starts with an apostrophe goes after the whole lemma (`gen'a` on ''Google'' gives ''Google'a'').
* Whole forms, written `CASE[pl]:FORM:FORM...`, e.g. `voc:człowiecze:człowieku`.
`CASE+CASE...` sets several cases at once, and `du` in place of `pl` names a dual slot (`nomdu`). Among endings, `+`
stands for the forms the rules give, so that e.g. `nomplowie:+` adds ''-owie'' to them. `-` stands for no ending (among
endings) or no form (among forms), and a footnote can follow any value. `depr` is the deprecative nominative plural of
a masculine personal noun. Return two values: the slots the override applies to, and an object describing it.
]==]
local Overrides = {}
function Overrides.parse(group, text)
local part = group[1]
local slots = {}
while true do
if mw.ustring.sub(part, 1, 4) == "depr" then
table.insert(slots, "depr_p")
part = mw.ustring.sub(part, 5)
else
local case = mw.ustring.sub(part, 1, 3)
if not M.data.case_codes[case] then
spec_error(("Unrecognized case '%s' in an override"):format(case), text)
end
part = mw.ustring.sub(part, 4)
if mw.ustring.find(part, "^pl") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_p")
elseif mw.ustring.find(part, "^du") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_d")
else
table.insert(slots, case .. "_s")
end
end
if mw.ustring.find(part, "^%+[a-z]") then
part = mw.ustring.sub(part, 2)
else
break
end
end
local override = {values = {}}
if mw.ustring.find(part, "^:") then
override.full = true
part = mw.ustring.sub(part, 2)
end
group[1] = part
for _, value_group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")) do
local value = value_group[1]
if value == "" then
spec_error("Use - for an empty ending or no form", text)
end
table.insert(override.values, {
form = value == "-" and "" or value,
default = not override.full and value == "+" or nil,
footnotes = fetch_footnotes(value_group, text),
})
end
return slots, override
end
-- The slots of an adjective table, which an override of {{tl|pl-adecl}} can name, with their accelerator tags (using the
-- codes in [[Module:form of/data]], `nv` = non-virile).
local ADJECTIVE_ACCEL = {
nom_m = "nom|m|s", nom_f = "nom|f|s", nom_n = "nom|n|s", nom_mp_pers = "vr|nom|p", nom_p_not_mp_pers = "nv|nom|p",
nom_mp_npers = "nv|nom|m|p", nom_fp = "nom|f|p", nom_np = "nom|n|p",
gen_mn = "gen|m//n|s", gen_f = "gen|f|s", gen_p = "gen|p",
dat_mn = "dat|m//n|s", dat_f = "dat|f|s", dat_p = "dat|p",
acc_m_an = "an|acc|m|s", acc_m_in = "in|acc|m|s", acc_f = "acc|f|s", acc_n = "acc|n|s",
acc_mp_pers = "vr|acc|p", acc_p_not_mp_pers = "nv|acc|p", acc_mp_npers = "nv|acc|m|p", acc_fp = "acc|f|p",
acc_np = "acc|n|p",
ins_mn = "ins|m//n|s", ins_f = "ins|f|s", ins_p = "ins|p", ins_mnp = "ins|m//n|p", ins_fp = "ins|f|p",
loc_mn = "loc|m//n|s", loc_f = "loc|f|s", loc_p = "loc|p",
nom_m_d = "nom|m|d", nom_fn_d = "nom|f//n|d", gen_d = "gen|d", dat_d = "dat|d", acc_m_d = "acc|m|d",
acc_fn_d = "acc|f//n|d", ins_d = "ins|d", loc_d = "loc|d",
short = "short",
}
--[==[
Parse an override of {{tl|pl-adecl}}, in the format of the former [[Module:pl-adjective]]: `SLOT[+SLOT...]:FORM:FORM...`
with the slot names of the adjective, e.g. `nom_mp_pers:weseli` or `gen_p+loc_p:...`. Only whole forms are allowed.
Return the same two values as `Overrides.parse`.
]==]
function Overrides.parseAdjective(group, text)
local slots = {}
local value_groups = M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")
if #value_groups[1] > 1 then
spec_error("A footnote can't follow the slot name of an override", text)
end
for slot in mw.text.gsplit(value_groups[1][1], "+", true) do
if not ADJECTIVE_ACCEL[slot] then
spec_error(("Unrecognized slot '%s' in an override"):format(slot), text)
end
table.insert(slots, slot)
end
local override = {values = {}, full = true}
for i = 2, #value_groups do
local value = value_groups[i][1]
if value == "" then
spec_error("Use - for no form", text)
end
table.insert(override.values, {form = value == "-" and "" or value, footnotes = fetch_footnotes(value_groups[i], text)})
end
return slots, override
end
-- Return the definition of the indicator `name` for `template`, or nil if there isn't one.
local function indicator_definition(data, template, name)
return data.indicators[template][name]
end
-- Return true if `part` of a spec is an override, i.e. it begins with a case code (or `depr`) and isn't an indicator.
local function is_override(data, template, part)
local name = mw.ustring.match(part, "^([^:]*)") or part
if indicator_definition(data, template, name) then
return false
end
return M.data.case_codes[mw.ustring.sub(part, 1, 3)] ~= nil or mw.ustring.sub(part, 1, 4) == "depr"
end
-- Return true if `part` (`NAME:VALUE`) is an indicator that takes a value (e.g. `decllemma:dń` or `lect:skur`) rather
-- than an override.
local function takes_value(data, template, part)
local definition = indicator_definition(data, template, mw.ustring.match(part, "^([^:]+):"))
return definition and definition.value ~= nil
end
function Spec.parse(angle_bracket_spec, template, data, lang)
local inside = mw.ustring.match(angle_bracket_spec, "^<(.*)>$")
local base = setmetatable({overrides = {}, indicators = {}, groups = {}, template = template, data = data,
lang = lang, text = angle_bracket_spec}, Spec)
if inside == "" then
return base
end
local segments = M.parse_utilities.parse_balanced_segment_run(inside, "[", "]")
for _, group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(segments, "%.")) do
local part = group[1]
if part == "" then
if #group == 1 then
spec_error("Empty indicator (two periods in a row, or a period at an end)", angle_bracket_spec)
end
base.footnotes = fetch_footnotes(group, angle_bracket_spec)
elseif template == "adjective" and mw.ustring.find(part, ":") and not takes_value(data, template, part)
or template ~= "adjective" and is_override(data, template, part) then
local slots, override
if template == "adjective" then
slots, override = Overrides.parseAdjective(group, angle_bracket_spec)
else
slots, override = Overrides.parse(group, angle_bracket_spec)
end
for _, slot in ipairs(slots) do
if base.overrides[slot] then
spec_error(("Two overrides for the slot '%s'"):format(slot), angle_bracket_spec)
end
base.overrides[slot] = override
end
else
if #group > 1 then
spec_error("A footnote can only follow an override or stand alone", angle_bracket_spec)
end
local name, value = mw.ustring.match(part, "^([^:]+):(.*)$")
name = name or part
local definition = indicator_definition(data, template, name)
if not definition then
local names = {}
for known in pairs(data.indicators[template]) do
table.insert(names, known)
end
table.sort(names)
spec_error(("Unrecognized indicator '%s'; the indicators are %s"):format(name, table.concat(names, ", ")),
angle_bracket_spec)
end
if definition.value and (value == nil or value == "") then
spec_error(("The indicator '%s' needs a value ('%s:...')"):format(name, name), angle_bracket_spec)
elseif not definition.value and value ~= nil then
spec_error(("The indicator '%s' takes no value"):format(name), angle_bracket_spec)
end
if base.indicators[name] ~= nil then
spec_error(("The indicator '%s' is given twice"):format(name), angle_bracket_spec)
end
local key = definition.group or name
if base.groups[key] then
spec_error(("The indicators '%s' and '%s' can't be used together"):format(base.groups[key], name),
angle_bracket_spec)
end
base.groups[key] = name
base.indicators[name] = value or true
end
end
return base
end
-- Return the value set by a group of indicators (e.g. "m" for `gender`), or nil if none of the group was given.
function Spec:group(group)
local name = self.groups[group]
if not name then
return nil
end
return indicator_definition(self.data, self.template, name).sets or name
end
------------------------------------------------------------------------------------------------------------------------
-- Stem --
------------------------------------------------------------------------------------------------------------------------
--[==[
Functions to find the stem of a lemma and apply the alternations of the language's data module to it.
]==]
local Stem = {}
-- Split a lemma into its stem and nominative ending. The ending is the first of the `nominative_endings` of its gender
-- (`m`, `f` or `n`, or `plural` for a plurale tantum) that the lemma ends in with something before it, unless the
-- ending is one of the gender's `nominative_after_consonant` and a vowel precedes it; if there's none, the lemma is its
-- own stem and the ending is empty.
function Stem.split(data, lemma, gender, plural)
local after_consonant = not plural and data.nominative_after_consonant[gender] or {}
for _, ending in ipairs(data.nominative_endings[plural and "plural" or gender]) do
local stem = mw.ustring.match(lemma, "^(.+)" .. ending .. "$")
if stem and not (after_consonant[ending] and mw.ustring.find(mw.ustring.sub(stem, -1), "[" .. data.vowels .. "]")) then
return stem, ending
end
end
return lemma, ""
end
-- Replace the last letters of `stem` according to `map`, trying the longest keys first (up to three letters). Return
-- nil if the stem ends in none of the keys.
local function replace_final(stem, map)
for _, length in ipairs({3, 2, 1}) do
if mw.ustring.len(stem) >= length then
local final = mw.ustring.sub(stem, -length)
if map[final] then
return mw.ustring.sub(stem, 1, -length - 1) .. map[final]
end
end
end
return nil
end
-- Remove the mobile vowel from `stem`, i.e. the first of the data's `mobile_vowels` that it has before its final
-- consonants. Return nil if it has none.
local function reduce(data, stem)
local vowels = data.vowels
for _, mobile in ipairs(data.mobile_vowels) do
local head, final = mw.ustring.match(stem, "^(.-)" .. mobile[1] .. "([^" .. vowels .. "]+)$")
if head and head ~= "" and not (mobile.after_consonant
and mw.ustring.find(mw.ustring.sub(head, -1), "[" .. vowels .. "]")) then
return (mobile.soften and replace_final(head, data[mobile.soften]) or head) .. final
end
end
return nil
end
-- Insert `vowel` before the last consonant of `stem`. Return nil if the stem doesn't end in two consonants.
local function insert(data, stem, vowel)
local vowels = data.vowels
local head, final = mw.ustring.match(stem, "^(.-[^" .. vowels .. "])([^" .. vowels .. "])$")
return head and head .. vowel .. final or nil
end
-- Change the vowel of the last syllable of `stem`, whose vowels are the letters of `vowels`, according to `map`
-- (`shorten`, `lengthen` or `front` in the data, or `clear` of a lect's paradigm). Return nil if that vowel isn't one
-- of the keys of `map`.
local function alternate(vowels, stem, map)
local letters = ""
for vowel in pairs(map) do
letters = letters .. vowel
end
local head, vowel, tail = mw.ustring.match(stem, "^(.*)([" .. letters .. "])([^" .. vowels .. "]*)$")
return head and head .. map[vowel] .. tail or nil
end
-- Return the stem that `label` names, which is either `plain` or a set of alternations joined with "+" (e.g.
-- `reduced+palatal`). Return nil if one of the alternations doesn't apply to `stem`.
function Stem.apply(data, stem, label)
local text = stem
for part in mw.text.gsplit(label, "+", true) do
if not text then
return nil
end
if part == "reduced" then
text = reduce(data, text)
elseif mw.ustring.find(part, "^inserted_") then
-- `inserted_VOWEL` puts the mobile vowel VOWEL in.
text = insert(data, text, mw.ustring.sub(part, 10))
elseif part == "truncated" then
text = replace_final(text, data.truncate)
elseif part == "spelled" then
text = replace_final(text, data.spelled)
elseif part == "shortened" then
text = alternate(data.vowels, text, data.shorten)
elseif part == "lengthened" then
text = alternate(data.vowels, text, data.lengthen)
elseif part == "fronted" then
text = alternate(data.vowels, text, data.front)
elseif part == "soft" or part == "final_soft" then
-- This is only a spelling, so leave the stem alone if it has no such letter.
text = replace_final(text, data[part]) or text
elseif part == "palatal" or part == "virile" then
text = replace_final(text, data[part])
elseif part == "irregular" then
text = ""
elseif part ~= "plain" then
error(("Internal error: unknown alternation '%s'"):format(part))
end
end
return text
end
------------------------------------------------------------------------------------------------------------------------
-- Noun rules --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the rules of one word's group, with the word's indicators applied. `NounRules.new(base)` finds the group
from the word's gender, kind, number and nominative ending, and `:forms(slot)` returns the forms of a slot by the rule
of the longest matching stem ending, as form objects `{form = ..., footnotes = {...}}`.
]==]
local NounRules = {}
NounRules.__index = NounRules
local function group_key(rule_gender, kind, plural, nominative)
return ("%s %s %s %s"):format(rule_gender, kind, plural and "pl" or "sg", nominative)
end
function NounRules.new(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy]
end
local plural = base.number == "pl"
-- A plurale tantum is either masculine personal (m-pr) or not, and the non-personal ones share the groups of the
-- neuter.
if plural and rule_gender ~= "m-pr" then
rule_gender = "n"
end
if not rule_gender then
spec_error(("The noun '%s' needs a gender (m, f or n)"):format(word), base.text)
end
local stem, nominative = Stem.split(data, word, rule_gender:sub(1, 1), plural)
local kind = base.kind or "common"
local group = data.noun_groups[group_key(rule_gender, kind, plural, nominative)]
or kind ~= "common" and data.noun_groups[group_key(rule_gender, "common", plural, nominative)]
if not group then
error(("No rules for %s nouns in -%s ('%s'); give the forms with overrides and <!>"):format(
rule_gender, nominative, word), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
used = {}, head_slot = plural and "nom_p" or "nom_s"}, NounRules)
end
-- Return the rule of `slot` for this stem, i.e. the rule of the longest stem ending (up to three letters) that has one.
function NounRules:rule(slot)
local rules = self.group.rules
for size = math.min(3, mw.ustring.len(self.stem)), 0, -1 do
local suffix = size == 0 and "" or mw.ustring.sub(self.stem, -size)
local by_slot = rules[suffix]
if by_slot and by_slot[slot] then
return by_slot[slot]
end
end
return nil
end
-- Return true if a part of an alternation label is about the mobile vowel, i.e. it's `reduced` or `inserted_VOWEL`.
local function is_mobile(part)
return part == "reduced" or mw.ustring.find(part, "^inserted_") ~= nil
end
-- Return the alternation label of an ending of a rule, with the word's indicators applied. `-*` takes out the mobile
-- vowel and `*` puts it in: for a lemma ending in a consonant it's dropped before an ending, and for one ending in a
-- vowel it's inserted into a bare stem (as `inserted_vowel` in the data says). `-#` and `#` do the same for ''ó''/''o''
-- and ''ą''/''ę''. A bare form of a lemma ending in a consonant is the lemma itself (e.g. the accusative of an
-- inanimate noun) and takes neither.
function NounRules:label(label, ending)
local base = self.base
local parts = {}
for part in mw.text.gsplit(label, "+", true) do
parts[part] = true
end
local mobile = false
for part in pairs(parts) do
mobile = mobile or is_mobile(part)
end
local consonant_final = self.nominative == ""
if base.reducible == false then
for part in pairs(parts) do
if is_mobile(part) then
parts[part] = nil
end
end
elseif base.reducible and not mobile then
if consonant_final and ending ~= "" then
parts.reduced = true
elseif ending == "" then
local inserted = self.data.inserted_vowel
parts["inserted_" .. (inserted.after[mw.ustring.sub(self.stem, -2, -2)] or inserted.default)] = true
end
end
if base.quantity == "none" then
parts.shortened, parts.lengthened = nil, nil
elseif base.quantity == "full" and not (parts.shortened or parts.lengthened) then
if consonant_final and ending ~= "" then
parts.shortened = true
elseif ending == "" then
parts.lengthened = true
end
end
-- Put the parts in the order they apply in, with the mobile vowel first.
local ordered = {}
if parts.reduced then
table.insert(ordered, "reduced")
end
local inserted = {}
for part in pairs(parts) do
if mw.ustring.find(part, "^inserted_") then
table.insert(inserted, part)
end
end
table.sort(inserted)
for _, part in ipairs(inserted) do
table.insert(ordered, part)
end
for _, name in ipairs({"truncated", "spelled", "shortened", "lengthened", "fronted", "soft", "final_soft", "palatal",
"virile", "irregular"}) do
if parts[name] then
table.insert(ordered, name)
end
end
return ordered[1] and table.concat(ordered, "+") or "plain"
end
-- Join a stem and an ending as the language spells them. A final soft consonant before a vowel is written with the
-- data's `soft_vowel`, which merges with the same vowel at the start of the ending (e.g. ''koń'' + ''-a'' → ''konia'',
-- ''goleń'' + ''-i'' → ''goleni'').
local function join(data, stem, ending)
if ending ~= "" and mw.ustring.find(mw.ustring.sub(ending, 1, 1), "[" .. data.vowels .. "]") then
local spelled = replace_final(stem, data.soft)
if spelled then
local vowel = data.soft_vowel
local length = mw.ustring.len(vowel)
return spelled .. (mw.ustring.sub(ending, 1, length) == vowel and mw.ustring.sub(ending, length + 1) or ending)
end
end
return stem .. ending
end
function NounRules:form(label, ending, note)
local footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil
-- An apostrophe keeps the lemma whole before the ending (''Google'' → ''Google'a'').
if mw.ustring.sub(ending, 1, 1) == "'" then
return {form = self.word .. ending, footnotes = footnotes}
end
local full = self:label(label, ending)
-- Note the alternations used, for the categories of the table.
for part in mw.text.gsplit(full, "+", true) do
self.used[part] = true
end
local stem = Stem.apply(self.data, self.stem, full) or self.stem
return {form = join(self.data, stem, ending), footnotes = footnotes}
end
-- Return the endings of a rule's cell as a list of `{ending, stem = ..., note = ...}`. A cell is an ending (a string),
-- one ending with a stem or note (e.g. `{ "e", stem = "palatal" }`), or a list of either (e.g. `{ "i", "ów" }`).
local function cell_endings(cell)
if type(cell) == "string" then
return {{cell}}
elseif type(cell[1]) == "string" and cell[2] == nil then
return {cell}
end
local list = {}
for _, ending in ipairs(cell) do
table.insert(list, type(ending) == "string" and {ending} or ending)
end
return list
end
-- Return the forms of `slot` according to its rule, or nil if the group has no rule for the slot.
function NounRules:forms(slot)
local cell = self:rule(slot)
if not cell then
return nil
end
local list = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(list, self:form(ending.stem or "plain", ending[1], ending.note))
end
return list
end
-- Return the alternation label for an ending given in an override of `slot`. If the ending is one of the rule's own
-- endings, use that ending's label; otherwise use the label of the rule's first ending minus the softening that its
-- ending brings (`palatal` before ''-e'', `virile` before the virile ''-i''/''-y''). This way ''dom'' with the locative
-- ''-u'' gives ''domu'', and ''Polak'' with the nominative plural ''-owie'' gives ''Polakowie''.
function NounRules:overrideLabel(slot, ending)
local cell = self:rule(slot)
local endings = cell and cell_endings(cell) or {}
for _, item in ipairs(endings) do
if item[1] == ending then
return item.stem or "plain"
end
end
local kept = {}
for part in mw.text.gsplit(endings[1] and endings[1].stem or "plain", "+", true) do
if part ~= "palatal" and part ~= "virile" and part ~= "irregular" and part ~= "plain" then
table.insert(kept, part)
end
end
return kept[1] and table.concat(kept, "+") or "plain"
end
--[==[
Object holding the rules of an adjective, with the methods of `NounRules`. The group comes from `adjective_groups`
according to the ending of the lemma (one of `adjective_nominatives`). Adjectives take no stem indicators.
]==]
local AdjectiveRules = setmetatable({}, {__index = NounRules})
AdjectiveRules.__index = AdjectiveRules
function AdjectiveRules.new(base, word)
local data = base.data
local stem, nominative, group
for _, ending in ipairs(data.adjective_nominatives) do
stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
if stem then
nominative = ending
group = data.adjective_groups["adj common sg " .. ending]
break
end
end
if not group then
local endings = {}
for _, ending in ipairs(data.adjective_nominatives) do
table.insert(endings, "-" .. ending)
end
error(("'%s' doesn't end in %s; an irregular adjective takes <irreg>"):format(word,
table.concat(endings, " or ")), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
head_slot = "nom_m", used = {}}, AdjectiveRules)
end
--[==[
Object holding the rules of a lect's paradigm, i.e. an entry of `lect_tables` with `table = "paradigm"`, such as
Standard Kurpie (`lect:skur`). The paradigm is the table in the data named by the entry's `rules`. Its `types` decide
the type of a lemma, and each type has one ending per slot. It answers the same calls from `decline_word` as
`NounRules`.
]==]
local ParadigmRules = {}
ParadigmRules.__index = ParadigmRules
-- Return the last consonant of a stem, which is either one of the data's `digraphs` or a single letter.
local function final_consonant(data, stem)
local last_two = mw.ustring.sub(stem, -2)
return data.digraphs[last_two] and last_two or mw.ustring.sub(stem, -1)
end
-- Return the stem, type and declension (the gender whose endings it takes) of a lemma in `paradigm`, decided by its
-- gender and ending (see `types` in the data). `name` is the name of the lect, for the error messages.
local function paradigm_type(data, paradigm, name, word, gender, text)
for _, entry in ipairs(gender and paradigm.types[gender] or {}) do
local stem = entry.ending == "" and word or mw.ustring.match(word, "^(.+)" .. entry.ending .. "$")
if stem and not (entry.consonant_final and mw.ustring.find(word, "[" .. paradigm.vowels .. "]$")) then
local final = final_consonant(data, stem)
for _, class in ipairs(entry.by_final or {}) do
if paradigm[class[1]][final] then
return stem, class[2], entry.declension or gender
end
end
return stem, entry.default, entry.declension or gender
end
end
spec_error(("The %s rules have no %s noun like '%s'; give its forms as overrides"):format(name,
gender and M.data.genders[gender].name or "genderless", word), text)
end
-- Return `stem` with the slanted vowel of its last syllable made clear by the `clear` table of `paradigm`, or by
-- `clear_before_nasal` when one of its `nasals` follows the vowel. Return nil if that vowel isn't slanted.
local function clear_vowel(paradigm, stem)
local vowels = paradigm.vowels
local following = mw.ustring.match(stem, "[" .. vowels .. "]([^" .. vowels .. "]?)[^" .. vowels .. "]*$")
local before_nasal = paradigm.nasals and paradigm.nasals[following] and paradigm.clear_before_nasal
return alternate(vowels, stem, before_nasal or paradigm.clear)
end
function ParadigmRules.new(base, word, paradigm, name)
local data = base.data
local plural = base.number == "pl"
local stem, type, declension
if plural then
-- A plurale tantum is declined from its nominative plural, with the plural endings of its gender's hard stems.
if not paradigm.plural_nominatives then
spec_error(("The %s rules have no pluralia tantum"):format(name), base.text)
end
for _, ending in ipairs(paradigm.plural_nominatives) do
stem = stem or mw.ustring.match(word, "^(.+)" .. ending .. "$")
end
if not stem then
spec_error(("The %s rules have no plurale tantum like '%s'"):format(name, word), base.text)
end
type, declension = "hard", base.gender or "n"
else
stem, type, declension = paradigm_type(data, paradigm, name, word, base.gender, base.text)
end
local consonant_final = not plural and stem == word
if declension == "m" and base.animacy ~= "inan" and paradigm.animate_types and paradigm.animate_types[type] then
type = paradigm.animate_types[type]
end
if base.reducible then
stem = reduce(data, stem) or spec_error(("The stem '%s' has no mobile e"):format(stem), base.text)
end
-- With `#`, the forms with an ending have the clear vowel of `clear_stem`.
local clear_stem
if base.quantity == "none" then
spec_error(("The %s rules have no vowel alternation for '-#' to remove"):format(name), base.text)
elseif base.quantity == "full" then
if not paradigm.clear then
spec_error(("The %s rules have no vowel alternation for '#'"):format(name), base.text)
elseif not consonant_final then
spec_error(("In the %s rules, '#' needs a lemma that ends in a consonant"):format(name), base.text)
end
clear_stem = clear_vowel(paradigm, stem)
or spec_error(("The stem '%s' has no slanted vowel for '#' to make clear"):format(stem), base.text)
end
local endings = paradigm.nouns[declension][type]
if plural then
local plural_endings = {}
for slot, ending in pairs(endings) do
if mw.ustring.find(slot, "_p$") then
plural_endings[slot] = ending
end
end
endings = plural_endings
end
local copies = {}
for slot, source in pairs(paradigm.copies[declension]) do
copies[slot] = source
end
if base.gender == "m" then
for slot, source in pairs(paradigm.animate_copies[base.animacy]) do
copies[slot] = source
end
end
return setmetatable({base = base, data = data, paradigm = paradigm, word = word, stem = stem, clear_stem = clear_stem,
endings = endings, group = {copies = copies}, head_slot = plural and "nom_p" or "nom_s"}, ParadigmRules)
end
-- Return one form: the stem (with its clear vowel before an ending, under `#`), palatalized if `label` is `palatal` (by
-- the paradigm's own `palatal` table), followed by the ending. After a hardened consonant, the first letter of the
-- ending is respelled by `hardened_spelling`.
function ParadigmRules:form(label, ending, note)
local paradigm = self.paradigm
local stem = self.clear_stem and ending ~= "" and self.clear_stem or self.stem
if label == "palatal" then
local last_two = mw.ustring.sub(stem, -2)
if paradigm.palatal[last_two] then
stem = mw.ustring.sub(stem, 1, -3) .. paradigm.palatal[last_two]
else
stem = mw.ustring.sub(stem, 1, -2) .. (paradigm.palatal[mw.ustring.sub(stem, -1)] or mw.ustring.sub(stem, -1))
end
end
if paradigm.hardened and paradigm.hardened[final_consonant(self.data, stem)] then
local respelled = paradigm.hardened_spelling and paradigm.hardened_spelling[mw.ustring.sub(ending, 1, 1)]
if respelled then
ending = respelled .. mw.ustring.sub(ending, 2)
end
end
return {form = stem .. ending, footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil}
end
function ParadigmRules:forms(slot)
local cell = self.endings[slot]
if not cell then
return {}
end
if type(cell) == "string" then
return {self:form("plain", cell)}
end
return {self:form(cell.stem or "plain", cell[1], cell.note)}
end
-- Return the stem label of a slot's rule. An ending given for the slot in an override goes on that stem.
function ParadigmRules:overrideLabel(slot)
local cell = self.endings[slot]
return type(cell) == "table" and cell.stem or "plain"
end
------------------------------------------------------------------------------------------------------------------------
-- Declension --
------------------------------------------------------------------------------------------------------------------------
-- Return the forms of a noun from the lexicon (`<irreg>`) or of an indeclinable noun (`<indecl>`).
local function lexicon_forms(base, word)
local forms = {}
if base.indicators.irreg then
local list = base.data.irregular_nouns[word]
if not list then
error(("'%s' is not one of the irregular nouns"):format(word), 0)
end
for i, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = list[i]}}
end
elseif base.indicators.indecl then
for _, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = word}}
end
end
return forms
end
-- Return the masculine nominative singular of an adjectival word given in another gender, using `adjective_lemma` in
-- the data, e.g. ''teściowa'' → ''teściowy'', ''tania'' → ''tani'', ''bykowe'' → ''bykowy'', ''wielkie'' →
-- ''wielki''. A plural such as ''Zjednoczone'' works the same way.
local function adjective_lemma(data, word, rule_gender, plural)
local lemma = data.adjective_lemma
for _, ending in ipairs(lemma.endings[plural and "plural" or rule_gender] or {}) do
local stem = mw.ustring.match(word, "^(.+)" .. ending[1] .. "$")
if stem then
return stem .. ((ending.soft or lemma.soft_after[mw.ustring.sub(stem, -1)]) and lemma.soft or lemma.hard)
end
end
return word
end
--[==[
Return the masculine nominative singular that goes with a virile plural, e.g. ''krewni'' → ''krewny'', ''polscy'' →
''polski''. We try each word that the data's `palatal` table could have softened into the plural (before one of the
`virile_endings`) and return the one whose virile nominative plural, as the adjective rules give it, is that plural.
Return {nil} if there's none.
]==]
local function virile_lemma(data, word)
local adjective = {indicators = {}, overrides = {}, data = data}
for final, softened in pairs(data.palatal) do
for _, ending in ipairs(data.virile_endings) do
local stem = mw.ustring.match(word, "^(.+)" .. softened .. ending .. "$")
if stem then
for _, nominative in ipairs(data.adjective_nominatives) do
local lemma = stem .. final .. nominative
local ok, rules = pcall(AdjectiveRules.new, adjective, lemma)
if ok then
for _, form in ipairs(rules:forms("nom_mp_pers")) do
if form.form == word then
return lemma
end
end
end
end
end
end
end
return nil
end
-- Return the forms of an adjective in a lect's paradigm (`lect:skur`): the endings of the paradigm's `adjective` added
-- to the lemma minus its last letter, with the slots shared as for every adjective (`adjective_shared` in the data).
local function paradigm_adjective_forms(data, paradigm, word)
local stem = mw.ustring.sub(word, 1, -2)
local forms = {nom_m = {{form = word}}}
for slot, ending in pairs(paradigm.adjective) do
forms[slot] = {{form = stem .. ending}}
end
for source, targets in pairs(data.adjective_shared) do
for _, target in ipairs(targets) do
forms[target] = forms[source]
end
end
return forms
end
-- Return the forms of an adjectival word (`+`) in a lect's paradigm (`lect:skur`), in noun slots. Its masculine comes from
-- the word as given: the word minus the paradigm's nominative ending for its gender and number, with ''-ï'' after one of
-- the paradigm's `adjective_soft` consonants and ''-y'' otherwise.
local function paradigm_adjectival_forms(base, word, rule_gender, plural)
local data = base.data
local paradigm = data[base.lect_table.rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
local masculine = word
if plural or rule_gender == "f" or rule_gender == "n" then
local ending = paradigm.adjective[plural and (rule_gender == "m-pr" and "nom_mp_pers" or "nom_p_not_mp_pers")
or "nom_" .. rule_gender]
local stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
or spec_error(("The adjectival word '%s' doesn't end in -%s"):format(word, ending), base.text)
masculine = stem .. (paradigm.adjective_soft and paradigm.adjective_soft[final_consonant(data, stem)] and "ï" or "y")
end
local adjective = paradigm_adjective_forms(data, paradigm, masculine)
for _, pair in ipairs(data.adjective_accusatives) do
adjective[pair[2]] = adjective[pair[2]] or adjective[pair[1]]
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = adjective[adjective_slot] or {}
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = adjective[adjective_slot] or {}
end
end
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
-- Return the forms of an adjectival word (`+`) in noun slots, using `adjectival_slots` in the data.
local function adjectival_forms(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy or "inan"]
end
local plural = base.number == "pl"
if base.lect_table and base.lect_table.table == "paradigm" then
return paradigm_adjectival_forms(base, word, rule_gender, plural)
end
local lemma = plural and rule_gender == "m-pr" and virile_lemma(data, word) or adjective_lemma(data, word, rule_gender, plural)
local adjective = {lemma = lemma, indicators = {}, overrides = {}, data = data}
local rules = AdjectiveRules.new(adjective, adjective.lemma)
local function forms_of(slot)
if slot == "nom_m" then
return {{form = adjective.lemma}}
end
local source = rules.group.copies[slot]
while source and rules.group.copies[source] do
source = rules.group.copies[source]
end
if source == "nom_m" then
return {{form = adjective.lemma}}
end
return rules:forms(source or slot) or {}
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = forms_of(adjective_slot)
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = forms_of(adjective_slot)
end
end
-- The word as given heads its table.
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
--[==[
Resolve the lect of a `lect:` indicator or a `[lect:CODE:PLACE]` tag through the aliases in the data module of the lects
(`lect_module` in the language's data, which is [[Module:zlw-lch-IPA/data/pl]] for Polish). Return the code and the
name of the lect.
]==]
local function lect_of(data, code, text)
local lects = mw.loadData(data.lect_module)
code = lects.lect_aliases[code] or code
local lect = lects.lects[code]
if not lect then
local codes = {}
for known in pairs(lects.lects) do
table.insert(codes, known)
end
table.sort(codes)
spec_error(("Unrecognized lect '%s'; the lects are %s"):format(code, table.concat(codes, ", ")), text)
end
return code, lect.name
end
-- Return a footnote `[lect:CODE]` or `[lect:CODE:PLACE]` of a word of `base` as it's shown, with the name of the lect
-- formatted as its label is (linked to the article on the dialect) and the place. Return nil if the footnote isn't a
-- lect tag.
local function lect_footnote(base, footnote)
local code, place = mw.ustring.match(footnote, "^%[lect:([^:%]]+):?(.-)%]$")
if not code then
return nil
end
local _, name = lect_of(base.data, code, base.text)
local label = M.labels.get_label_info{label = name, lang = base.lang, nocat = true}.label
return "[" .. label .. (place ~= "" and " (" .. place .. ")" or "") .. "]"
end
-- Return the link target of a form of an attested lect, i.e. its modern spelling according to `respelling` (e.g.
-- ''ptåka'' → ''ptaka''). Return nil if it's spelled the same.
local function respelled(respelling, form)
local target = mw.ustring.gsub(form, ".", respelling)
return target ~= form and target or nil
end
-- Return a `generate_link` function for `show_forms` for the table of `spec`, which links a respelled form (one with a
-- `target`) to its modern spelling.
local function respelled_link(spec)
return function(data)
if data.form.target then
return M.links.full_link{lang = spec.lang, term = data.form.target, alt = data.form.formval_for_link,
tr = "-"} .. M.inflection_utilities.get_footnote_text(data.form.footnotes, data.footnote_obj)
end
end
end
--[==[
Return the forms of an attested table (Middle Polish `lect:mpl`, the `dialectal` table and every Old Polish table),
which are the cells given, exactly as given, and nothing else. In a dialectal table, every form must have a lect,
either from its own `[lect:...]` tag or from a tag given for the whole word.
]==]
local function attested_forms(base)
local forms = {}
local word_lect
local word_footnotes = {}
for _, note in ipairs(base.footnotes or {}) do
local shown = lect_footnote(base, note)
word_lect = word_lect or shown
table.insert(word_footnotes, shown or note)
end
-- the forms with a lect tag of their own, which the lect tag of the word doesn't go on
local own_lect = {}
local respelling = base.lect_table and base.lect_table.respelling and base.data[base.lect_table.respelling]
for slot, override in pairs(base.overrides) do
if not override.full then
spec_error(("An attested table takes whole forms: '%s:FORM'"):format(slot), base.text)
end
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
local footnotes, lect = {}, nil
for _, note in ipairs(value.footnotes or {}) do
local shown = lect_footnote(base, note)
lect = lect or shown
table.insert(footnotes, shown or note)
end
if base.indicators.dialectal then
if not lect and not word_lect then
spec_error(("The dialectal form '%s' needs [lect:CODE]"):format(value.form), base.text)
end
end
local form = {
form = value.form,
target = respelling and respelled(respelling, value.form) or nil,
footnotes = footnotes[1] and footnotes or nil,
}
own_lect[form] = lect and true or nil
table.insert(list, form)
end
end
forms[slot] = list
end
if base.footnotes then
base.footnotes, base.word_lect, base.own_lect = word_footnotes, word_lect, own_lect
end
return forms
end
-- Return the entry of a pronoun in the data's `pronouns` along with the ending its forms take. This is the lemma's own
-- entry (with no ending), or the entry of the pronoun it's made from plus one of the `pronoun_suffixes` (e.g.
-- ''cośkolwiek'' is ''co'' plus ''-śkolwiek'').
local function pronoun_entry(data, lemma)
local pronouns = data.pronouns
if pronouns[lemma] then
return pronouns[lemma], ""
end
for _, suffix in ipairs(data.pronoun_suffixes or {}) do
local head = mw.ustring.match(lemma, "^(.+)" .. suffix .. "$")
if head and pronouns[head] then
return pronouns[head], suffix
end
end
return nil
end
-- Return the forms of a pronoun (`<pron>`) with their notes. In an attested table (Old Polish), the forms given in the
-- spec go on top of them.
local function pronoun_forms(base, word)
local data = base.data
local pronoun, suffix = pronoun_entry(data, word)
if not pronoun then
local lemmas = {}
for lemma in pairs(data.pronouns) do
table.insert(lemmas, lemma)
end
table.sort(lemmas)
local message = ("No pronoun '%s'; the pronouns are %s"):format(word, table.concat(lemmas, ", "))
if data.pronoun_suffixes then
local suffixes = {}
for _, item in ipairs(data.pronoun_suffixes) do
table.insert(suffixes, "-" .. item)
end
message = message .. ", and these with " .. table.concat(suffixes, ", ")
end
spec_error(message, base.text)
end
base.pronoun = pronoun
local forms = {}
for slot, list in pairs(pronoun) do
if slot ~= "numbers" and slot ~= "numberless" then
forms[slot] = {}
for _, item in ipairs(list) do
local form = {form = (type(item) == "table" and item[1] or item) .. suffix}
if type(item) == "table" then
form.footnotes = {}
for _, note in ipairs(item.notes) do
table.insert(form.footnotes, "[" .. data.notes[note] .. "]")
end
end
table.insert(forms[slot], form)
end
end
end
if base.attested then
for slot, list in pairs(attested_forms(base)) do
forms[slot] = list
end
end
return forms
end
-- Return the rule of a numeral in `rules` (`numeral_rules` or `collective_rules` in the data), i.e. the rule of the
-- longest key that the lemma ends in, along with the lemma minus that key.
local function numeral_rule(rules, word, text)
for length = mw.ustring.len(word), 0, -1 do
local key = length == 0 and "" or mw.ustring.sub(word, -length)
if rules[key] then
return rules[key], mw.ustring.sub(word, 1, mw.ustring.len(word) - length)
end
end
spec_error(("No numeral declines like '%s'"):format(word), text)
end
-- Return the forms of a numeral (`<num>`), i.e. the endings of its rule added to its stem.
local function numeral_forms(rules, base, word)
local rule, stem = numeral_rule(rules, word, base.text)
local forms = {}
for slot, cell in pairs(rule) do
forms[slot] = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(forms[slot], {form = stem .. ending[1],
footnotes = ending.note and {"[" .. base.data.notes[ending.note] .. "]"} or nil})
end
end
return forms
end
--[==[
Add the footnotes given for the whole word (`base.footnotes`) after the footnotes of every form, as new form objects,
since a copied slot shares the form objects of its source. In an attested table the word's lect tag
(`base.word_lect`) only goes on the forms without a lect tag of their own (`base.own_lect`). Return the forms.
]==]
local function add_word_footnotes(base, forms)
if not base.footnotes then
return forms
end
for slot, list in pairs(forms) do
local copy = {}
for _, form in ipairs(list) do
local footnotes = {}
for _, note in ipairs(form.footnotes or {}) do
table.insert(footnotes, note)
end
for _, note in ipairs(base.footnotes) do
if not (note == base.word_lect and base.own_lect[form]) then
table.insert(footnotes, note)
end
end
table.insert(copy, {form = form.form, footnotes = footnotes, target = form.target})
end
forms[slot] = copy
end
return forms
end
--[==[
Decline a single word. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]]. First the
rules fill every slot they cover. Then the overrides apply (an ending goes on the stem that the slot's rule uses, and a
form replaces the cell), followed by the copies (unless a copy is overridden itself), the deprecative forms of a
masculine personal noun (after its nominative plural, with a footnote) and finally the footnote for the whole word.
]==]
local function decline_word(base)
local word = base.indicators.decllemma or base.lemma
local forms, rules
if base.attested then
base.forms = add_word_footnotes(base, base.indicators.pron and pronoun_forms(base, word) or attested_forms(base))
return
elseif base.indicators.pron then
forms = pronoun_forms(base, word)
elseif base.indicators.num then
forms = numeral_forms(base.data.collective_rules, base, word)
elseif base.indicators.irreg or base.indicators.indecl then
forms = lexicon_forms(base, word)
elseif base.indicators["!"] then
-- A manual table has only the forms its overrides give.
forms = {}
elseif base.indicators["+"] then
forms = adjectival_forms(base, word)
else
rules = base.lect_table and base.lect_table.table == "paradigm"
and ParadigmRules.new(base, word, base.data[base.lect_table.rules], base.lect_name) or NounRules.new(base, word)
-- The lemma heads the table, even when another word is declined in its place (`decllemma`).
forms = {[rules.head_slot] = {{form = base.lemma}}}
-- The rules give the singular and the plural; only an attested table has the dual.
for _, entry in ipairs(M.data.noun_slots) do
local slot = entry.slot
if entry.number ~= "d" and slot ~= rules.head_slot and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
-- A form that is the declined word itself (e.g. an inanimate accusative) belongs to the lemma.
for _, form in ipairs(forms[slot] or {}) do
if form.form == word then
form.form = base.lemma
end
end
end
end
-- In a phrase the deprecative forms would agree with nothing (''pany młodzi''), so only a single word shows
-- them.
if not base.in_phrase then
forms.depr_p = rules:forms("depr_p")
end
end
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.default then
for _, form in ipairs(rules and rules:forms(slot) or {}) do
table.insert(list, form)
end
elseif override.full then
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
else
local form = rules and rules:form(rules:overrideLabel(slot, value.form), value.form) or {form = word .. value.form}
form.footnotes = value.footnotes
table.insert(list, form)
end
end
forms[slot] = list
end
if rules then
-- A copy can copy another copy (e.g. the vocative of a feminine consonant-stem noun is its locative, which is
-- its dative). Fill each one from the slot at the end of its chain, unless a slot along the way is overridden.
local copies = rules.group.copies
for slot in pairs(copies) do
if not base.overrides[slot] then
local source = copies[slot]
while copies[source] and not base.overrides[source] do
source = copies[source]
end
local list = {}
for _, form in ipairs(forms[source] or {}) do
table.insert(list, form)
end
forms[slot] = list
end
end
end
if forms.depr_p then
forms.nom_p = forms.nom_p or {}
-- A deprecative form that's the same as a virile form (e.g. ''zaklinacze'') isn't a separate form, so don't
-- show it twice.
local virile = {}
for _, form in ipairs(forms.nom_p) do
virile[form.form] = true
end
for _, form in ipairs(forms.depr_p) do
if not virile[form.form] then
table.insert(forms.nom_p, {form = form.form, footnotes = form.footnotes or {"[" .. base.data.notes.deprecative .. "]"}})
end
end
forms.depr_p = nil
end
base.forms = add_word_footnotes(base, forms)
-- Keep the rules the forms came from, and the alternations they used, for the categories.
base.rules = rules
end
-- Join an adjective stem and an ending. If the data's `adjective_dropped` says the last letter of the stem drops before
-- the first letter of the ending, drop it (e.g. ''moj-'' + ''-ich'' → ''moich'').
local function adjective_form(data, stem, ending)
local before = data.adjective_dropped[mw.ustring.sub(stem, -1)]
if before and mw.ustring.sub(ending, 1, mw.ustring.len(before)) == before then
return mw.ustring.sub(stem, 1, -2) .. ending
end
return stem .. ending
end
-- Return the forms of an irregular adjective from `irregular_adjectives`, along with the layout of the table it needs
-- (nil, `dwa` or `plonly`).
local function irregular_adjective_forms(base, word)
local data = base.data
for _, entry in ipairs(data.irregular_adjectives) do
local captured = mw.ustring.match(word, entry.pattern)
if captured or entry.stem and mw.ustring.find(word, entry.pattern) then
local forms = {}
local function add(slot, stem, endings, note)
if type(endings) == "string" then
endings = {endings}
end
for _, ending in ipairs(endings or {}) do
forms[slot] = forms[slot] or {}
local form = ending == "-" and base.lemma or adjective_form(data, stem, ending)
table.insert(forms[slot], {form = form, footnotes = note and {"[" .. note .. "]"} or nil})
end
end
if entry.table ~= "dwa" then
add("nom_m", nil, "-")
end
for _, set in ipairs(entry.sets) do
local stem = (entry.stem or captured) .. (set.add or "")
for slot, endings in pairs(set.endings or {}) do
add(slot, stem, endings, set.note)
for _, target in ipairs(data.adjective_shared[slot] or {}) do
add(target, stem, endings, set.note)
end
end
for slot, endings in pairs(set.own or {}) do
add(slot, stem, endings, set.note)
end
if set.archaic_dative and base.indicators.archdat then
add("dat_mn", stem, set.archaic_dative, data.notes[data.archaic_dative.note])
end
end
return forms, entry.table
end
end
error(("Unrecognized irregular adjective '%s'"):format(word), 0)
end
--[==[
Decline a single adjective. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]] for
{{tl|pl-adecl}}. The rules (or the lexicon of irregular adjectives) fill the slots; then the overrides apply, followed
by the accusatives taken from other slots (unless overridden) and the footnote for the whole word. An attested table
has the cells given and nothing else.
]==]
local function decline_adjective_word(base)
local data = base.data
local word = base.indicators.decllemma or base.lemma
local forms, layout
if base.attested then
-- The cells given and nothing else, with the dual columns if `du` is given.
forms, layout = attested_forms(base), base.indicators.du and "dual" or nil
elseif base.indicators.irreg then
forms, layout = irregular_adjective_forms(base, word)
elseif base.indicators.lect then
local paradigm = data[data.lect_tables[base.indicators.lect].rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
forms = paradigm_adjective_forms(data, paradigm, word)
-- With `decllemma`, the lemma itself heads the table (''båbcyn'' declined as ''båbcyny'').
forms.nom_m = {{form = base.lemma}}
elseif base.indicators.num then
forms, layout = numeral_forms(data.numeral_rules, base, word), "plonly"
else
local rules = AdjectiveRules.new(base, word)
-- With `decllemma`, the lemma itself still heads the table (''wart'' declined as ''warty'').
forms = {nom_m = {{form = base.lemma}}}
for _, slot in ipairs(data.adjective_slots) do
if slot ~= "nom_m" and slot ~= "short" and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
end
end
if base.indicators.archdat then
local archaic = data.archaic_dative
table.insert(forms.dat_mn, {form = rules.stem .. archaic[1], footnotes = {"[" .. data.notes[archaic.note] .. "]"}})
end
-- Keep the slots that every adjective shares as copies, so that an override of the source carries over.
for slot, source in pairs(rules.group.copies) do
local accusative = mw.ustring.find(slot, "^acc")
if not accusative and not base.overrides[slot] then
forms[slot] = forms[source]
end
end
end
if not base.attested then
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
end
forms[slot] = list
end
for _, pair in ipairs(data.adjective_accusatives) do
local source, target = pair[1], pair[2]
if not base.overrides[target] and forms[source] and not (base.indicators.irreg and forms[target]) then
forms[target] = forms[source]
end
end
end
base.forms = add_word_footnotes(base, forms)
base.layout = layout
end
-- Return the attested tables there are for `template` (`noun` or `adjective`), for the error messages: those of the
-- language's attested lects and its dialectal table, plus the templates of the languages whose tables of that kind are
-- all attested.
local function attested_tables(data, template)
local tables = {}
local codes = {}
for code, lect_table in pairs(data.lect_tables or {}) do
if lect_table.table == "attested" then
table.insert(codes, code)
end
end
table.sort(codes)
for _, code in ipairs(codes) do
table.insert(tables, "<lect:" .. code .. ">")
end
if data.indicators[template].dialectal then
table.insert(tables, "<dialectal>")
end
local languages = {}
for code, language in pairs(M.data.languages) do
if language[template] then
table.insert(languages, code)
end
end
table.sort(languages)
for _, code in ipairs(languages) do
if mw.loadData("Module:zlw-lch-decl/data/" .. code).attested then
table.insert(tables, "{{" .. M.data.languages[code][template] .. "}}")
end
end
return table.concat(tables, ", ")
end
-- Work out the table a base is for: its lect (`lect:CODE`), and whether the table is attested, i.e. has only the cells
-- given (for an attested lect, the dialectal table, or a language whose tables are all attested). Throw an error if
-- `recon` or `du` is given for a table that isn't attested, if a lect tag appears outside the dialectal table, or if a
-- dual slot is given without `du`.
local function resolve_table(base)
local data = base.data
if base.indicators.lect then
base.indicators.lect, base.lect_name = lect_of(data, base.indicators.lect, base.text)
base.lect_table = data.lect_tables[base.indicators.lect]
if not base.lect_table then
local codes = {}
for code in pairs(data.lect_tables) do
table.insert(codes, code)
end
table.sort(codes)
spec_error(("The lect '%s' has no table of its own (the lects with one are %s); give its forms in a "
.. "<dialectal> table"):format(base.indicators.lect, table.concat(codes, ", ")), base.text)
end
end
base.attested = data.attested or base.indicators.dialectal
or base.lect_table and base.lect_table.table == "attested" or nil
for _, name in ipairs({"recon", "du"}) do
if base.indicators[name] and not base.attested then
spec_error(("Only an attested table (%s) takes '%s'"):format(attested_tables(data, base.template), name),
base.text)
end
end
-- A form of a lect can only be tagged in the dialectal table, so that none ends up among the standard forms.
if not base.indicators.dialectal then
local function check(footnotes)
for _, footnote in ipairs(footnotes or {}) do
if mw.ustring.find(footnote, "^%[lect:") then
spec_error(("A lect's form (%s) belongs in a <dialectal> table"):format(footnote), base.text)
end
end
end
check(base.footnotes)
for _, override in pairs(base.overrides) do
for _, value in ipairs(override.values) do
check(value.footnotes)
end
end
end
if not base.indicators.du then
for slot in pairs(base.overrides) do
if mw.ustring.find(slot, "_d$") then
spec_error(("The dual slot '%s' needs the indicator 'du'"):format(slot), base.text)
end
end
end
end
-- Set the fields of a base that the rules use, based on its indicators.
local function normalize_base(base)
base.gender = base:group("gender")
base.animacy = base:group("animacy")
base.number = base:group("number")
base.kind = base:group("kind")
if base.indicators["*"] then
base.reducible = true
elseif base.indicators["-*"] then
base.reducible = false
end
base.quantity = base.indicators["#"] and "full" or base.indicators["-#"] and "none" or nil
if base.gender == "m" and not base.animacy then
base.animacy = "inan"
end
resolve_table(base)
end
------------------------------------------------------------------------------------------------------------------------
-- Output --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object to render the declined words as a table with [[Module:inflection-table]], with a column for each number shown and
a row for each case. Each row has a `data-case` attribute so that scripts can reorder the cases. The cells come from
`show_forms` in [[Module:inflection utilities]], linked with accelerators for the lemma, and the footnotes go under the
table.
]==]
local TableRenderer = {}
TableRenderer.__index = TableRenderer
function TableRenderer.new(spec)
return setmetatable({spec = spec}, TableRenderer)
end
function TableRenderer:numbers()
local numbers = {}
for _, number in ipairs(M.data.numbers) do
if self.spec.numbers[number.code] then
table.insert(numbers, number)
end
end
return numbers
end
-- Return the title of a table: `title=` if given, otherwise what the table is (e.g. "Declension of " or "Attested
-- Middle Polish forms of ") followed by its head, unlinked. `suffix` follows the default title (`default_kind` and the
-- lemma), e.g. the declension kinds of an adjective.
function TableRenderer:title(default_kind, suffix)
local spec = self.spec
if spec.title then
return spec.title
end
local kind, head = default_kind, spec.forms.lemma
if spec.kind_title then
kind, head, suffix = spec.kind_title[1], spec.kind_title[2] or head, nil
end
return kind .. M.links.full_link({lang = spec.lang, alt = head}, "term") .. (suffix or "")
end
-- Return the first lines of a table titled `title`: the frame from [[Module:inflection-table]], with its first row
-- opened.
function TableRenderer:top(title)
return {M.inflection_table.make_top{
title = title,
palette = "blue",
tall = "yes",
lang = self.spec.lang:getCode(),
}}
end
-- Close the table in `lines` with its footnotes and categories, and return its wikitext.
function TableRenderer:finish(lines)
local spec = self.spec
table.insert(lines, M.inflection_table.make_bottom{notes = spec.forms.footnote or ""})
if spec.categories[1] and not spec.nocat then
table.insert(lines, M.utilities.format_categories(spec.categories, spec.lang))
end
return table.concat(lines, "\n")
end
function TableRenderer:render()
local spec = self.spec
local numbers = self:numbers()
local slot_list = {}
for _, case in ipairs(M.data.cases) do
for _, number in ipairs(numbers) do
-- A table with one number doesn't name it in its accelerators, and an attested or lect table has none
-- ("-").
local accel = (spec.attested or spec.lect) and "-" or #numbers > 1 and case.accel .. "|" .. number.accel or case.accel
table.insert(slot_list, {case.code .. "_" .. number.code, accel})
end
end
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
-- A Middle Polish form links to its modern spelling.
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của "))
-- make_top has already opened the first row.
table.insert(lines, '! class="outer" |')
for _, number in ipairs(numbers) do
-- A numberless pronoun (e.g. ''siebie'') has an empty header over its one column.
table.insert(lines, '! class="outer" | ' .. (spec.numberless and "" or number.name))
end
for _, case in ipairs(M.data.cases) do
table.insert(lines, ('|- data-case="%s"'):format(case.code))
table.insert(lines, ('! title="%s" | %s'):format(spec.data.case_titles[case.code], case.name))
for _, number in ipairs(numbers) do
local cell = spec.forms[case.code .. "_" .. number.code]
table.insert(lines, "| " .. (cell or "—"))
end
end
return self:finish(lines)
end
--[==[
The rows of an adjective table, by layout. Each row is a case and its cells, and each cell is a slot and the number of
columns it spans. The regular table has the masculine animate, masculine inanimate, feminine and neuter singular, then
the virile and non-virile plural, as in the former [[Module:pl-adjective]]. The dual table (an attested table with `du`)
puts the dual, masculine and feminine/neuter, between them.
]==]
local ADJECTIVE_LAYOUTS = {
regular = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_mp_pers"},
{"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_p", 2}}},
},
},
plonly = {
columns = {
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_p", 2}}},
{"dat", "dative", {{"dat_p", 2}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_p", 2}}},
{"loc", "locative", {{"loc_p", 2}}},
},
},
-- an attested table with the dual (`du`), between the singular and the plural
dual = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"dual", 2, {"masculine", "feminine/<wbr />neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_m_d"}, {"nom_fn_d"},
{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_d", 2}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_d", 2}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_m_d"}, {"acc_fn_d"},
{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_d", 2}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_d", 2}, {"loc_p", 2}}},
},
},
dwa = {
columns = {
{"plural", 4, {"masculine personal", "masculine non-personal", "feminine", "neuter"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_mp_npers"}, {"nom_fp"}, {"nom_np"}}},
{"gen", "genitive", {{"gen_p", 4}}},
{"dat", "dative", {{"dat_p", 4}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_mp_npers"}, {"acc_fp"}, {"acc_np"}}},
{"ins", "instrumental", {{"ins_mnp", 2}, {"ins_fp"}, {"ins_mnp"}}},
{"loc", "locative", {{"loc_p", 4}}},
},
},
}
function TableRenderer:renderAdjective()
local spec = self.spec
local layout = ADJECTIVE_LAYOUTS[spec.layout]
local slot_list = {}
for slot, accel in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, (spec.lect or spec.attested) and "-" or accel})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của ",
spec.kinds[1] and " (" .. table.concat(spec.kinds, " // ") .. ")" or nil))
-- make_top has already opened the first row. Add the number headers, then the gender headers.
table.insert(lines, '! class="outer" rowspan="2" |')
for _, column in ipairs(layout.columns) do
table.insert(lines, ('! class="outer" colspan="%d" | %s'):format(column[2], column[1]))
end
table.insert(lines, "|- class=\"secondary\"")
for _, column in ipairs(layout.columns) do
for _, header in ipairs(column[3]) do
table.insert(lines, "! " .. header)
end
end
for _, row in ipairs(layout.rows) do
table.insert(lines, ('|- data-case="%s"'):format(row[1]))
table.insert(lines, "! " .. row[2])
for _, cell in ipairs(row[3]) do
local span = cell[2] and ('colspan="%d" | '):format(cell[2]) or ""
table.insert(lines, "| " .. span .. (spec.forms[cell[1]] or "—"))
end
end
if spec.forms.short and spec.forms.short ~= "—" then
table.insert(lines, '|- data-case="short"')
table.insert(lines, "! short")
table.insert(lines, '| colspan="2" | ' .. spec.forms.short)
end
return self:finish(lines)
end
------------------------------------------------------------------------------------------------------------------------
-- The call --
------------------------------------------------------------------------------------------------------------------------
--[==[
Decline a noun call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl` or `zlw-opl`). Return the
alternant multiword spec from [[Module:inflection utilities]], with the fields `forms` (a table mapping each slot to a
list of form objects), `numbers` (a set of `s`, `d` and `p`), `categories`, `title` and `nocat`.
]==]
function export.decline_noun(args, pagename, lang_code)
local data, lang = language_of(lang_code, "noun")
-- The angle brackets are omittable, so a bare word would be read as an indicator; with no spec, decline the page
-- name with no indicators.
local spec_text = args[1] or ""
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
local base = Spec.parse(angle_bracket_spec, "noun", data, lang)
normalize_base(base)
return base
end,
allow_blank_lemma = true,
angle_brackets_omittable = true,
}
local spec = M.inflection_utilities.parse_inflected_text(spec_text, parse_props)
local number, noun
local word_count = 0
M.inflection_utilities.map_word_specs(spec, function()
word_count = word_count + 1
end)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
-- An irregular noun has the gender and animacy of its lexicon entry. They're used if the spec gives none, and
-- giving others is an error.
local irregular = base.indicators.irreg and data.irregular_nouns[base.indicators.decllemma or base.lemma]
if irregular then
if base.gender and (base.gender ~= irregular.gender or base.animacy ~= irregular.animacy) then
spec_error(("The irregular noun '%s' is <%s>"):format(base.lemma,
irregular.gender .. (irregular.animacy and "." .. irregular.animacy or "")), base.text)
end
base.gender, base.animacy = irregular.gender, irregular.animacy
end
base.in_phrase = word_count > 1 and #spec.alternant_or_word_specs > 1 or nil
number = number or base.number
if not base.indicators["+"] and base.gender then
noun = noun or base
end
end)
-- An adjectival word (`+`) agrees with the noun of the phrase, taking whatever gender, animacy and number it
-- doesn't give itself.
M.inflection_utilities.map_word_specs(spec, function(base)
if base.indicators["+"] and noun then
base.gender = base.gender or noun.gender
if base.gender == noun.gender then
base.animacy = base.animacy or noun.animacy
end
base.number = base.number or noun.number
end
if base.indicators["+"] and not base.gender then
error(("The adjectival word '%s' needs a gender, or a noun in the phrase"):format(base.lemma), 0)
end
end)
local slot_list = {}
for _, entry in ipairs(M.data.noun_slots) do
table.insert(slot_list, {entry.slot, entry.slot})
end
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_word,
})
local first
M.inflection_utilities.map_word_specs(spec, function(base)
first = first or base
end)
spec.lang = lang
spec.data = data
spec.numbers = number == "sg" and {s = true} or number == "pl" and {p = true} or {s = true, p = true}
if first.indicators.du then
spec.numbers.d = true
end
-- A collective numeral has only the plural.
if first.indicators.num then
spec.numbers = {p = true}
end
if first.pronoun then
spec.numbers = {}
for _, number_code in ipairs(first.pronoun.numbers) do
spec.numbers[number_code] = true
end
spec.numberless = first.pronoun.numberless
end
spec.categories = {}
-- Only a table of the standard language is categorized; for the lects, the labels of the entry do that.
if not first.attested and not first.indicators.lect then
local function add(name, ...)
table.insert(spec.categories, lang:getCanonicalName() .. " " .. data.categories[name]:format(...))
end
if number == "sg" then
add("singularia_tantum")
elseif number == "pl" then
add("pluralia_tantum")
end
if word_count == 1 then
local indicators = first.indicators
if indicators.irreg then
add("irregular")
elseif indicators.indecl then
add("indeclinable")
elseif indicators["+"] then
add("adjectival")
elseif first.rules and first.rules.used then
local final = final_consonant(data, first.rules.stem)
local stem_type = data.stem_types.velar[final] and "velar" or data.stem_types.soft[final] and "soft"
or "hard"
local gender = data.category_genders[first.gender]
if type(gender) == "table" then
gender = gender[first.animacy]
end
-- A plurale tantum has no gender to tell apart, except for a personal one.
if gender and (number ~= "pl" or first.animacy == "pr") then
add("stem", stem_type, gender)
end
local reducible = false
for part in pairs(first.rules.used) do
reducible = reducible or is_mobile(part)
end
if reducible then
add("reducible")
end
local used = first.rules.used
if used.shortened or used.lengthened then
add("quantitative")
end
end
end
end
-- An attested table says what it attests in its title. Its head is the nominative given, or the reconstructed one
-- starred.
spec.attested = first.attested
local head
if first.attested then
local nominative = spec.forms[number == "pl" and "nom_p" or "nom_s"]
head = first.indicators.recon and "*" .. first.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil
end
spec.lect = first.indicators.lect
if first.indicators.lect then
-- A paradigm's table is headed by the lemma, and an attested one by its nominative.
spec.kind_title = {data.lect_titles[first.indicators.lect], first.attested and head or nil}
elseif first.indicators.dialectal then
spec.kind_title = {data.lect_titles.dialectal, head}
elseif data.attested then
spec.kind_title = {"Biến cách của ", head}
end
spec.title = args.title
spec.nocat = args.nocat
spec.lemmas = {pagename}
return spec
end
-- Return the kind of declension of an adjective, for its title and category: `irregular`, or the kind of the first
-- entry in the data's `adjective_kinds` that its lemma matches (hard ''-y'', velar ''-ki'' and ''-gi'', or soft).
local function adjective_kind(base)
if base.indicators.irreg then
return "irregular"
end
local word = base.indicators.decllemma or base.lemma
for _, kind in ipairs(base.data.adjective_kinds) do
if mw.ustring.find(word, kind[1]) then
return kind[2]
end
end
end
--[==[
Decline an adjective call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl`). Return the alternant
multiword spec from [[Module:inflection utilities]], with the fields `forms`, `layout` (`regular`, `plonly`, `dwa` or
`dual`), `kinds` (the declension kinds of its words), `pos` (the part of speech of the table, from `pos:` on one of its
words), `categories`, `title` and `nocat`.
]==]
function export.decline_adjective(args, pagename, lang_code)
local data, lang = language_of(lang_code, "adjective")
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
return Spec.parse(angle_bracket_spec, "adjective", data, lang)
end,
allow_default_indicator = true,
allow_blank_lemma = true,
}
local spec = M.inflection_utilities.parse_inflected_text(args[1] or pagename, parse_props)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
base.lemma = M.links.remove_links(base.lemma)
-- The part of speech belongs to the whole table, so only one word may give it.
local pos = base.indicators.pos
if pos then
if not data.parts_of_speech[pos] then
local names = {}
for name in pairs(data.parts_of_speech) do
table.insert(names, name)
end
table.sort(names)
spec_error(("Unrecognized part of speech '%s'; the parts of speech are %s"):format(pos,
table.concat(names, ", ")), base.text)
elseif spec.pos then
spec_error("The part of speech ('pos:') is given on more than one word", base.text)
end
spec.pos = pos
end
resolve_table(base)
end)
local slot_list = {}
for slot in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, slot})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_adjective_word,
})
spec.pos = spec.pos or "adjective"
local plural_pos = data.parts_of_speech[spec.pos]
spec.layout, spec.kinds, spec.categories = "regular", {}, {}
local seen = {}
M.inflection_utilities.map_word_specs(spec, function(base)
-- A lect's table names its lect and isn't categorized, and neither is a numeral's. An attested table is headed
-- by the masculine nominative given, or the reconstructed lemma starred.
if base.attested then
local nominative = spec.forms.nom_m
spec.attested = true
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect or "dialectal"], base.indicators.recon and "*" .. base.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil}
spec.layout = base.layout or base.indicators.plonly and "plonly" or spec.layout
return
elseif base.indicators.lect then
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect]}
return
elseif base.indicators.num then
spec.layout = base.layout
return
end
local function add(name, ...)
table.insert(spec.categories, lang:getCanonicalName() .. " " .. data.categories[name]:format(...))
end
local kind = adjective_kind(base)
if not seen[kind] then
seen[kind] = true
table.insert(spec.kinds, kind)
add("adjective_kind", kind, plural_pos)
end
if base.overrides.short then
add("short_forms", plural_pos)
end
if base.indicators.decllemma then
add("irregular_stem", plural_pos)
end
if base.layout or base.indicators.plonly then
spec.layout = base.layout or "plonly"
end
end)
spec.title = args.title
spec.nocat = args.nocat
spec.lang = lang
spec.lemmas = {pagename}
return spec
end
-- Process the arguments of a call of the template of `entry` (`noun` or `adjective`). On the template's own page, a call
-- with no arguments declines the language's example (`examples` in [[Module:zlw-lch-decl/data]]) instead of the page
-- name.
local function process_args(frame, entry)
local language = M.data.languages[frame.args.lang]
return M.parameters.process(frame:getParent().args, {
[1] = {template_default = language and language.examples[entry]},
title = {},
nocat = {type = "boolean"},
json = {type = "boolean"},
pagename = {},
})
end
-- Run the template entry point `entry` (`noun` or `adjective`) on the call of `frame`: decline it with `decline`
-- (`export.decline_noun` or `export.decline_adjective`) and return its table, made by the `TableRenderer` method
-- `render`, or with json=1 the table's data, as `json_data` gives it from the declined spec.
local function run_entry(frame, entry, decline, render, json_data)
local args = process_args(frame, entry)
local spec = decline(args, args.pagename or M.headword_data.pagename, frame.args.lang)
if args.json then
return M.JSON.toJSON(json_data(spec))
end
local renderer = TableRenderer.new(spec)
return renderer[render](renderer)
end
--[==[
Entry point for {{tl|pl-ndecl}} and {{tl|zlw-opl-ndecl}}. Template-callable function to parse and decline a noun given
user-specified arguments and generate a displayable table of the declined forms, or the table's data as JSON with
{{para|json|1}}.
]==]
function export.noun(frame)
return run_entry(frame, "noun", export.decline_noun, "render", function(spec)
return {forms = spec.forms, numbers = spec.numbers, categories = spec.categories, title = spec.title}
end)
end
--[==[
Entry point for {{tl|pl-adecl}}. Template-callable function to parse and decline an adjective given user-specified
arguments and generate a displayable table of the declined forms, or the table's data as JSON with {{para|json|1}}.
]==]
function export.adjective(frame)
return run_entry(frame, "adjective", export.decline_adjective, "renderAdjective", function(spec)
return {forms = spec.forms, layout = spec.layout, kinds = spec.kinds, categories = spec.categories,
title = spec.title}
end)
end
return export
cidtd3rf90raarjipza1wsfgi76r1k1
2573188
2573186
2026-10-24T09:09:15Z
Hiyuune
50834
2573188
Scribunto
text/plain
--[==[ intro:
This module implements the declension tables of the Lechitic languages: {{tl|pl-ndecl}} for Polish nouns and
{{tl|pl-adecl}} for Polish adjectives (both with their Middle Polish, Standard Kurpie and dialectal tables), and
{{tl|zlw-opl-ndecl}} for Old Polish nouns.
The following terminology is helpful to understand:
* The '''lemma''' is the word being declined, normally the nominative singular, or the nominative plural of a plurale
tantum. In a call it's followed by an inline spec of indicators in angle brackets, e.g.
`{{pl-ndecl|<m.anml.*.datu>}}` (the page name as an animal noun with a mobile ''e'' and the dative in ''-u'') or
`{{pl-ndecl|Morze<n.sg> Bałtyckie<+>}}`.
* A '''slot''' is a particular combination of case and number, e.g. `nom_s` or `loc_p`. Each slot is one cell of a
table.
* The '''stem''' is the lemma minus its nominative ending. A '''group''' is the set of nouns that share one set of
rules; a '''rule''' gives the forms of a slot for the stems that end in particular letters; and a '''copy''' is a
slot that takes its forms from another one. See [[Module:zlw-lch-decl/data/pl]] for the details.
* An '''alternation''' is a change to the stem that a rule asks for: dropping or inserting the mobile ''e'', ''ó''/''o''
and ''ą''/''ę'', and the palatalizations.
* A '''base''' is what [[Module:inflection utilities]] calls the parsed spec of a single word: its lemma, indicators and
overrides, plus its forms once it has been declined.
Authorship: [[User:Fenakhay]]
]==]
local export = {}
local M = require("Module:module loader").init {
require = {
inflection_table = "Module:inflection-table",
inflection_utilities = "Module:inflection utilities",
JSON = "Module:JSON",
labels = "Module:labels",
languages = "Module:languages",
links = "Module:links",
parameters = "Module:parameters",
parse_utilities = "Module:parse utilities",
utilities = "Module:utilities",
},
loadData = {
data = "Module:zlw-lch-decl/data",
headword_data = "Module:headword/data",
},
}
-- Return the data module of the language `code` (`Module:zlw-lch-decl/data/CODE`) and its language object. `entry` is
-- the entry point being invoked (`noun` or `adjective`); throw an error if `languages` in [[Module:zlw-lch-decl/data]]
-- doesn't list that entry for the language.
local function language_of(code, entry)
local language = code and M.data.languages[code]
if not language or not language[entry] then
local codes = {}
for known, entries in pairs(M.data.languages) do
if entries[entry] then
table.insert(codes, known)
end
end
table.sort(codes)
error(("The #invoke needs lang= with one of %s"):format(table.concat(codes, ", ")), 0)
end
return mw.loadData("Module:zlw-lch-decl/data/" .. code), M.languages.getByCode(code)
end
------------------------------------------------------------------------------------------------------------------------
-- Spec --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the indicators of a single word, i.e. the `<...>` after its lemma, e.g. `<m.anml.*.datu>`. `Spec.parse`
is the `parse_indicator_spec` callback passed to [[Module:inflection utilities]]; it returns the base of the word, with
its indicators by group and its overrides by slot. The indicators each template knows are listed under `indicators` in
the language's data module, and an unknown one is an error that lists the known ones.
]==]
local Spec = {}
Spec.__index = Spec
local function spec_error(message, text)
error(message .. " in the spec '" .. text .. "'.", 0)
end
-- Return the footnotes in a group that `split_alternating_runs` produced from a bracketed run, i.e. the bracketed
-- segments after the first segment. Throw an error if any text follows a footnote.
local function fetch_footnotes(group, text)
local footnotes
for i = 2, #group - 1, 2 do
if group[i + 1] ~= "" then
spec_error("Only another footnote can follow a footnote", text)
end
footnotes = footnotes or {}
table.insert(footnotes, group[i])
end
return footnotes
end
--[==[
Parse an override of one or more slots of a noun. There are two kinds of overrides:
* Endings, written `CASE[pl]ENDING:ENDING...`, e.g. `genu` or `insplami:mi`. These go on the stem that the slot's rule
uses; an ending that starts with an apostrophe goes after the whole lemma (`gen'a` on ''Google'' gives ''Google'a'').
* Whole forms, written `CASE[pl]:FORM:FORM...`, e.g. `voc:człowiecze:człowieku`.
`CASE+CASE...` sets several cases at once, and `du` in place of `pl` names a dual slot (`nomdu`). Among endings, `+`
stands for the forms the rules give, so that e.g. `nomplowie:+` adds ''-owie'' to them. `-` stands for no ending (among
endings) or no form (among forms), and a footnote can follow any value. `depr` is the deprecative nominative plural of
a masculine personal noun. Return two values: the slots the override applies to, and an object describing it.
]==]
local Overrides = {}
function Overrides.parse(group, text)
local part = group[1]
local slots = {}
while true do
if mw.ustring.sub(part, 1, 4) == "depr" then
table.insert(slots, "depr_p")
part = mw.ustring.sub(part, 5)
else
local case = mw.ustring.sub(part, 1, 3)
if not M.data.case_codes[case] then
spec_error(("Unrecognized case '%s' in an override"):format(case), text)
end
part = mw.ustring.sub(part, 4)
if mw.ustring.find(part, "^pl") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_p")
elseif mw.ustring.find(part, "^du") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_d")
else
table.insert(slots, case .. "_s")
end
end
if mw.ustring.find(part, "^%+[a-z]") then
part = mw.ustring.sub(part, 2)
else
break
end
end
local override = {values = {}}
if mw.ustring.find(part, "^:") then
override.full = true
part = mw.ustring.sub(part, 2)
end
group[1] = part
for _, value_group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")) do
local value = value_group[1]
if value == "" then
spec_error("Use - for an empty ending or no form", text)
end
table.insert(override.values, {
form = value == "-" and "" or value,
default = not override.full and value == "+" or nil,
footnotes = fetch_footnotes(value_group, text),
})
end
return slots, override
end
-- The slots of an adjective table, which an override of {{tl|pl-adecl}} can name, with their accelerator tags (using the
-- codes in [[Module:form of/data]], `nv` = non-virile).
local ADJECTIVE_ACCEL = {
nom_m = "nom|m|s", nom_f = "nom|f|s", nom_n = "nom|n|s", nom_mp_pers = "vr|nom|p", nom_p_not_mp_pers = "nv|nom|p",
nom_mp_npers = "nv|nom|m|p", nom_fp = "nom|f|p", nom_np = "nom|n|p",
gen_mn = "gen|m//n|s", gen_f = "gen|f|s", gen_p = "gen|p",
dat_mn = "dat|m//n|s", dat_f = "dat|f|s", dat_p = "dat|p",
acc_m_an = "an|acc|m|s", acc_m_in = "in|acc|m|s", acc_f = "acc|f|s", acc_n = "acc|n|s",
acc_mp_pers = "vr|acc|p", acc_p_not_mp_pers = "nv|acc|p", acc_mp_npers = "nv|acc|m|p", acc_fp = "acc|f|p",
acc_np = "acc|n|p",
ins_mn = "ins|m//n|s", ins_f = "ins|f|s", ins_p = "ins|p", ins_mnp = "ins|m//n|p", ins_fp = "ins|f|p",
loc_mn = "loc|m//n|s", loc_f = "loc|f|s", loc_p = "loc|p",
nom_m_d = "nom|m|d", nom_fn_d = "nom|f//n|d", gen_d = "gen|d", dat_d = "dat|d", acc_m_d = "acc|m|d",
acc_fn_d = "acc|f//n|d", ins_d = "ins|d", loc_d = "loc|d",
short = "short",
}
--[==[
Parse an override of {{tl|pl-adecl}}, in the format of the former [[Module:pl-adjective]]: `SLOT[+SLOT...]:FORM:FORM...`
with the slot names of the adjective, e.g. `nom_mp_pers:weseli` or `gen_p+loc_p:...`. Only whole forms are allowed.
Return the same two values as `Overrides.parse`.
]==]
function Overrides.parseAdjective(group, text)
local slots = {}
local value_groups = M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")
if #value_groups[1] > 1 then
spec_error("A footnote can't follow the slot name of an override", text)
end
for slot in mw.text.gsplit(value_groups[1][1], "+", true) do
if not ADJECTIVE_ACCEL[slot] then
spec_error(("Unrecognized slot '%s' in an override"):format(slot), text)
end
table.insert(slots, slot)
end
local override = {values = {}, full = true}
for i = 2, #value_groups do
local value = value_groups[i][1]
if value == "" then
spec_error("Use - for no form", text)
end
table.insert(override.values, {form = value == "-" and "" or value, footnotes = fetch_footnotes(value_groups[i], text)})
end
return slots, override
end
-- Return the definition of the indicator `name` for `template`, or nil if there isn't one.
local function indicator_definition(data, template, name)
return data.indicators[template][name]
end
-- Return true if `part` of a spec is an override, i.e. it begins with a case code (or `depr`) and isn't an indicator.
local function is_override(data, template, part)
local name = mw.ustring.match(part, "^([^:]*)") or part
if indicator_definition(data, template, name) then
return false
end
return M.data.case_codes[mw.ustring.sub(part, 1, 3)] ~= nil or mw.ustring.sub(part, 1, 4) == "depr"
end
-- Return true if `part` (`NAME:VALUE`) is an indicator that takes a value (e.g. `decllemma:dń` or `lect:skur`) rather
-- than an override.
local function takes_value(data, template, part)
local definition = indicator_definition(data, template, mw.ustring.match(part, "^([^:]+):"))
return definition and definition.value ~= nil
end
function Spec.parse(angle_bracket_spec, template, data, lang)
local inside = mw.ustring.match(angle_bracket_spec, "^<(.*)>$")
local base = setmetatable({overrides = {}, indicators = {}, groups = {}, template = template, data = data,
lang = lang, text = angle_bracket_spec}, Spec)
if inside == "" then
return base
end
local segments = M.parse_utilities.parse_balanced_segment_run(inside, "[", "]")
for _, group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(segments, "%.")) do
local part = group[1]
if part == "" then
if #group == 1 then
spec_error("Empty indicator (two periods in a row, or a period at an end)", angle_bracket_spec)
end
base.footnotes = fetch_footnotes(group, angle_bracket_spec)
elseif template == "adjective" and mw.ustring.find(part, ":") and not takes_value(data, template, part)
or template ~= "adjective" and is_override(data, template, part) then
local slots, override
if template == "adjective" then
slots, override = Overrides.parseAdjective(group, angle_bracket_spec)
else
slots, override = Overrides.parse(group, angle_bracket_spec)
end
for _, slot in ipairs(slots) do
if base.overrides[slot] then
spec_error(("Two overrides for the slot '%s'"):format(slot), angle_bracket_spec)
end
base.overrides[slot] = override
end
else
if #group > 1 then
spec_error("A footnote can only follow an override or stand alone", angle_bracket_spec)
end
local name, value = mw.ustring.match(part, "^([^:]+):(.*)$")
name = name or part
local definition = indicator_definition(data, template, name)
if not definition then
local names = {}
for known in pairs(data.indicators[template]) do
table.insert(names, known)
end
table.sort(names)
spec_error(("Unrecognized indicator '%s'; the indicators are %s"):format(name, table.concat(names, ", ")),
angle_bracket_spec)
end
if definition.value and (value == nil or value == "") then
spec_error(("The indicator '%s' needs a value ('%s:...')"):format(name, name), angle_bracket_spec)
elseif not definition.value and value ~= nil then
spec_error(("The indicator '%s' takes no value"):format(name), angle_bracket_spec)
end
if base.indicators[name] ~= nil then
spec_error(("The indicator '%s' is given twice"):format(name), angle_bracket_spec)
end
local key = definition.group or name
if base.groups[key] then
spec_error(("The indicators '%s' and '%s' can't be used together"):format(base.groups[key], name),
angle_bracket_spec)
end
base.groups[key] = name
base.indicators[name] = value or true
end
end
return base
end
-- Return the value set by a group of indicators (e.g. "m" for `gender`), or nil if none of the group was given.
function Spec:group(group)
local name = self.groups[group]
if not name then
return nil
end
return indicator_definition(self.data, self.template, name).sets or name
end
------------------------------------------------------------------------------------------------------------------------
-- Stem --
------------------------------------------------------------------------------------------------------------------------
--[==[
Functions to find the stem of a lemma and apply the alternations of the language's data module to it.
]==]
local Stem = {}
-- Split a lemma into its stem and nominative ending. The ending is the first of the `nominative_endings` of its gender
-- (`m`, `f` or `n`, or `plural` for a plurale tantum) that the lemma ends in with something before it, unless the
-- ending is one of the gender's `nominative_after_consonant` and a vowel precedes it; if there's none, the lemma is its
-- own stem and the ending is empty.
function Stem.split(data, lemma, gender, plural)
local after_consonant = not plural and data.nominative_after_consonant[gender] or {}
for _, ending in ipairs(data.nominative_endings[plural and "plural" or gender]) do
local stem = mw.ustring.match(lemma, "^(.+)" .. ending .. "$")
if stem and not (after_consonant[ending] and mw.ustring.find(mw.ustring.sub(stem, -1), "[" .. data.vowels .. "]")) then
return stem, ending
end
end
return lemma, ""
end
-- Replace the last letters of `stem` according to `map`, trying the longest keys first (up to three letters). Return
-- nil if the stem ends in none of the keys.
local function replace_final(stem, map)
for _, length in ipairs({3, 2, 1}) do
if mw.ustring.len(stem) >= length then
local final = mw.ustring.sub(stem, -length)
if map[final] then
return mw.ustring.sub(stem, 1, -length - 1) .. map[final]
end
end
end
return nil
end
-- Remove the mobile vowel from `stem`, i.e. the first of the data's `mobile_vowels` that it has before its final
-- consonants. Return nil if it has none.
local function reduce(data, stem)
local vowels = data.vowels
for _, mobile in ipairs(data.mobile_vowels) do
local head, final = mw.ustring.match(stem, "^(.-)" .. mobile[1] .. "([^" .. vowels .. "]+)$")
if head and head ~= "" and not (mobile.after_consonant
and mw.ustring.find(mw.ustring.sub(head, -1), "[" .. vowels .. "]")) then
return (mobile.soften and replace_final(head, data[mobile.soften]) or head) .. final
end
end
return nil
end
-- Insert `vowel` before the last consonant of `stem`. Return nil if the stem doesn't end in two consonants.
local function insert(data, stem, vowel)
local vowels = data.vowels
local head, final = mw.ustring.match(stem, "^(.-[^" .. vowels .. "])([^" .. vowels .. "])$")
return head and head .. vowel .. final or nil
end
-- Change the vowel of the last syllable of `stem`, whose vowels are the letters of `vowels`, according to `map`
-- (`shorten`, `lengthen` or `front` in the data, or `clear` of a lect's paradigm). Return nil if that vowel isn't one
-- of the keys of `map`.
local function alternate(vowels, stem, map)
local letters = ""
for vowel in pairs(map) do
letters = letters .. vowel
end
local head, vowel, tail = mw.ustring.match(stem, "^(.*)([" .. letters .. "])([^" .. vowels .. "]*)$")
return head and head .. map[vowel] .. tail or nil
end
-- Return the stem that `label` names, which is either `plain` or a set of alternations joined with "+" (e.g.
-- `reduced+palatal`). Return nil if one of the alternations doesn't apply to `stem`.
function Stem.apply(data, stem, label)
local text = stem
for part in mw.text.gsplit(label, "+", true) do
if not text then
return nil
end
if part == "reduced" then
text = reduce(data, text)
elseif mw.ustring.find(part, "^inserted_") then
-- `inserted_VOWEL` puts the mobile vowel VOWEL in.
text = insert(data, text, mw.ustring.sub(part, 10))
elseif part == "truncated" then
text = replace_final(text, data.truncate)
elseif part == "spelled" then
text = replace_final(text, data.spelled)
elseif part == "shortened" then
text = alternate(data.vowels, text, data.shorten)
elseif part == "lengthened" then
text = alternate(data.vowels, text, data.lengthen)
elseif part == "fronted" then
text = alternate(data.vowels, text, data.front)
elseif part == "soft" or part == "final_soft" then
-- This is only a spelling, so leave the stem alone if it has no such letter.
text = replace_final(text, data[part]) or text
elseif part == "palatal" or part == "virile" then
text = replace_final(text, data[part])
elseif part == "irregular" then
text = ""
elseif part ~= "plain" then
error(("Internal error: unknown alternation '%s'"):format(part))
end
end
return text
end
------------------------------------------------------------------------------------------------------------------------
-- Noun rules --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the rules of one word's group, with the word's indicators applied. `NounRules.new(base)` finds the group
from the word's gender, kind, number and nominative ending, and `:forms(slot)` returns the forms of a slot by the rule
of the longest matching stem ending, as form objects `{form = ..., footnotes = {...}}`.
]==]
local NounRules = {}
NounRules.__index = NounRules
local function group_key(rule_gender, kind, plural, nominative)
return ("%s %s %s %s"):format(rule_gender, kind, plural and "pl" or "sg", nominative)
end
function NounRules.new(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy]
end
local plural = base.number == "pl"
-- A plurale tantum is either masculine personal (m-pr) or not, and the non-personal ones share the groups of the
-- neuter.
if plural and rule_gender ~= "m-pr" then
rule_gender = "n"
end
if not rule_gender then
spec_error(("The noun '%s' needs a gender (m, f or n)"):format(word), base.text)
end
local stem, nominative = Stem.split(data, word, rule_gender:sub(1, 1), plural)
local kind = base.kind or "common"
local group = data.noun_groups[group_key(rule_gender, kind, plural, nominative)]
or kind ~= "common" and data.noun_groups[group_key(rule_gender, "common", plural, nominative)]
if not group then
error(("No rules for %s nouns in -%s ('%s'); give the forms with overrides and <!>"):format(
rule_gender, nominative, word), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
used = {}, head_slot = plural and "nom_p" or "nom_s"}, NounRules)
end
-- Return the rule of `slot` for this stem, i.e. the rule of the longest stem ending (up to three letters) that has one.
function NounRules:rule(slot)
local rules = self.group.rules
for size = math.min(3, mw.ustring.len(self.stem)), 0, -1 do
local suffix = size == 0 and "" or mw.ustring.sub(self.stem, -size)
local by_slot = rules[suffix]
if by_slot and by_slot[slot] then
return by_slot[slot]
end
end
return nil
end
-- Return true if a part of an alternation label is about the mobile vowel, i.e. it's `reduced` or `inserted_VOWEL`.
local function is_mobile(part)
return part == "reduced" or mw.ustring.find(part, "^inserted_") ~= nil
end
-- Return the alternation label of an ending of a rule, with the word's indicators applied. `-*` takes out the mobile
-- vowel and `*` puts it in: for a lemma ending in a consonant it's dropped before an ending, and for one ending in a
-- vowel it's inserted into a bare stem (as `inserted_vowel` in the data says). `-#` and `#` do the same for ''ó''/''o''
-- and ''ą''/''ę''. A bare form of a lemma ending in a consonant is the lemma itself (e.g. the accusative of an
-- inanimate noun) and takes neither.
function NounRules:label(label, ending)
local base = self.base
local parts = {}
for part in mw.text.gsplit(label, "+", true) do
parts[part] = true
end
local mobile = false
for part in pairs(parts) do
mobile = mobile or is_mobile(part)
end
local consonant_final = self.nominative == ""
if base.reducible == false then
for part in pairs(parts) do
if is_mobile(part) then
parts[part] = nil
end
end
elseif base.reducible and not mobile then
if consonant_final and ending ~= "" then
parts.reduced = true
elseif ending == "" then
local inserted = self.data.inserted_vowel
parts["inserted_" .. (inserted.after[mw.ustring.sub(self.stem, -2, -2)] or inserted.default)] = true
end
end
if base.quantity == "none" then
parts.shortened, parts.lengthened = nil, nil
elseif base.quantity == "full" and not (parts.shortened or parts.lengthened) then
if consonant_final and ending ~= "" then
parts.shortened = true
elseif ending == "" then
parts.lengthened = true
end
end
-- Put the parts in the order they apply in, with the mobile vowel first.
local ordered = {}
if parts.reduced then
table.insert(ordered, "reduced")
end
local inserted = {}
for part in pairs(parts) do
if mw.ustring.find(part, "^inserted_") then
table.insert(inserted, part)
end
end
table.sort(inserted)
for _, part in ipairs(inserted) do
table.insert(ordered, part)
end
for _, name in ipairs({"truncated", "spelled", "shortened", "lengthened", "fronted", "soft", "final_soft", "palatal",
"virile", "irregular"}) do
if parts[name] then
table.insert(ordered, name)
end
end
return ordered[1] and table.concat(ordered, "+") or "plain"
end
-- Join a stem and an ending as the language spells them. A final soft consonant before a vowel is written with the
-- data's `soft_vowel`, which merges with the same vowel at the start of the ending (e.g. ''koń'' + ''-a'' → ''konia'',
-- ''goleń'' + ''-i'' → ''goleni'').
local function join(data, stem, ending)
if ending ~= "" and mw.ustring.find(mw.ustring.sub(ending, 1, 1), "[" .. data.vowels .. "]") then
local spelled = replace_final(stem, data.soft)
if spelled then
local vowel = data.soft_vowel
local length = mw.ustring.len(vowel)
return spelled .. (mw.ustring.sub(ending, 1, length) == vowel and mw.ustring.sub(ending, length + 1) or ending)
end
end
return stem .. ending
end
function NounRules:form(label, ending, note)
local footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil
-- An apostrophe keeps the lemma whole before the ending (''Google'' → ''Google'a'').
if mw.ustring.sub(ending, 1, 1) == "'" then
return {form = self.word .. ending, footnotes = footnotes}
end
local full = self:label(label, ending)
-- Note the alternations used, for the categories of the table.
for part in mw.text.gsplit(full, "+", true) do
self.used[part] = true
end
local stem = Stem.apply(self.data, self.stem, full) or self.stem
return {form = join(self.data, stem, ending), footnotes = footnotes}
end
-- Return the endings of a rule's cell as a list of `{ending, stem = ..., note = ...}`. A cell is an ending (a string),
-- one ending with a stem or note (e.g. `{ "e", stem = "palatal" }`), or a list of either (e.g. `{ "i", "ów" }`).
local function cell_endings(cell)
if type(cell) == "string" then
return {{cell}}
elseif type(cell[1]) == "string" and cell[2] == nil then
return {cell}
end
local list = {}
for _, ending in ipairs(cell) do
table.insert(list, type(ending) == "string" and {ending} or ending)
end
return list
end
-- Return the forms of `slot` according to its rule, or nil if the group has no rule for the slot.
function NounRules:forms(slot)
local cell = self:rule(slot)
if not cell then
return nil
end
local list = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(list, self:form(ending.stem or "plain", ending[1], ending.note))
end
return list
end
-- Return the alternation label for an ending given in an override of `slot`. If the ending is one of the rule's own
-- endings, use that ending's label; otherwise use the label of the rule's first ending minus the softening that its
-- ending brings (`palatal` before ''-e'', `virile` before the virile ''-i''/''-y''). This way ''dom'' with the locative
-- ''-u'' gives ''domu'', and ''Polak'' with the nominative plural ''-owie'' gives ''Polakowie''.
function NounRules:overrideLabel(slot, ending)
local cell = self:rule(slot)
local endings = cell and cell_endings(cell) or {}
for _, item in ipairs(endings) do
if item[1] == ending then
return item.stem or "plain"
end
end
local kept = {}
for part in mw.text.gsplit(endings[1] and endings[1].stem or "plain", "+", true) do
if part ~= "palatal" and part ~= "virile" and part ~= "irregular" and part ~= "plain" then
table.insert(kept, part)
end
end
return kept[1] and table.concat(kept, "+") or "plain"
end
--[==[
Object holding the rules of an adjective, with the methods of `NounRules`. The group comes from `adjective_groups`
according to the ending of the lemma (one of `adjective_nominatives`). Adjectives take no stem indicators.
]==]
local AdjectiveRules = setmetatable({}, {__index = NounRules})
AdjectiveRules.__index = AdjectiveRules
function AdjectiveRules.new(base, word)
local data = base.data
local stem, nominative, group
for _, ending in ipairs(data.adjective_nominatives) do
stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
if stem then
nominative = ending
group = data.adjective_groups["adj common sg " .. ending]
break
end
end
if not group then
local endings = {}
for _, ending in ipairs(data.adjective_nominatives) do
table.insert(endings, "-" .. ending)
end
error(("'%s' doesn't end in %s; an irregular adjective takes <irreg>"):format(word,
table.concat(endings, " or ")), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
head_slot = "nom_m", used = {}}, AdjectiveRules)
end
--[==[
Object holding the rules of a lect's paradigm, i.e. an entry of `lect_tables` with `table = "paradigm"`, such as
Standard Kurpie (`lect:skur`). The paradigm is the table in the data named by the entry's `rules`. Its `types` decide
the type of a lemma, and each type has one ending per slot. It answers the same calls from `decline_word` as
`NounRules`.
]==]
local ParadigmRules = {}
ParadigmRules.__index = ParadigmRules
-- Return the last consonant of a stem, which is either one of the data's `digraphs` or a single letter.
local function final_consonant(data, stem)
local last_two = mw.ustring.sub(stem, -2)
return data.digraphs[last_two] and last_two or mw.ustring.sub(stem, -1)
end
-- Return the stem, type and declension (the gender whose endings it takes) of a lemma in `paradigm`, decided by its
-- gender and ending (see `types` in the data). `name` is the name of the lect, for the error messages.
local function paradigm_type(data, paradigm, name, word, gender, text)
for _, entry in ipairs(gender and paradigm.types[gender] or {}) do
local stem = entry.ending == "" and word or mw.ustring.match(word, "^(.+)" .. entry.ending .. "$")
if stem and not (entry.consonant_final and mw.ustring.find(word, "[" .. paradigm.vowels .. "]$")) then
local final = final_consonant(data, stem)
for _, class in ipairs(entry.by_final or {}) do
if paradigm[class[1]][final] then
return stem, class[2], entry.declension or gender
end
end
return stem, entry.default, entry.declension or gender
end
end
spec_error(("The %s rules have no %s noun like '%s'; give its forms as overrides"):format(name,
gender and M.data.genders[gender].name or "genderless", word), text)
end
-- Return `stem` with the slanted vowel of its last syllable made clear by the `clear` table of `paradigm`, or by
-- `clear_before_nasal` when one of its `nasals` follows the vowel. Return nil if that vowel isn't slanted.
local function clear_vowel(paradigm, stem)
local vowels = paradigm.vowels
local following = mw.ustring.match(stem, "[" .. vowels .. "]([^" .. vowels .. "]?)[^" .. vowels .. "]*$")
local before_nasal = paradigm.nasals and paradigm.nasals[following] and paradigm.clear_before_nasal
return alternate(vowels, stem, before_nasal or paradigm.clear)
end
function ParadigmRules.new(base, word, paradigm, name)
local data = base.data
local plural = base.number == "pl"
local stem, type, declension
if plural then
-- A plurale tantum is declined from its nominative plural, with the plural endings of its gender's hard stems.
if not paradigm.plural_nominatives then
spec_error(("The %s rules have no pluralia tantum"):format(name), base.text)
end
for _, ending in ipairs(paradigm.plural_nominatives) do
stem = stem or mw.ustring.match(word, "^(.+)" .. ending .. "$")
end
if not stem then
spec_error(("The %s rules have no plurale tantum like '%s'"):format(name, word), base.text)
end
type, declension = "hard", base.gender or "n"
else
stem, type, declension = paradigm_type(data, paradigm, name, word, base.gender, base.text)
end
local consonant_final = not plural and stem == word
if declension == "m" and base.animacy ~= "inan" and paradigm.animate_types and paradigm.animate_types[type] then
type = paradigm.animate_types[type]
end
if base.reducible then
stem = reduce(data, stem) or spec_error(("The stem '%s' has no mobile e"):format(stem), base.text)
end
-- With `#`, the forms with an ending have the clear vowel of `clear_stem`.
local clear_stem
if base.quantity == "none" then
spec_error(("The %s rules have no vowel alternation for '-#' to remove"):format(name), base.text)
elseif base.quantity == "full" then
if not paradigm.clear then
spec_error(("The %s rules have no vowel alternation for '#'"):format(name), base.text)
elseif not consonant_final then
spec_error(("In the %s rules, '#' needs a lemma that ends in a consonant"):format(name), base.text)
end
clear_stem = clear_vowel(paradigm, stem)
or spec_error(("The stem '%s' has no slanted vowel for '#' to make clear"):format(stem), base.text)
end
local endings = paradigm.nouns[declension][type]
if plural then
local plural_endings = {}
for slot, ending in pairs(endings) do
if mw.ustring.find(slot, "_p$") then
plural_endings[slot] = ending
end
end
endings = plural_endings
end
local copies = {}
for slot, source in pairs(paradigm.copies[declension]) do
copies[slot] = source
end
if base.gender == "m" then
for slot, source in pairs(paradigm.animate_copies[base.animacy]) do
copies[slot] = source
end
end
return setmetatable({base = base, data = data, paradigm = paradigm, word = word, stem = stem, clear_stem = clear_stem,
endings = endings, group = {copies = copies}, head_slot = plural and "nom_p" or "nom_s"}, ParadigmRules)
end
-- Return one form: the stem (with its clear vowel before an ending, under `#`), palatalized if `label` is `palatal` (by
-- the paradigm's own `palatal` table), followed by the ending. After a hardened consonant, the first letter of the
-- ending is respelled by `hardened_spelling`.
function ParadigmRules:form(label, ending, note)
local paradigm = self.paradigm
local stem = self.clear_stem and ending ~= "" and self.clear_stem or self.stem
if label == "palatal" then
local last_two = mw.ustring.sub(stem, -2)
if paradigm.palatal[last_two] then
stem = mw.ustring.sub(stem, 1, -3) .. paradigm.palatal[last_two]
else
stem = mw.ustring.sub(stem, 1, -2) .. (paradigm.palatal[mw.ustring.sub(stem, -1)] or mw.ustring.sub(stem, -1))
end
end
if paradigm.hardened and paradigm.hardened[final_consonant(self.data, stem)] then
local respelled = paradigm.hardened_spelling and paradigm.hardened_spelling[mw.ustring.sub(ending, 1, 1)]
if respelled then
ending = respelled .. mw.ustring.sub(ending, 2)
end
end
return {form = stem .. ending, footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil}
end
function ParadigmRules:forms(slot)
local cell = self.endings[slot]
if not cell then
return {}
end
if type(cell) == "string" then
return {self:form("plain", cell)}
end
return {self:form(cell.stem or "plain", cell[1], cell.note)}
end
-- Return the stem label of a slot's rule. An ending given for the slot in an override goes on that stem.
function ParadigmRules:overrideLabel(slot)
local cell = self.endings[slot]
return type(cell) == "table" and cell.stem or "plain"
end
------------------------------------------------------------------------------------------------------------------------
-- Declension --
------------------------------------------------------------------------------------------------------------------------
-- Return the forms of a noun from the lexicon (`<irreg>`) or of an indeclinable noun (`<indecl>`).
local function lexicon_forms(base, word)
local forms = {}
if base.indicators.irreg then
local list = base.data.irregular_nouns[word]
if not list then
error(("'%s' is not one of the irregular nouns"):format(word), 0)
end
for i, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = list[i]}}
end
elseif base.indicators.indecl then
for _, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = word}}
end
end
return forms
end
-- Return the masculine nominative singular of an adjectival word given in another gender, using `adjective_lemma` in
-- the data, e.g. ''teściowa'' → ''teściowy'', ''tania'' → ''tani'', ''bykowe'' → ''bykowy'', ''wielkie'' →
-- ''wielki''. A plural such as ''Zjednoczone'' works the same way.
local function adjective_lemma(data, word, rule_gender, plural)
local lemma = data.adjective_lemma
for _, ending in ipairs(lemma.endings[plural and "plural" or rule_gender] or {}) do
local stem = mw.ustring.match(word, "^(.+)" .. ending[1] .. "$")
if stem then
return stem .. ((ending.soft or lemma.soft_after[mw.ustring.sub(stem, -1)]) and lemma.soft or lemma.hard)
end
end
return word
end
--[==[
Return the masculine nominative singular that goes with a virile plural, e.g. ''krewni'' → ''krewny'', ''polscy'' →
''polski''. We try each word that the data's `palatal` table could have softened into the plural (before one of the
`virile_endings`) and return the one whose virile nominative plural, as the adjective rules give it, is that plural.
Return {nil} if there's none.
]==]
local function virile_lemma(data, word)
local adjective = {indicators = {}, overrides = {}, data = data}
for final, softened in pairs(data.palatal) do
for _, ending in ipairs(data.virile_endings) do
local stem = mw.ustring.match(word, "^(.+)" .. softened .. ending .. "$")
if stem then
for _, nominative in ipairs(data.adjective_nominatives) do
local lemma = stem .. final .. nominative
local ok, rules = pcall(AdjectiveRules.new, adjective, lemma)
if ok then
for _, form in ipairs(rules:forms("nom_mp_pers")) do
if form.form == word then
return lemma
end
end
end
end
end
end
end
return nil
end
-- Return the forms of an adjective in a lect's paradigm (`lect:skur`): the endings of the paradigm's `adjective` added
-- to the lemma minus its last letter, with the slots shared as for every adjective (`adjective_shared` in the data).
local function paradigm_adjective_forms(data, paradigm, word)
local stem = mw.ustring.sub(word, 1, -2)
local forms = {nom_m = {{form = word}}}
for slot, ending in pairs(paradigm.adjective) do
forms[slot] = {{form = stem .. ending}}
end
for source, targets in pairs(data.adjective_shared) do
for _, target in ipairs(targets) do
forms[target] = forms[source]
end
end
return forms
end
-- Return the forms of an adjectival word (`+`) in a lect's paradigm (`lect:skur`), in noun slots. Its masculine comes from
-- the word as given: the word minus the paradigm's nominative ending for its gender and number, with ''-ï'' after one of
-- the paradigm's `adjective_soft` consonants and ''-y'' otherwise.
local function paradigm_adjectival_forms(base, word, rule_gender, plural)
local data = base.data
local paradigm = data[base.lect_table.rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
local masculine = word
if plural or rule_gender == "f" or rule_gender == "n" then
local ending = paradigm.adjective[plural and (rule_gender == "m-pr" and "nom_mp_pers" or "nom_p_not_mp_pers")
or "nom_" .. rule_gender]
local stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
or spec_error(("The adjectival word '%s' doesn't end in -%s"):format(word, ending), base.text)
masculine = stem .. (paradigm.adjective_soft and paradigm.adjective_soft[final_consonant(data, stem)] and "ï" or "y")
end
local adjective = paradigm_adjective_forms(data, paradigm, masculine)
for _, pair in ipairs(data.adjective_accusatives) do
adjective[pair[2]] = adjective[pair[2]] or adjective[pair[1]]
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = adjective[adjective_slot] or {}
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = adjective[adjective_slot] or {}
end
end
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
-- Return the forms of an adjectival word (`+`) in noun slots, using `adjectival_slots` in the data.
local function adjectival_forms(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy or "inan"]
end
local plural = base.number == "pl"
if base.lect_table and base.lect_table.table == "paradigm" then
return paradigm_adjectival_forms(base, word, rule_gender, plural)
end
local lemma = plural and rule_gender == "m-pr" and virile_lemma(data, word) or adjective_lemma(data, word, rule_gender, plural)
local adjective = {lemma = lemma, indicators = {}, overrides = {}, data = data}
local rules = AdjectiveRules.new(adjective, adjective.lemma)
local function forms_of(slot)
if slot == "nom_m" then
return {{form = adjective.lemma}}
end
local source = rules.group.copies[slot]
while source and rules.group.copies[source] do
source = rules.group.copies[source]
end
if source == "nom_m" then
return {{form = adjective.lemma}}
end
return rules:forms(source or slot) or {}
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = forms_of(adjective_slot)
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = forms_of(adjective_slot)
end
end
-- The word as given heads its table.
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
--[==[
Resolve the lect of a `lect:` indicator or a `[lect:CODE:PLACE]` tag through the aliases in the data module of the lects
(`lect_module` in the language's data, which is [[Module:zlw-lch-IPA/data/pl]] for Polish). Return the code and the
name of the lect.
]==]
local function lect_of(data, code, text)
local lects = mw.loadData(data.lect_module)
code = lects.lect_aliases[code] or code
local lect = lects.lects[code]
if not lect then
local codes = {}
for known in pairs(lects.lects) do
table.insert(codes, known)
end
table.sort(codes)
spec_error(("Unrecognized lect '%s'; the lects are %s"):format(code, table.concat(codes, ", ")), text)
end
return code, lect.name
end
-- Return a footnote `[lect:CODE]` or `[lect:CODE:PLACE]` of a word of `base` as it's shown, with the name of the lect
-- formatted as its label is (linked to the article on the dialect) and the place. Return nil if the footnote isn't a
-- lect tag.
local function lect_footnote(base, footnote)
local code, place = mw.ustring.match(footnote, "^%[lect:([^:%]]+):?(.-)%]$")
if not code then
return nil
end
local _, name = lect_of(base.data, code, base.text)
local label = M.labels.get_label_info{label = name, lang = base.lang, nocat = true}.label
return "[" .. label .. (place ~= "" and " (" .. place .. ")" or "") .. "]"
end
-- Return the link target of a form of an attested lect, i.e. its modern spelling according to `respelling` (e.g.
-- ''ptåka'' → ''ptaka''). Return nil if it's spelled the same.
local function respelled(respelling, form)
local target = mw.ustring.gsub(form, ".", respelling)
return target ~= form and target or nil
end
-- Return a `generate_link` function for `show_forms` for the table of `spec`, which links a respelled form (one with a
-- `target`) to its modern spelling.
local function respelled_link(spec)
return function(data)
if data.form.target then
return M.links.full_link{lang = spec.lang, term = data.form.target, alt = data.form.formval_for_link,
tr = "-"} .. M.inflection_utilities.get_footnote_text(data.form.footnotes, data.footnote_obj)
end
end
end
--[==[
Return the forms of an attested table (Middle Polish `lect:mpl`, the `dialectal` table and every Old Polish table),
which are the cells given, exactly as given, and nothing else. In a dialectal table, every form must have a lect,
either from its own `[lect:...]` tag or from a tag given for the whole word.
]==]
local function attested_forms(base)
local forms = {}
local word_lect
local word_footnotes = {}
for _, note in ipairs(base.footnotes or {}) do
local shown = lect_footnote(base, note)
word_lect = word_lect or shown
table.insert(word_footnotes, shown or note)
end
-- the forms with a lect tag of their own, which the lect tag of the word doesn't go on
local own_lect = {}
local respelling = base.lect_table and base.lect_table.respelling and base.data[base.lect_table.respelling]
for slot, override in pairs(base.overrides) do
if not override.full then
spec_error(("An attested table takes whole forms: '%s:FORM'"):format(slot), base.text)
end
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
local footnotes, lect = {}, nil
for _, note in ipairs(value.footnotes or {}) do
local shown = lect_footnote(base, note)
lect = lect or shown
table.insert(footnotes, shown or note)
end
if base.indicators.dialectal then
if not lect and not word_lect then
spec_error(("The dialectal form '%s' needs [lect:CODE]"):format(value.form), base.text)
end
end
local form = {
form = value.form,
target = respelling and respelled(respelling, value.form) or nil,
footnotes = footnotes[1] and footnotes or nil,
}
own_lect[form] = lect and true or nil
table.insert(list, form)
end
end
forms[slot] = list
end
if base.footnotes then
base.footnotes, base.word_lect, base.own_lect = word_footnotes, word_lect, own_lect
end
return forms
end
-- Return the entry of a pronoun in the data's `pronouns` along with the ending its forms take. This is the lemma's own
-- entry (with no ending), or the entry of the pronoun it's made from plus one of the `pronoun_suffixes` (e.g.
-- ''cośkolwiek'' is ''co'' plus ''-śkolwiek'').
local function pronoun_entry(data, lemma)
local pronouns = data.pronouns
if pronouns[lemma] then
return pronouns[lemma], ""
end
for _, suffix in ipairs(data.pronoun_suffixes or {}) do
local head = mw.ustring.match(lemma, "^(.+)" .. suffix .. "$")
if head and pronouns[head] then
return pronouns[head], suffix
end
end
return nil
end
-- Return the forms of a pronoun (`<pron>`) with their notes. In an attested table (Old Polish), the forms given in the
-- spec go on top of them.
local function pronoun_forms(base, word)
local data = base.data
local pronoun, suffix = pronoun_entry(data, word)
if not pronoun then
local lemmas = {}
for lemma in pairs(data.pronouns) do
table.insert(lemmas, lemma)
end
table.sort(lemmas)
local message = ("No pronoun '%s'; the pronouns are %s"):format(word, table.concat(lemmas, ", "))
if data.pronoun_suffixes then
local suffixes = {}
for _, item in ipairs(data.pronoun_suffixes) do
table.insert(suffixes, "-" .. item)
end
message = message .. ", and these with " .. table.concat(suffixes, ", ")
end
spec_error(message, base.text)
end
base.pronoun = pronoun
local forms = {}
for slot, list in pairs(pronoun) do
if slot ~= "numbers" and slot ~= "numberless" then
forms[slot] = {}
for _, item in ipairs(list) do
local form = {form = (type(item) == "table" and item[1] or item) .. suffix}
if type(item) == "table" then
form.footnotes = {}
for _, note in ipairs(item.notes) do
table.insert(form.footnotes, "[" .. data.notes[note] .. "]")
end
end
table.insert(forms[slot], form)
end
end
end
if base.attested then
for slot, list in pairs(attested_forms(base)) do
forms[slot] = list
end
end
return forms
end
-- Return the rule of a numeral in `rules` (`numeral_rules` or `collective_rules` in the data), i.e. the rule of the
-- longest key that the lemma ends in, along with the lemma minus that key.
local function numeral_rule(rules, word, text)
for length = mw.ustring.len(word), 0, -1 do
local key = length == 0 and "" or mw.ustring.sub(word, -length)
if rules[key] then
return rules[key], mw.ustring.sub(word, 1, mw.ustring.len(word) - length)
end
end
spec_error(("No numeral declines like '%s'"):format(word), text)
end
-- Return the forms of a numeral (`<num>`), i.e. the endings of its rule added to its stem.
local function numeral_forms(rules, base, word)
local rule, stem = numeral_rule(rules, word, base.text)
local forms = {}
for slot, cell in pairs(rule) do
forms[slot] = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(forms[slot], {form = stem .. ending[1],
footnotes = ending.note and {"[" .. base.data.notes[ending.note] .. "]"} or nil})
end
end
return forms
end
--[==[
Add the footnotes given for the whole word (`base.footnotes`) after the footnotes of every form, as new form objects,
since a copied slot shares the form objects of its source. In an attested table the word's lect tag
(`base.word_lect`) only goes on the forms without a lect tag of their own (`base.own_lect`). Return the forms.
]==]
local function add_word_footnotes(base, forms)
if not base.footnotes then
return forms
end
for slot, list in pairs(forms) do
local copy = {}
for _, form in ipairs(list) do
local footnotes = {}
for _, note in ipairs(form.footnotes or {}) do
table.insert(footnotes, note)
end
for _, note in ipairs(base.footnotes) do
if not (note == base.word_lect and base.own_lect[form]) then
table.insert(footnotes, note)
end
end
table.insert(copy, {form = form.form, footnotes = footnotes, target = form.target})
end
forms[slot] = copy
end
return forms
end
--[==[
Decline a single word. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]]. First the
rules fill every slot they cover. Then the overrides apply (an ending goes on the stem that the slot's rule uses, and a
form replaces the cell), followed by the copies (unless a copy is overridden itself), the deprecative forms of a
masculine personal noun (after its nominative plural, with a footnote) and finally the footnote for the whole word.
]==]
local function decline_word(base)
local word = base.indicators.decllemma or base.lemma
local forms, rules
if base.attested then
base.forms = add_word_footnotes(base, base.indicators.pron and pronoun_forms(base, word) or attested_forms(base))
return
elseif base.indicators.pron then
forms = pronoun_forms(base, word)
elseif base.indicators.num then
forms = numeral_forms(base.data.collective_rules, base, word)
elseif base.indicators.irreg or base.indicators.indecl then
forms = lexicon_forms(base, word)
elseif base.indicators["!"] then
-- A manual table has only the forms its overrides give.
forms = {}
elseif base.indicators["+"] then
forms = adjectival_forms(base, word)
else
rules = base.lect_table and base.lect_table.table == "paradigm"
and ParadigmRules.new(base, word, base.data[base.lect_table.rules], base.lect_name) or NounRules.new(base, word)
-- The lemma heads the table, even when another word is declined in its place (`decllemma`).
forms = {[rules.head_slot] = {{form = base.lemma}}}
-- The rules give the singular and the plural; only an attested table has the dual.
for _, entry in ipairs(M.data.noun_slots) do
local slot = entry.slot
if entry.number ~= "d" and slot ~= rules.head_slot and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
-- A form that is the declined word itself (e.g. an inanimate accusative) belongs to the lemma.
for _, form in ipairs(forms[slot] or {}) do
if form.form == word then
form.form = base.lemma
end
end
end
end
-- In a phrase the deprecative forms would agree with nothing (''pany młodzi''), so only a single word shows
-- them.
if not base.in_phrase then
forms.depr_p = rules:forms("depr_p")
end
end
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.default then
for _, form in ipairs(rules and rules:forms(slot) or {}) do
table.insert(list, form)
end
elseif override.full then
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
else
local form = rules and rules:form(rules:overrideLabel(slot, value.form), value.form) or {form = word .. value.form}
form.footnotes = value.footnotes
table.insert(list, form)
end
end
forms[slot] = list
end
if rules then
-- A copy can copy another copy (e.g. the vocative of a feminine consonant-stem noun is its locative, which is
-- its dative). Fill each one from the slot at the end of its chain, unless a slot along the way is overridden.
local copies = rules.group.copies
for slot in pairs(copies) do
if not base.overrides[slot] then
local source = copies[slot]
while copies[source] and not base.overrides[source] do
source = copies[source]
end
local list = {}
for _, form in ipairs(forms[source] or {}) do
table.insert(list, form)
end
forms[slot] = list
end
end
end
if forms.depr_p then
forms.nom_p = forms.nom_p or {}
-- A deprecative form that's the same as a virile form (e.g. ''zaklinacze'') isn't a separate form, so don't
-- show it twice.
local virile = {}
for _, form in ipairs(forms.nom_p) do
virile[form.form] = true
end
for _, form in ipairs(forms.depr_p) do
if not virile[form.form] then
table.insert(forms.nom_p, {form = form.form, footnotes = form.footnotes or {"[" .. base.data.notes.deprecative .. "]"}})
end
end
forms.depr_p = nil
end
base.forms = add_word_footnotes(base, forms)
-- Keep the rules the forms came from, and the alternations they used, for the categories.
base.rules = rules
end
-- Join an adjective stem and an ending. If the data's `adjective_dropped` says the last letter of the stem drops before
-- the first letter of the ending, drop it (e.g. ''moj-'' + ''-ich'' → ''moich'').
local function adjective_form(data, stem, ending)
local before = data.adjective_dropped[mw.ustring.sub(stem, -1)]
if before and mw.ustring.sub(ending, 1, mw.ustring.len(before)) == before then
return mw.ustring.sub(stem, 1, -2) .. ending
end
return stem .. ending
end
-- Return the forms of an irregular adjective from `irregular_adjectives`, along with the layout of the table it needs
-- (nil, `dwa` or `plonly`).
local function irregular_adjective_forms(base, word)
local data = base.data
for _, entry in ipairs(data.irregular_adjectives) do
local captured = mw.ustring.match(word, entry.pattern)
if captured or entry.stem and mw.ustring.find(word, entry.pattern) then
local forms = {}
local function add(slot, stem, endings, note)
if type(endings) == "string" then
endings = {endings}
end
for _, ending in ipairs(endings or {}) do
forms[slot] = forms[slot] or {}
local form = ending == "-" and base.lemma or adjective_form(data, stem, ending)
table.insert(forms[slot], {form = form, footnotes = note and {"[" .. note .. "]"} or nil})
end
end
if entry.table ~= "dwa" then
add("nom_m", nil, "-")
end
for _, set in ipairs(entry.sets) do
local stem = (entry.stem or captured) .. (set.add or "")
for slot, endings in pairs(set.endings or {}) do
add(slot, stem, endings, set.note)
for _, target in ipairs(data.adjective_shared[slot] or {}) do
add(target, stem, endings, set.note)
end
end
for slot, endings in pairs(set.own or {}) do
add(slot, stem, endings, set.note)
end
if set.archaic_dative and base.indicators.archdat then
add("dat_mn", stem, set.archaic_dative, data.notes[data.archaic_dative.note])
end
end
return forms, entry.table
end
end
error(("Unrecognized irregular adjective '%s'"):format(word), 0)
end
--[==[
Decline a single adjective. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]] for
{{tl|pl-adecl}}. The rules (or the lexicon of irregular adjectives) fill the slots; then the overrides apply, followed
by the accusatives taken from other slots (unless overridden) and the footnote for the whole word. An attested table
has the cells given and nothing else.
]==]
local function decline_adjective_word(base)
local data = base.data
local word = base.indicators.decllemma or base.lemma
local forms, layout
if base.attested then
-- The cells given and nothing else, with the dual columns if `du` is given.
forms, layout = attested_forms(base), base.indicators.du and "dual" or nil
elseif base.indicators.irreg then
forms, layout = irregular_adjective_forms(base, word)
elseif base.indicators.lect then
local paradigm = data[data.lect_tables[base.indicators.lect].rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
forms = paradigm_adjective_forms(data, paradigm, word)
-- With `decllemma`, the lemma itself heads the table (''båbcyn'' declined as ''båbcyny'').
forms.nom_m = {{form = base.lemma}}
elseif base.indicators.num then
forms, layout = numeral_forms(data.numeral_rules, base, word), "plonly"
else
local rules = AdjectiveRules.new(base, word)
-- With `decllemma`, the lemma itself still heads the table (''wart'' declined as ''warty'').
forms = {nom_m = {{form = base.lemma}}}
for _, slot in ipairs(data.adjective_slots) do
if slot ~= "nom_m" and slot ~= "short" and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
end
end
if base.indicators.archdat then
local archaic = data.archaic_dative
table.insert(forms.dat_mn, {form = rules.stem .. archaic[1], footnotes = {"[" .. data.notes[archaic.note] .. "]"}})
end
-- Keep the slots that every adjective shares as copies, so that an override of the source carries over.
for slot, source in pairs(rules.group.copies) do
local accusative = mw.ustring.find(slot, "^acc")
if not accusative and not base.overrides[slot] then
forms[slot] = forms[source]
end
end
end
if not base.attested then
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
end
forms[slot] = list
end
for _, pair in ipairs(data.adjective_accusatives) do
local source, target = pair[1], pair[2]
if not base.overrides[target] and forms[source] and not (base.indicators.irreg and forms[target]) then
forms[target] = forms[source]
end
end
end
base.forms = add_word_footnotes(base, forms)
base.layout = layout
end
-- Return the attested tables there are for `template` (`noun` or `adjective`), for the error messages: those of the
-- language's attested lects and its dialectal table, plus the templates of the languages whose tables of that kind are
-- all attested.
local function attested_tables(data, template)
local tables = {}
local codes = {}
for code, lect_table in pairs(data.lect_tables or {}) do
if lect_table.table == "attested" then
table.insert(codes, code)
end
end
table.sort(codes)
for _, code in ipairs(codes) do
table.insert(tables, "<lect:" .. code .. ">")
end
if data.indicators[template].dialectal then
table.insert(tables, "<dialectal>")
end
local languages = {}
for code, language in pairs(M.data.languages) do
if language[template] then
table.insert(languages, code)
end
end
table.sort(languages)
for _, code in ipairs(languages) do
if mw.loadData("Module:zlw-lch-decl/data/" .. code).attested then
table.insert(tables, "{{" .. M.data.languages[code][template] .. "}}")
end
end
return table.concat(tables, ", ")
end
-- Work out the table a base is for: its lect (`lect:CODE`), and whether the table is attested, i.e. has only the cells
-- given (for an attested lect, the dialectal table, or a language whose tables are all attested). Throw an error if
-- `recon` or `du` is given for a table that isn't attested, if a lect tag appears outside the dialectal table, or if a
-- dual slot is given without `du`.
local function resolve_table(base)
local data = base.data
if base.indicators.lect then
base.indicators.lect, base.lect_name = lect_of(data, base.indicators.lect, base.text)
base.lect_table = data.lect_tables[base.indicators.lect]
if not base.lect_table then
local codes = {}
for code in pairs(data.lect_tables) do
table.insert(codes, code)
end
table.sort(codes)
spec_error(("The lect '%s' has no table of its own (the lects with one are %s); give its forms in a "
.. "<dialectal> table"):format(base.indicators.lect, table.concat(codes, ", ")), base.text)
end
end
base.attested = data.attested or base.indicators.dialectal
or base.lect_table and base.lect_table.table == "attested" or nil
for _, name in ipairs({"recon", "du"}) do
if base.indicators[name] and not base.attested then
spec_error(("Only an attested table (%s) takes '%s'"):format(attested_tables(data, base.template), name),
base.text)
end
end
-- A form of a lect can only be tagged in the dialectal table, so that none ends up among the standard forms.
if not base.indicators.dialectal then
local function check(footnotes)
for _, footnote in ipairs(footnotes or {}) do
if mw.ustring.find(footnote, "^%[lect:") then
spec_error(("A lect's form (%s) belongs in a <dialectal> table"):format(footnote), base.text)
end
end
end
check(base.footnotes)
for _, override in pairs(base.overrides) do
for _, value in ipairs(override.values) do
check(value.footnotes)
end
end
end
if not base.indicators.du then
for slot in pairs(base.overrides) do
if mw.ustring.find(slot, "_d$") then
spec_error(("The dual slot '%s' needs the indicator 'du'"):format(slot), base.text)
end
end
end
end
-- Set the fields of a base that the rules use, based on its indicators.
local function normalize_base(base)
base.gender = base:group("gender")
base.animacy = base:group("animacy")
base.number = base:group("number")
base.kind = base:group("kind")
if base.indicators["*"] then
base.reducible = true
elseif base.indicators["-*"] then
base.reducible = false
end
base.quantity = base.indicators["#"] and "full" or base.indicators["-#"] and "none" or nil
if base.gender == "m" and not base.animacy then
base.animacy = "inan"
end
resolve_table(base)
end
------------------------------------------------------------------------------------------------------------------------
-- Output --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object to render the declined words as a table with [[Module:inflection-table]], with a column for each number shown and
a row for each case. Each row has a `data-case` attribute so that scripts can reorder the cases. The cells come from
`show_forms` in [[Module:inflection utilities]], linked with accelerators for the lemma, and the footnotes go under the
table.
]==]
local TableRenderer = {}
TableRenderer.__index = TableRenderer
function TableRenderer.new(spec)
return setmetatable({spec = spec}, TableRenderer)
end
function TableRenderer:numbers()
local numbers = {}
for _, number in ipairs(M.data.numbers) do
if self.spec.numbers[number.code] then
table.insert(numbers, number)
end
end
return numbers
end
-- Return the title of a table: `title=` if given, otherwise what the table is (e.g. "Declension of " or "Attested
-- Middle Polish forms of ") followed by its head, unlinked. `suffix` follows the default title (`default_kind` and the
-- lemma), e.g. the declension kinds of an adjective.
function TableRenderer:title(default_kind, suffix)
local spec = self.spec
if spec.title then
return spec.title
end
local kind, head = default_kind, spec.forms.lemma
if spec.kind_title then
kind, head, suffix = spec.kind_title[1], spec.kind_title[2] or head, nil
end
return kind .. M.links.full_link({lang = spec.lang, alt = head}, "term") .. (suffix or "")
end
-- Return the first lines of a table titled `title`: the frame from [[Module:inflection-table]], with its first row
-- opened.
function TableRenderer:top(title)
return {M.inflection_table.make_top{
title = title,
palette = "blue",
tall = "yes",
lang = self.spec.lang:getCode(),
}}
end
-- Close the table in `lines` with its footnotes and categories, and return its wikitext.
function TableRenderer:finish(lines)
local spec = self.spec
table.insert(lines, M.inflection_table.make_bottom{notes = spec.forms.footnote or ""})
if spec.categories[1] and not spec.nocat then
table.insert(lines, M.utilities.format_categories(spec.categories, spec.lang))
end
return table.concat(lines, "\n")
end
function TableRenderer:render()
local spec = self.spec
local numbers = self:numbers()
local slot_list = {}
for _, case in ipairs(M.data.cases) do
for _, number in ipairs(numbers) do
-- A table with one number doesn't name it in its accelerators, and an attested or lect table has none
-- ("-").
local accel = (spec.attested or spec.lect) and "-" or #numbers > 1 and case.accel .. "|" .. number.accel or case.accel
table.insert(slot_list, {case.code .. "_" .. number.code, accel})
end
end
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
-- A Middle Polish form links to its modern spelling.
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của "))
-- make_top has already opened the first row.
table.insert(lines, '! class="outer" |')
for _, number in ipairs(numbers) do
-- A numberless pronoun (e.g. ''siebie'') has an empty header over its one column.
table.insert(lines, '! class="outer" | ' .. (spec.numberless and "" or number.name))
end
for _, case in ipairs(M.data.cases) do
table.insert(lines, ('|- data-case="%s"'):format(case.code))
table.insert(lines, ('! title="%s" | %s'):format(spec.data.case_titles[case.code], case.name))
for _, number in ipairs(numbers) do
local cell = spec.forms[case.code .. "_" .. number.code]
table.insert(lines, "| " .. (cell or "—"))
end
end
return self:finish(lines)
end
--[==[
The rows of an adjective table, by layout. Each row is a case and its cells, and each cell is a slot and the number of
columns it spans. The regular table has the masculine animate, masculine inanimate, feminine and neuter singular, then
the virile and non-virile plural, as in the former [[Module:pl-adjective]]. The dual table (an attested table with `du`)
puts the dual, masculine and feminine/neuter, between them.
]==]
local ADJECTIVE_LAYOUTS = {
regular = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_mp_pers"},
{"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_p", 2}}},
},
},
plonly = {
columns = {
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_p", 2}}},
{"dat", "dative", {{"dat_p", 2}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_p", 2}}},
{"loc", "locative", {{"loc_p", 2}}},
},
},
-- an attested table with the dual (`du`), between the singular and the plural
dual = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"dual", 2, {"masculine", "feminine/<wbr />neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_m_d"}, {"nom_fn_d"},
{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_d", 2}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_d", 2}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_m_d"}, {"acc_fn_d"},
{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_d", 2}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_d", 2}, {"loc_p", 2}}},
},
},
dwa = {
columns = {
{"plural", 4, {"masculine personal", "masculine non-personal", "feminine", "neuter"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_mp_npers"}, {"nom_fp"}, {"nom_np"}}},
{"gen", "genitive", {{"gen_p", 4}}},
{"dat", "dative", {{"dat_p", 4}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_mp_npers"}, {"acc_fp"}, {"acc_np"}}},
{"ins", "instrumental", {{"ins_mnp", 2}, {"ins_fp"}, {"ins_mnp"}}},
{"loc", "locative", {{"loc_p", 4}}},
},
},
}
function TableRenderer:renderAdjective()
local spec = self.spec
local layout = ADJECTIVE_LAYOUTS[spec.layout]
local slot_list = {}
for slot, accel in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, (spec.lect or spec.attested) and "-" or accel})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của ",
spec.kinds[1] and " (" .. table.concat(spec.kinds, " // ") .. ")" or nil))
-- make_top has already opened the first row. Add the number headers, then the gender headers.
table.insert(lines, '! class="outer" rowspan="2" |')
for _, column in ipairs(layout.columns) do
table.insert(lines, ('! class="outer" colspan="%d" | %s'):format(column[2], column[1]))
end
table.insert(lines, "|- class=\"secondary\"")
for _, column in ipairs(layout.columns) do
for _, header in ipairs(column[3]) do
table.insert(lines, "! " .. header)
end
end
for _, row in ipairs(layout.rows) do
table.insert(lines, ('|- data-case="%s"'):format(row[1]))
table.insert(lines, "! " .. row[2])
for _, cell in ipairs(row[3]) do
local span = cell[2] and ('colspan="%d" | '):format(cell[2]) or ""
table.insert(lines, "| " .. span .. (spec.forms[cell[1]] or "—"))
end
end
if spec.forms.short and spec.forms.short ~= "—" then
table.insert(lines, '|- data-case="short"')
table.insert(lines, "! short")
table.insert(lines, '| colspan="2" | ' .. spec.forms.short)
end
return self:finish(lines)
end
------------------------------------------------------------------------------------------------------------------------
-- The call --
------------------------------------------------------------------------------------------------------------------------
--[==[
Decline a noun call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl` or `zlw-opl`). Return the
alternant multiword spec from [[Module:inflection utilities]], with the fields `forms` (a table mapping each slot to a
list of form objects), `numbers` (a set of `s`, `d` and `p`), `categories`, `title` and `nocat`.
]==]
function export.decline_noun(args, pagename, lang_code)
local data, lang = language_of(lang_code, "noun")
-- The angle brackets are omittable, so a bare word would be read as an indicator; with no spec, decline the page
-- name with no indicators.
local spec_text = args[1] or ""
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
local base = Spec.parse(angle_bracket_spec, "noun", data, lang)
normalize_base(base)
return base
end,
allow_blank_lemma = true,
angle_brackets_omittable = true,
}
local spec = M.inflection_utilities.parse_inflected_text(spec_text, parse_props)
local number, noun
local word_count = 0
M.inflection_utilities.map_word_specs(spec, function()
word_count = word_count + 1
end)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
-- An irregular noun has the gender and animacy of its lexicon entry. They're used if the spec gives none, and
-- giving others is an error.
local irregular = base.indicators.irreg and data.irregular_nouns[base.indicators.decllemma or base.lemma]
if irregular then
if base.gender and (base.gender ~= irregular.gender or base.animacy ~= irregular.animacy) then
spec_error(("The irregular noun '%s' is <%s>"):format(base.lemma,
irregular.gender .. (irregular.animacy and "." .. irregular.animacy or "")), base.text)
end
base.gender, base.animacy = irregular.gender, irregular.animacy
end
base.in_phrase = word_count > 1 and #spec.alternant_or_word_specs > 1 or nil
number = number or base.number
if not base.indicators["+"] and base.gender then
noun = noun or base
end
end)
-- An adjectival word (`+`) agrees with the noun of the phrase, taking whatever gender, animacy and number it
-- doesn't give itself.
M.inflection_utilities.map_word_specs(spec, function(base)
if base.indicators["+"] and noun then
base.gender = base.gender or noun.gender
if base.gender == noun.gender then
base.animacy = base.animacy or noun.animacy
end
base.number = base.number or noun.number
end
if base.indicators["+"] and not base.gender then
error(("The adjectival word '%s' needs a gender, or a noun in the phrase"):format(base.lemma), 0)
end
end)
local slot_list = {}
for _, entry in ipairs(M.data.noun_slots) do
table.insert(slot_list, {entry.slot, entry.slot})
end
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_word,
})
local first
M.inflection_utilities.map_word_specs(spec, function(base)
first = first or base
end)
spec.lang = lang
spec.data = data
spec.numbers = number == "sg" and {s = true} or number == "pl" and {p = true} or {s = true, p = true}
if first.indicators.du then
spec.numbers.d = true
end
-- A collective numeral has only the plural.
if first.indicators.num then
spec.numbers = {p = true}
end
if first.pronoun then
spec.numbers = {}
for _, number_code in ipairs(first.pronoun.numbers) do
spec.numbers[number_code] = true
end
spec.numberless = first.pronoun.numberless
end
spec.categories = {}
-- Only a table of the standard language is categorized; for the lects, the labels of the entry do that.
if not first.attested and not first.indicators.lect then
local function add(name, ...)
table.insert(spec.categories, data.categories[name]:format(...) .. " " .. lang:getCanonicalName())
end
if number == "sg" then
add("singularia_tantum")
elseif number == "pl" then
add("pluralia_tantum")
end
if word_count == 1 then
local indicators = first.indicators
if indicators.irreg then
add("irregular")
elseif indicators.indecl then
add("indeclinable")
elseif indicators["+"] then
add("adjectival")
elseif first.rules and first.rules.used then
local final = final_consonant(data, first.rules.stem)
local stem_type = data.stem_types.velar[final] and "velar" or data.stem_types.soft[final] and "soft"
or "hard"
local gender = data.category_genders[first.gender]
if type(gender) == "table" then
gender = gender[first.animacy]
end
-- A plurale tantum has no gender to tell apart, except for a personal one.
if gender and (number ~= "pl" or first.animacy == "pr") then
add("stem", stem_type, gender)
end
local reducible = false
for part in pairs(first.rules.used) do
reducible = reducible or is_mobile(part)
end
if reducible then
add("reducible")
end
local used = first.rules.used
if used.shortened or used.lengthened then
add("quantitative")
end
end
end
end
-- An attested table says what it attests in its title. Its head is the nominative given, or the reconstructed one
-- starred.
spec.attested = first.attested
local head
if first.attested then
local nominative = spec.forms[number == "pl" and "nom_p" or "nom_s"]
head = first.indicators.recon and "*" .. first.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil
end
spec.lect = first.indicators.lect
if first.indicators.lect then
-- A paradigm's table is headed by the lemma, and an attested one by its nominative.
spec.kind_title = {data.lect_titles[first.indicators.lect], first.attested and head or nil}
elseif first.indicators.dialectal then
spec.kind_title = {data.lect_titles.dialectal, head}
elseif data.attested then
spec.kind_title = {"Biến cách của ", head}
end
spec.title = args.title
spec.nocat = args.nocat
spec.lemmas = {pagename}
return spec
end
-- Return the kind of declension of an adjective, for its title and category: `irregular`, or the kind of the first
-- entry in the data's `adjective_kinds` that its lemma matches (hard ''-y'', velar ''-ki'' and ''-gi'', or soft).
local function adjective_kind(base)
if base.indicators.irreg then
return "irregular"
end
local word = base.indicators.decllemma or base.lemma
for _, kind in ipairs(base.data.adjective_kinds) do
if mw.ustring.find(word, kind[1]) then
return kind[2]
end
end
end
--[==[
Decline an adjective call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl`). Return the alternant
multiword spec from [[Module:inflection utilities]], with the fields `forms`, `layout` (`regular`, `plonly`, `dwa` or
`dual`), `kinds` (the declension kinds of its words), `pos` (the part of speech of the table, from `pos:` on one of its
words), `categories`, `title` and `nocat`.
]==]
function export.decline_adjective(args, pagename, lang_code)
local data, lang = language_of(lang_code, "adjective")
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
return Spec.parse(angle_bracket_spec, "adjective", data, lang)
end,
allow_default_indicator = true,
allow_blank_lemma = true,
}
local spec = M.inflection_utilities.parse_inflected_text(args[1] or pagename, parse_props)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
base.lemma = M.links.remove_links(base.lemma)
-- The part of speech belongs to the whole table, so only one word may give it.
local pos = base.indicators.pos
if pos then
if not data.parts_of_speech[pos] then
local names = {}
for name in pairs(data.parts_of_speech) do
table.insert(names, name)
end
table.sort(names)
spec_error(("Unrecognized part of speech '%s'; the parts of speech are %s"):format(pos,
table.concat(names, ", ")), base.text)
elseif spec.pos then
spec_error("The part of speech ('pos:') is given on more than one word", base.text)
end
spec.pos = pos
end
resolve_table(base)
end)
local slot_list = {}
for slot in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, slot})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_adjective_word,
})
spec.pos = spec.pos or "adjective"
local plural_pos = data.parts_of_speech[spec.pos]
spec.layout, spec.kinds, spec.categories = "regular", {}, {}
local seen = {}
M.inflection_utilities.map_word_specs(spec, function(base)
-- A lect's table names its lect and isn't categorized, and neither is a numeral's. An attested table is headed
-- by the masculine nominative given, or the reconstructed lemma starred.
if base.attested then
local nominative = spec.forms.nom_m
spec.attested = true
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect or "dialectal"], base.indicators.recon and "*" .. base.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil}
spec.layout = base.layout or base.indicators.plonly and "plonly" or spec.layout
return
elseif base.indicators.lect then
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect]}
return
elseif base.indicators.num then
spec.layout = base.layout
return
end
local function add(name, ...)
table.insert(spec.categories, lang:getCanonicalName() .. " " .. data.categories[name]:format(...))
end
local kind = adjective_kind(base)
if not seen[kind] then
seen[kind] = true
table.insert(spec.kinds, kind)
add("adjective_kind", kind, plural_pos)
end
if base.overrides.short then
add("short_forms", plural_pos)
end
if base.indicators.decllemma then
add("irregular_stem", plural_pos)
end
if base.layout or base.indicators.plonly then
spec.layout = base.layout or "plonly"
end
end)
spec.title = args.title
spec.nocat = args.nocat
spec.lang = lang
spec.lemmas = {pagename}
return spec
end
-- Process the arguments of a call of the template of `entry` (`noun` or `adjective`). On the template's own page, a call
-- with no arguments declines the language's example (`examples` in [[Module:zlw-lch-decl/data]]) instead of the page
-- name.
local function process_args(frame, entry)
local language = M.data.languages[frame.args.lang]
return M.parameters.process(frame:getParent().args, {
[1] = {template_default = language and language.examples[entry]},
title = {},
nocat = {type = "boolean"},
json = {type = "boolean"},
pagename = {},
})
end
-- Run the template entry point `entry` (`noun` or `adjective`) on the call of `frame`: decline it with `decline`
-- (`export.decline_noun` or `export.decline_adjective`) and return its table, made by the `TableRenderer` method
-- `render`, or with json=1 the table's data, as `json_data` gives it from the declined spec.
local function run_entry(frame, entry, decline, render, json_data)
local args = process_args(frame, entry)
local spec = decline(args, args.pagename or M.headword_data.pagename, frame.args.lang)
if args.json then
return M.JSON.toJSON(json_data(spec))
end
local renderer = TableRenderer.new(spec)
return renderer[render](renderer)
end
--[==[
Entry point for {{tl|pl-ndecl}} and {{tl|zlw-opl-ndecl}}. Template-callable function to parse and decline a noun given
user-specified arguments and generate a displayable table of the declined forms, or the table's data as JSON with
{{para|json|1}}.
]==]
function export.noun(frame)
return run_entry(frame, "noun", export.decline_noun, "render", function(spec)
return {forms = spec.forms, numbers = spec.numbers, categories = spec.categories, title = spec.title}
end)
end
--[==[
Entry point for {{tl|pl-adecl}}. Template-callable function to parse and decline an adjective given user-specified
arguments and generate a displayable table of the declined forms, or the table's data as JSON with {{para|json|1}}.
]==]
function export.adjective(frame)
return run_entry(frame, "adjective", export.decline_adjective, "renderAdjective", function(spec)
return {forms = spec.forms, layout = spec.layout, kinds = spec.kinds, categories = spec.categories,
title = spec.title}
end)
end
return export
s2k36677k2dae77ps5vvngv73ylzfzj
2573189
2573188
2026-10-24T09:12:15Z
Hiyuune
50834
2573189
Scribunto
text/plain
--[==[ intro:
This module implements the declension tables of the Lechitic languages: {{tl|pl-ndecl}} for Polish nouns and
{{tl|pl-adecl}} for Polish adjectives (both with their Middle Polish, Standard Kurpie and dialectal tables), and
{{tl|zlw-opl-ndecl}} for Old Polish nouns.
The following terminology is helpful to understand:
* The '''lemma''' is the word being declined, normally the nominative singular, or the nominative plural of a plurale
tantum. In a call it's followed by an inline spec of indicators in angle brackets, e.g.
`{{pl-ndecl|<m.anml.*.datu>}}` (the page name as an animal noun with a mobile ''e'' and the dative in ''-u'') or
`{{pl-ndecl|Morze<n.sg> Bałtyckie<+>}}`.
* A '''slot''' is a particular combination of case and number, e.g. `nom_s` or `loc_p`. Each slot is one cell of a
table.
* The '''stem''' is the lemma minus its nominative ending. A '''group''' is the set of nouns that share one set of
rules; a '''rule''' gives the forms of a slot for the stems that end in particular letters; and a '''copy''' is a
slot that takes its forms from another one. See [[Module:zlw-lch-decl/data/pl]] for the details.
* An '''alternation''' is a change to the stem that a rule asks for: dropping or inserting the mobile ''e'', ''ó''/''o''
and ''ą''/''ę'', and the palatalizations.
* A '''base''' is what [[Module:inflection utilities]] calls the parsed spec of a single word: its lemma, indicators and
overrides, plus its forms once it has been declined.
Authorship: [[User:Fenakhay]]
]==]
local export = {}
local M = require("Module:module loader").init {
require = {
inflection_table = "Module:inflection-table",
inflection_utilities = "Module:inflection utilities",
JSON = "Module:JSON",
labels = "Module:labels",
languages = "Module:languages",
links = "Module:links",
parameters = "Module:parameters",
parse_utilities = "Module:parse utilities",
utilities = "Module:utilities",
},
loadData = {
data = "Module:zlw-lch-decl/data",
headword_data = "Module:headword/data",
},
}
-- Return the data module of the language `code` (`Module:zlw-lch-decl/data/CODE`) and its language object. `entry` is
-- the entry point being invoked (`noun` or `adjective`); throw an error if `languages` in [[Module:zlw-lch-decl/data]]
-- doesn't list that entry for the language.
local function language_of(code, entry)
local language = code and M.data.languages[code]
if not language or not language[entry] then
local codes = {}
for known, entries in pairs(M.data.languages) do
if entries[entry] then
table.insert(codes, known)
end
end
table.sort(codes)
error(("The #invoke needs lang= with one of %s"):format(table.concat(codes, ", ")), 0)
end
return mw.loadData("Module:zlw-lch-decl/data/" .. code), M.languages.getByCode(code)
end
------------------------------------------------------------------------------------------------------------------------
-- Spec --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the indicators of a single word, i.e. the `<...>` after its lemma, e.g. `<m.anml.*.datu>`. `Spec.parse`
is the `parse_indicator_spec` callback passed to [[Module:inflection utilities]]; it returns the base of the word, with
its indicators by group and its overrides by slot. The indicators each template knows are listed under `indicators` in
the language's data module, and an unknown one is an error that lists the known ones.
]==]
local Spec = {}
Spec.__index = Spec
local function spec_error(message, text)
error(message .. " in the spec '" .. text .. "'.", 0)
end
-- Return the footnotes in a group that `split_alternating_runs` produced from a bracketed run, i.e. the bracketed
-- segments after the first segment. Throw an error if any text follows a footnote.
local function fetch_footnotes(group, text)
local footnotes
for i = 2, #group - 1, 2 do
if group[i + 1] ~= "" then
spec_error("Only another footnote can follow a footnote", text)
end
footnotes = footnotes or {}
table.insert(footnotes, group[i])
end
return footnotes
end
--[==[
Parse an override of one or more slots of a noun. There are two kinds of overrides:
* Endings, written `CASE[pl]ENDING:ENDING...`, e.g. `genu` or `insplami:mi`. These go on the stem that the slot's rule
uses; an ending that starts with an apostrophe goes after the whole lemma (`gen'a` on ''Google'' gives ''Google'a'').
* Whole forms, written `CASE[pl]:FORM:FORM...`, e.g. `voc:człowiecze:człowieku`.
`CASE+CASE...` sets several cases at once, and `du` in place of `pl` names a dual slot (`nomdu`). Among endings, `+`
stands for the forms the rules give, so that e.g. `nomplowie:+` adds ''-owie'' to them. `-` stands for no ending (among
endings) or no form (among forms), and a footnote can follow any value. `depr` is the deprecative nominative plural of
a masculine personal noun. Return two values: the slots the override applies to, and an object describing it.
]==]
local Overrides = {}
function Overrides.parse(group, text)
local part = group[1]
local slots = {}
while true do
if mw.ustring.sub(part, 1, 4) == "depr" then
table.insert(slots, "depr_p")
part = mw.ustring.sub(part, 5)
else
local case = mw.ustring.sub(part, 1, 3)
if not M.data.case_codes[case] then
spec_error(("Unrecognized case '%s' in an override"):format(case), text)
end
part = mw.ustring.sub(part, 4)
if mw.ustring.find(part, "^pl") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_p")
elseif mw.ustring.find(part, "^du") then
part = mw.ustring.sub(part, 3)
table.insert(slots, case .. "_d")
else
table.insert(slots, case .. "_s")
end
end
if mw.ustring.find(part, "^%+[a-z]") then
part = mw.ustring.sub(part, 2)
else
break
end
end
local override = {values = {}}
if mw.ustring.find(part, "^:") then
override.full = true
part = mw.ustring.sub(part, 2)
end
group[1] = part
for _, value_group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")) do
local value = value_group[1]
if value == "" then
spec_error("Use - for an empty ending or no form", text)
end
table.insert(override.values, {
form = value == "-" and "" or value,
default = not override.full and value == "+" or nil,
footnotes = fetch_footnotes(value_group, text),
})
end
return slots, override
end
-- The slots of an adjective table, which an override of {{tl|pl-adecl}} can name, with their accelerator tags (using the
-- codes in [[Module:form of/data]], `nv` = non-virile).
local ADJECTIVE_ACCEL = {
nom_m = "nom|m|s", nom_f = "nom|f|s", nom_n = "nom|n|s", nom_mp_pers = "vr|nom|p", nom_p_not_mp_pers = "nv|nom|p",
nom_mp_npers = "nv|nom|m|p", nom_fp = "nom|f|p", nom_np = "nom|n|p",
gen_mn = "gen|m//n|s", gen_f = "gen|f|s", gen_p = "gen|p",
dat_mn = "dat|m//n|s", dat_f = "dat|f|s", dat_p = "dat|p",
acc_m_an = "an|acc|m|s", acc_m_in = "in|acc|m|s", acc_f = "acc|f|s", acc_n = "acc|n|s",
acc_mp_pers = "vr|acc|p", acc_p_not_mp_pers = "nv|acc|p", acc_mp_npers = "nv|acc|m|p", acc_fp = "acc|f|p",
acc_np = "acc|n|p",
ins_mn = "ins|m//n|s", ins_f = "ins|f|s", ins_p = "ins|p", ins_mnp = "ins|m//n|p", ins_fp = "ins|f|p",
loc_mn = "loc|m//n|s", loc_f = "loc|f|s", loc_p = "loc|p",
nom_m_d = "nom|m|d", nom_fn_d = "nom|f//n|d", gen_d = "gen|d", dat_d = "dat|d", acc_m_d = "acc|m|d",
acc_fn_d = "acc|f//n|d", ins_d = "ins|d", loc_d = "loc|d",
short = "short",
}
--[==[
Parse an override of {{tl|pl-adecl}}, in the format of the former [[Module:pl-adjective]]: `SLOT[+SLOT...]:FORM:FORM...`
with the slot names of the adjective, e.g. `nom_mp_pers:weseli` or `gen_p+loc_p:...`. Only whole forms are allowed.
Return the same two values as `Overrides.parse`.
]==]
function Overrides.parseAdjective(group, text)
local slots = {}
local value_groups = M.parse_utilities.split_alternating_runs_and_strip_spaces(group, ":")
if #value_groups[1] > 1 then
spec_error("A footnote can't follow the slot name of an override", text)
end
for slot in mw.text.gsplit(value_groups[1][1], "+", true) do
if not ADJECTIVE_ACCEL[slot] then
spec_error(("Unrecognized slot '%s' in an override"):format(slot), text)
end
table.insert(slots, slot)
end
local override = {values = {}, full = true}
for i = 2, #value_groups do
local value = value_groups[i][1]
if value == "" then
spec_error("Use - for no form", text)
end
table.insert(override.values, {form = value == "-" and "" or value, footnotes = fetch_footnotes(value_groups[i], text)})
end
return slots, override
end
-- Return the definition of the indicator `name` for `template`, or nil if there isn't one.
local function indicator_definition(data, template, name)
return data.indicators[template][name]
end
-- Return true if `part` of a spec is an override, i.e. it begins with a case code (or `depr`) and isn't an indicator.
local function is_override(data, template, part)
local name = mw.ustring.match(part, "^([^:]*)") or part
if indicator_definition(data, template, name) then
return false
end
return M.data.case_codes[mw.ustring.sub(part, 1, 3)] ~= nil or mw.ustring.sub(part, 1, 4) == "depr"
end
-- Return true if `part` (`NAME:VALUE`) is an indicator that takes a value (e.g. `decllemma:dń` or `lect:skur`) rather
-- than an override.
local function takes_value(data, template, part)
local definition = indicator_definition(data, template, mw.ustring.match(part, "^([^:]+):"))
return definition and definition.value ~= nil
end
function Spec.parse(angle_bracket_spec, template, data, lang)
local inside = mw.ustring.match(angle_bracket_spec, "^<(.*)>$")
local base = setmetatable({overrides = {}, indicators = {}, groups = {}, template = template, data = data,
lang = lang, text = angle_bracket_spec}, Spec)
if inside == "" then
return base
end
local segments = M.parse_utilities.parse_balanced_segment_run(inside, "[", "]")
for _, group in ipairs(M.parse_utilities.split_alternating_runs_and_strip_spaces(segments, "%.")) do
local part = group[1]
if part == "" then
if #group == 1 then
spec_error("Empty indicator (two periods in a row, or a period at an end)", angle_bracket_spec)
end
base.footnotes = fetch_footnotes(group, angle_bracket_spec)
elseif template == "adjective" and mw.ustring.find(part, ":") and not takes_value(data, template, part)
or template ~= "adjective" and is_override(data, template, part) then
local slots, override
if template == "adjective" then
slots, override = Overrides.parseAdjective(group, angle_bracket_spec)
else
slots, override = Overrides.parse(group, angle_bracket_spec)
end
for _, slot in ipairs(slots) do
if base.overrides[slot] then
spec_error(("Two overrides for the slot '%s'"):format(slot), angle_bracket_spec)
end
base.overrides[slot] = override
end
else
if #group > 1 then
spec_error("A footnote can only follow an override or stand alone", angle_bracket_spec)
end
local name, value = mw.ustring.match(part, "^([^:]+):(.*)$")
name = name or part
local definition = indicator_definition(data, template, name)
if not definition then
local names = {}
for known in pairs(data.indicators[template]) do
table.insert(names, known)
end
table.sort(names)
spec_error(("Unrecognized indicator '%s'; the indicators are %s"):format(name, table.concat(names, ", ")),
angle_bracket_spec)
end
if definition.value and (value == nil or value == "") then
spec_error(("The indicator '%s' needs a value ('%s:...')"):format(name, name), angle_bracket_spec)
elseif not definition.value and value ~= nil then
spec_error(("The indicator '%s' takes no value"):format(name), angle_bracket_spec)
end
if base.indicators[name] ~= nil then
spec_error(("The indicator '%s' is given twice"):format(name), angle_bracket_spec)
end
local key = definition.group or name
if base.groups[key] then
spec_error(("The indicators '%s' and '%s' can't be used together"):format(base.groups[key], name),
angle_bracket_spec)
end
base.groups[key] = name
base.indicators[name] = value or true
end
end
return base
end
-- Return the value set by a group of indicators (e.g. "m" for `gender`), or nil if none of the group was given.
function Spec:group(group)
local name = self.groups[group]
if not name then
return nil
end
return indicator_definition(self.data, self.template, name).sets or name
end
------------------------------------------------------------------------------------------------------------------------
-- Stem --
------------------------------------------------------------------------------------------------------------------------
--[==[
Functions to find the stem of a lemma and apply the alternations of the language's data module to it.
]==]
local Stem = {}
-- Split a lemma into its stem and nominative ending. The ending is the first of the `nominative_endings` of its gender
-- (`m`, `f` or `n`, or `plural` for a plurale tantum) that the lemma ends in with something before it, unless the
-- ending is one of the gender's `nominative_after_consonant` and a vowel precedes it; if there's none, the lemma is its
-- own stem and the ending is empty.
function Stem.split(data, lemma, gender, plural)
local after_consonant = not plural and data.nominative_after_consonant[gender] or {}
for _, ending in ipairs(data.nominative_endings[plural and "plural" or gender]) do
local stem = mw.ustring.match(lemma, "^(.+)" .. ending .. "$")
if stem and not (after_consonant[ending] and mw.ustring.find(mw.ustring.sub(stem, -1), "[" .. data.vowels .. "]")) then
return stem, ending
end
end
return lemma, ""
end
-- Replace the last letters of `stem` according to `map`, trying the longest keys first (up to three letters). Return
-- nil if the stem ends in none of the keys.
local function replace_final(stem, map)
for _, length in ipairs({3, 2, 1}) do
if mw.ustring.len(stem) >= length then
local final = mw.ustring.sub(stem, -length)
if map[final] then
return mw.ustring.sub(stem, 1, -length - 1) .. map[final]
end
end
end
return nil
end
-- Remove the mobile vowel from `stem`, i.e. the first of the data's `mobile_vowels` that it has before its final
-- consonants. Return nil if it has none.
local function reduce(data, stem)
local vowels = data.vowels
for _, mobile in ipairs(data.mobile_vowels) do
local head, final = mw.ustring.match(stem, "^(.-)" .. mobile[1] .. "([^" .. vowels .. "]+)$")
if head and head ~= "" and not (mobile.after_consonant
and mw.ustring.find(mw.ustring.sub(head, -1), "[" .. vowels .. "]")) then
return (mobile.soften and replace_final(head, data[mobile.soften]) or head) .. final
end
end
return nil
end
-- Insert `vowel` before the last consonant of `stem`. Return nil if the stem doesn't end in two consonants.
local function insert(data, stem, vowel)
local vowels = data.vowels
local head, final = mw.ustring.match(stem, "^(.-[^" .. vowels .. "])([^" .. vowels .. "])$")
return head and head .. vowel .. final or nil
end
-- Change the vowel of the last syllable of `stem`, whose vowels are the letters of `vowels`, according to `map`
-- (`shorten`, `lengthen` or `front` in the data, or `clear` of a lect's paradigm). Return nil if that vowel isn't one
-- of the keys of `map`.
local function alternate(vowels, stem, map)
local letters = ""
for vowel in pairs(map) do
letters = letters .. vowel
end
local head, vowel, tail = mw.ustring.match(stem, "^(.*)([" .. letters .. "])([^" .. vowels .. "]*)$")
return head and head .. map[vowel] .. tail or nil
end
-- Return the stem that `label` names, which is either `plain` or a set of alternations joined with "+" (e.g.
-- `reduced+palatal`). Return nil if one of the alternations doesn't apply to `stem`.
function Stem.apply(data, stem, label)
local text = stem
for part in mw.text.gsplit(label, "+", true) do
if not text then
return nil
end
if part == "reduced" then
text = reduce(data, text)
elseif mw.ustring.find(part, "^inserted_") then
-- `inserted_VOWEL` puts the mobile vowel VOWEL in.
text = insert(data, text, mw.ustring.sub(part, 10))
elseif part == "truncated" then
text = replace_final(text, data.truncate)
elseif part == "spelled" then
text = replace_final(text, data.spelled)
elseif part == "shortened" then
text = alternate(data.vowels, text, data.shorten)
elseif part == "lengthened" then
text = alternate(data.vowels, text, data.lengthen)
elseif part == "fronted" then
text = alternate(data.vowels, text, data.front)
elseif part == "soft" or part == "final_soft" then
-- This is only a spelling, so leave the stem alone if it has no such letter.
text = replace_final(text, data[part]) or text
elseif part == "palatal" or part == "virile" then
text = replace_final(text, data[part])
elseif part == "irregular" then
text = ""
elseif part ~= "plain" then
error(("Internal error: unknown alternation '%s'"):format(part))
end
end
return text
end
------------------------------------------------------------------------------------------------------------------------
-- Noun rules --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object holding the rules of one word's group, with the word's indicators applied. `NounRules.new(base)` finds the group
from the word's gender, kind, number and nominative ending, and `:forms(slot)` returns the forms of a slot by the rule
of the longest matching stem ending, as form objects `{form = ..., footnotes = {...}}`.
]==]
local NounRules = {}
NounRules.__index = NounRules
local function group_key(rule_gender, kind, plural, nominative)
return ("%s %s %s %s"):format(rule_gender, kind, plural and "pl" or "sg", nominative)
end
function NounRules.new(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy]
end
local plural = base.number == "pl"
-- A plurale tantum is either masculine personal (m-pr) or not, and the non-personal ones share the groups of the
-- neuter.
if plural and rule_gender ~= "m-pr" then
rule_gender = "n"
end
if not rule_gender then
spec_error(("The noun '%s' needs a gender (m, f or n)"):format(word), base.text)
end
local stem, nominative = Stem.split(data, word, rule_gender:sub(1, 1), plural)
local kind = base.kind or "common"
local group = data.noun_groups[group_key(rule_gender, kind, plural, nominative)]
or kind ~= "common" and data.noun_groups[group_key(rule_gender, "common", plural, nominative)]
if not group then
error(("No rules for %s nouns in -%s ('%s'); give the forms with overrides and <!>"):format(
rule_gender, nominative, word), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
used = {}, head_slot = plural and "nom_p" or "nom_s"}, NounRules)
end
-- Return the rule of `slot` for this stem, i.e. the rule of the longest stem ending (up to three letters) that has one.
function NounRules:rule(slot)
local rules = self.group.rules
for size = math.min(3, mw.ustring.len(self.stem)), 0, -1 do
local suffix = size == 0 and "" or mw.ustring.sub(self.stem, -size)
local by_slot = rules[suffix]
if by_slot and by_slot[slot] then
return by_slot[slot]
end
end
return nil
end
-- Return true if a part of an alternation label is about the mobile vowel, i.e. it's `reduced` or `inserted_VOWEL`.
local function is_mobile(part)
return part == "reduced" or mw.ustring.find(part, "^inserted_") ~= nil
end
-- Return the alternation label of an ending of a rule, with the word's indicators applied. `-*` takes out the mobile
-- vowel and `*` puts it in: for a lemma ending in a consonant it's dropped before an ending, and for one ending in a
-- vowel it's inserted into a bare stem (as `inserted_vowel` in the data says). `-#` and `#` do the same for ''ó''/''o''
-- and ''ą''/''ę''. A bare form of a lemma ending in a consonant is the lemma itself (e.g. the accusative of an
-- inanimate noun) and takes neither.
function NounRules:label(label, ending)
local base = self.base
local parts = {}
for part in mw.text.gsplit(label, "+", true) do
parts[part] = true
end
local mobile = false
for part in pairs(parts) do
mobile = mobile or is_mobile(part)
end
local consonant_final = self.nominative == ""
if base.reducible == false then
for part in pairs(parts) do
if is_mobile(part) then
parts[part] = nil
end
end
elseif base.reducible and not mobile then
if consonant_final and ending ~= "" then
parts.reduced = true
elseif ending == "" then
local inserted = self.data.inserted_vowel
parts["inserted_" .. (inserted.after[mw.ustring.sub(self.stem, -2, -2)] or inserted.default)] = true
end
end
if base.quantity == "none" then
parts.shortened, parts.lengthened = nil, nil
elseif base.quantity == "full" and not (parts.shortened or parts.lengthened) then
if consonant_final and ending ~= "" then
parts.shortened = true
elseif ending == "" then
parts.lengthened = true
end
end
-- Put the parts in the order they apply in, with the mobile vowel first.
local ordered = {}
if parts.reduced then
table.insert(ordered, "reduced")
end
local inserted = {}
for part in pairs(parts) do
if mw.ustring.find(part, "^inserted_") then
table.insert(inserted, part)
end
end
table.sort(inserted)
for _, part in ipairs(inserted) do
table.insert(ordered, part)
end
for _, name in ipairs({"truncated", "spelled", "shortened", "lengthened", "fronted", "soft", "final_soft", "palatal",
"virile", "irregular"}) do
if parts[name] then
table.insert(ordered, name)
end
end
return ordered[1] and table.concat(ordered, "+") or "plain"
end
-- Join a stem and an ending as the language spells them. A final soft consonant before a vowel is written with the
-- data's `soft_vowel`, which merges with the same vowel at the start of the ending (e.g. ''koń'' + ''-a'' → ''konia'',
-- ''goleń'' + ''-i'' → ''goleni'').
local function join(data, stem, ending)
if ending ~= "" and mw.ustring.find(mw.ustring.sub(ending, 1, 1), "[" .. data.vowels .. "]") then
local spelled = replace_final(stem, data.soft)
if spelled then
local vowel = data.soft_vowel
local length = mw.ustring.len(vowel)
return spelled .. (mw.ustring.sub(ending, 1, length) == vowel and mw.ustring.sub(ending, length + 1) or ending)
end
end
return stem .. ending
end
function NounRules:form(label, ending, note)
local footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil
-- An apostrophe keeps the lemma whole before the ending (''Google'' → ''Google'a'').
if mw.ustring.sub(ending, 1, 1) == "'" then
return {form = self.word .. ending, footnotes = footnotes}
end
local full = self:label(label, ending)
-- Note the alternations used, for the categories of the table.
for part in mw.text.gsplit(full, "+", true) do
self.used[part] = true
end
local stem = Stem.apply(self.data, self.stem, full) or self.stem
return {form = join(self.data, stem, ending), footnotes = footnotes}
end
-- Return the endings of a rule's cell as a list of `{ending, stem = ..., note = ...}`. A cell is an ending (a string),
-- one ending with a stem or note (e.g. `{ "e", stem = "palatal" }`), or a list of either (e.g. `{ "i", "ów" }`).
local function cell_endings(cell)
if type(cell) == "string" then
return {{cell}}
elseif type(cell[1]) == "string" and cell[2] == nil then
return {cell}
end
local list = {}
for _, ending in ipairs(cell) do
table.insert(list, type(ending) == "string" and {ending} or ending)
end
return list
end
-- Return the forms of `slot` according to its rule, or nil if the group has no rule for the slot.
function NounRules:forms(slot)
local cell = self:rule(slot)
if not cell then
return nil
end
local list = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(list, self:form(ending.stem or "plain", ending[1], ending.note))
end
return list
end
-- Return the alternation label for an ending given in an override of `slot`. If the ending is one of the rule's own
-- endings, use that ending's label; otherwise use the label of the rule's first ending minus the softening that its
-- ending brings (`palatal` before ''-e'', `virile` before the virile ''-i''/''-y''). This way ''dom'' with the locative
-- ''-u'' gives ''domu'', and ''Polak'' with the nominative plural ''-owie'' gives ''Polakowie''.
function NounRules:overrideLabel(slot, ending)
local cell = self:rule(slot)
local endings = cell and cell_endings(cell) or {}
for _, item in ipairs(endings) do
if item[1] == ending then
return item.stem or "plain"
end
end
local kept = {}
for part in mw.text.gsplit(endings[1] and endings[1].stem or "plain", "+", true) do
if part ~= "palatal" and part ~= "virile" and part ~= "irregular" and part ~= "plain" then
table.insert(kept, part)
end
end
return kept[1] and table.concat(kept, "+") or "plain"
end
--[==[
Object holding the rules of an adjective, with the methods of `NounRules`. The group comes from `adjective_groups`
according to the ending of the lemma (one of `adjective_nominatives`). Adjectives take no stem indicators.
]==]
local AdjectiveRules = setmetatable({}, {__index = NounRules})
AdjectiveRules.__index = AdjectiveRules
function AdjectiveRules.new(base, word)
local data = base.data
local stem, nominative, group
for _, ending in ipairs(data.adjective_nominatives) do
stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
if stem then
nominative = ending
group = data.adjective_groups["adj common sg " .. ending]
break
end
end
if not group then
local endings = {}
for _, ending in ipairs(data.adjective_nominatives) do
table.insert(endings, "-" .. ending)
end
error(("'%s' doesn't end in %s; an irregular adjective takes <irreg>"):format(word,
table.concat(endings, " or ")), 0)
end
return setmetatable({base = base, data = data, word = word, stem = stem, nominative = nominative, group = group,
head_slot = "nom_m", used = {}}, AdjectiveRules)
end
--[==[
Object holding the rules of a lect's paradigm, i.e. an entry of `lect_tables` with `table = "paradigm"`, such as
Standard Kurpie (`lect:skur`). The paradigm is the table in the data named by the entry's `rules`. Its `types` decide
the type of a lemma, and each type has one ending per slot. It answers the same calls from `decline_word` as
`NounRules`.
]==]
local ParadigmRules = {}
ParadigmRules.__index = ParadigmRules
-- Return the last consonant of a stem, which is either one of the data's `digraphs` or a single letter.
local function final_consonant(data, stem)
local last_two = mw.ustring.sub(stem, -2)
return data.digraphs[last_two] and last_two or mw.ustring.sub(stem, -1)
end
-- Return the stem, type and declension (the gender whose endings it takes) of a lemma in `paradigm`, decided by its
-- gender and ending (see `types` in the data). `name` is the name of the lect, for the error messages.
local function paradigm_type(data, paradigm, name, word, gender, text)
for _, entry in ipairs(gender and paradigm.types[gender] or {}) do
local stem = entry.ending == "" and word or mw.ustring.match(word, "^(.+)" .. entry.ending .. "$")
if stem and not (entry.consonant_final and mw.ustring.find(word, "[" .. paradigm.vowels .. "]$")) then
local final = final_consonant(data, stem)
for _, class in ipairs(entry.by_final or {}) do
if paradigm[class[1]][final] then
return stem, class[2], entry.declension or gender
end
end
return stem, entry.default, entry.declension or gender
end
end
spec_error(("The %s rules have no %s noun like '%s'; give its forms as overrides"):format(name,
gender and M.data.genders[gender].name or "genderless", word), text)
end
-- Return `stem` with the slanted vowel of its last syllable made clear by the `clear` table of `paradigm`, or by
-- `clear_before_nasal` when one of its `nasals` follows the vowel. Return nil if that vowel isn't slanted.
local function clear_vowel(paradigm, stem)
local vowels = paradigm.vowels
local following = mw.ustring.match(stem, "[" .. vowels .. "]([^" .. vowels .. "]?)[^" .. vowels .. "]*$")
local before_nasal = paradigm.nasals and paradigm.nasals[following] and paradigm.clear_before_nasal
return alternate(vowels, stem, before_nasal or paradigm.clear)
end
function ParadigmRules.new(base, word, paradigm, name)
local data = base.data
local plural = base.number == "pl"
local stem, type, declension
if plural then
-- A plurale tantum is declined from its nominative plural, with the plural endings of its gender's hard stems.
if not paradigm.plural_nominatives then
spec_error(("The %s rules have no pluralia tantum"):format(name), base.text)
end
for _, ending in ipairs(paradigm.plural_nominatives) do
stem = stem or mw.ustring.match(word, "^(.+)" .. ending .. "$")
end
if not stem then
spec_error(("The %s rules have no plurale tantum like '%s'"):format(name, word), base.text)
end
type, declension = "cứng", base.gender or "n"
else
stem, type, declension = paradigm_type(data, paradigm, name, word, base.gender, base.text)
end
local consonant_final = not plural and stem == word
if declension == "m" and base.animacy ~= "inan" and paradigm.animate_types and paradigm.animate_types[type] then
type = paradigm.animate_types[type]
end
if base.reducible then
stem = reduce(data, stem) or spec_error(("The stem '%s' has no mobile e"):format(stem), base.text)
end
-- With `#`, the forms with an ending have the clear vowel of `clear_stem`.
local clear_stem
if base.quantity == "none" then
spec_error(("The %s rules have no vowel alternation for '-#' to remove"):format(name), base.text)
elseif base.quantity == "full" then
if not paradigm.clear then
spec_error(("The %s rules have no vowel alternation for '#'"):format(name), base.text)
elseif not consonant_final then
spec_error(("In the %s rules, '#' needs a lemma that ends in a consonant"):format(name), base.text)
end
clear_stem = clear_vowel(paradigm, stem)
or spec_error(("The stem '%s' has no slanted vowel for '#' to make clear"):format(stem), base.text)
end
local endings = paradigm.nouns[declension][type]
if plural then
local plural_endings = {}
for slot, ending in pairs(endings) do
if mw.ustring.find(slot, "_p$") then
plural_endings[slot] = ending
end
end
endings = plural_endings
end
local copies = {}
for slot, source in pairs(paradigm.copies[declension]) do
copies[slot] = source
end
if base.gender == "m" then
for slot, source in pairs(paradigm.animate_copies[base.animacy]) do
copies[slot] = source
end
end
return setmetatable({base = base, data = data, paradigm = paradigm, word = word, stem = stem, clear_stem = clear_stem,
endings = endings, group = {copies = copies}, head_slot = plural and "nom_p" or "nom_s"}, ParadigmRules)
end
-- Return one form: the stem (with its clear vowel before an ending, under `#`), palatalized if `label` is `palatal` (by
-- the paradigm's own `palatal` table), followed by the ending. After a hardened consonant, the first letter of the
-- ending is respelled by `hardened_spelling`.
function ParadigmRules:form(label, ending, note)
local paradigm = self.paradigm
local stem = self.clear_stem and ending ~= "" and self.clear_stem or self.stem
if label == "palatal" then
local last_two = mw.ustring.sub(stem, -2)
if paradigm.palatal[last_two] then
stem = mw.ustring.sub(stem, 1, -3) .. paradigm.palatal[last_two]
else
stem = mw.ustring.sub(stem, 1, -2) .. (paradigm.palatal[mw.ustring.sub(stem, -1)] or mw.ustring.sub(stem, -1))
end
end
if paradigm.hardened and paradigm.hardened[final_consonant(self.data, stem)] then
local respelled = paradigm.hardened_spelling and paradigm.hardened_spelling[mw.ustring.sub(ending, 1, 1)]
if respelled then
ending = respelled .. mw.ustring.sub(ending, 2)
end
end
return {form = stem .. ending, footnotes = note and {"[" .. self.data.notes[note] .. "]"} or nil}
end
function ParadigmRules:forms(slot)
local cell = self.endings[slot]
if not cell then
return {}
end
if type(cell) == "string" then
return {self:form("plain", cell)}
end
return {self:form(cell.stem or "plain", cell[1], cell.note)}
end
-- Return the stem label of a slot's rule. An ending given for the slot in an override goes on that stem.
function ParadigmRules:overrideLabel(slot)
local cell = self.endings[slot]
return type(cell) == "table" and cell.stem or "plain"
end
------------------------------------------------------------------------------------------------------------------------
-- Declension --
------------------------------------------------------------------------------------------------------------------------
-- Return the forms of a noun from the lexicon (`<irreg>`) or of an indeclinable noun (`<indecl>`).
local function lexicon_forms(base, word)
local forms = {}
if base.indicators.irreg then
local list = base.data.irregular_nouns[word]
if not list then
error(("'%s' is not one of the irregular nouns"):format(word), 0)
end
for i, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = list[i]}}
end
elseif base.indicators.indecl then
for _, slot in ipairs(base.data.slot_order) do
forms[slot] = {{form = word}}
end
end
return forms
end
-- Return the masculine nominative singular of an adjectival word given in another gender, using `adjective_lemma` in
-- the data, e.g. ''teściowa'' → ''teściowy'', ''tania'' → ''tani'', ''bykowe'' → ''bykowy'', ''wielkie'' →
-- ''wielki''. A plural such as ''Zjednoczone'' works the same way.
local function adjective_lemma(data, word, rule_gender, plural)
local lemma = data.adjective_lemma
for _, ending in ipairs(lemma.endings[plural and "plural" or rule_gender] or {}) do
local stem = mw.ustring.match(word, "^(.+)" .. ending[1] .. "$")
if stem then
return stem .. ((ending.soft or lemma.soft_after[mw.ustring.sub(stem, -1)]) and lemma.soft or lemma.hard)
end
end
return word
end
--[==[
Return the masculine nominative singular that goes with a virile plural, e.g. ''krewni'' → ''krewny'', ''polscy'' →
''polski''. We try each word that the data's `palatal` table could have softened into the plural (before one of the
`virile_endings`) and return the one whose virile nominative plural, as the adjective rules give it, is that plural.
Return {nil} if there's none.
]==]
local function virile_lemma(data, word)
local adjective = {indicators = {}, overrides = {}, data = data}
for final, softened in pairs(data.palatal) do
for _, ending in ipairs(data.virile_endings) do
local stem = mw.ustring.match(word, "^(.+)" .. softened .. ending .. "$")
if stem then
for _, nominative in ipairs(data.adjective_nominatives) do
local lemma = stem .. final .. nominative
local ok, rules = pcall(AdjectiveRules.new, adjective, lemma)
if ok then
for _, form in ipairs(rules:forms("nom_mp_pers")) do
if form.form == word then
return lemma
end
end
end
end
end
end
end
return nil
end
-- Return the forms of an adjective in a lect's paradigm (`lect:skur`): the endings of the paradigm's `adjective` added
-- to the lemma minus its last letter, with the slots shared as for every adjective (`adjective_shared` in the data).
local function paradigm_adjective_forms(data, paradigm, word)
local stem = mw.ustring.sub(word, 1, -2)
local forms = {nom_m = {{form = word}}}
for slot, ending in pairs(paradigm.adjective) do
forms[slot] = {{form = stem .. ending}}
end
for source, targets in pairs(data.adjective_shared) do
for _, target in ipairs(targets) do
forms[target] = forms[source]
end
end
return forms
end
-- Return the forms of an adjectival word (`+`) in a lect's paradigm (`lect:skur`), in noun slots. Its masculine comes from
-- the word as given: the word minus the paradigm's nominative ending for its gender and number, with ''-ï'' after one of
-- the paradigm's `adjective_soft` consonants and ''-y'' otherwise.
local function paradigm_adjectival_forms(base, word, rule_gender, plural)
local data = base.data
local paradigm = data[base.lect_table.rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
local masculine = word
if plural or rule_gender == "f" or rule_gender == "n" then
local ending = paradigm.adjective[plural and (rule_gender == "m-pr" and "nom_mp_pers" or "nom_p_not_mp_pers")
or "nom_" .. rule_gender]
local stem = mw.ustring.match(word, "^(.+)" .. ending .. "$")
or spec_error(("The adjectival word '%s' doesn't end in -%s"):format(word, ending), base.text)
masculine = stem .. (paradigm.adjective_soft and paradigm.adjective_soft[final_consonant(data, stem)] and "ï" or "y")
end
local adjective = paradigm_adjective_forms(data, paradigm, masculine)
for _, pair in ipairs(data.adjective_accusatives) do
adjective[pair[2]] = adjective[pair[2]] or adjective[pair[1]]
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = adjective[adjective_slot] or {}
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = adjective[adjective_slot] or {}
end
end
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
-- Return the forms of an adjectival word (`+`) in noun slots, using `adjectival_slots` in the data.
local function adjectival_forms(base, word)
local data = base.data
local rule_gender = data.rule_gender[base.gender]
if type(rule_gender) == "table" then
rule_gender = rule_gender[base.animacy or "inan"]
end
local plural = base.number == "pl"
if base.lect_table and base.lect_table.table == "paradigm" then
return paradigm_adjectival_forms(base, word, rule_gender, plural)
end
local lemma = plural and rule_gender == "m-pr" and virile_lemma(data, word) or adjective_lemma(data, word, rule_gender, plural)
local adjective = {lemma = lemma, indicators = {}, overrides = {}, data = data}
local rules = AdjectiveRules.new(adjective, adjective.lemma)
local function forms_of(slot)
if slot == "nom_m" then
return {{form = adjective.lemma}}
end
local source = rules.group.copies[slot]
while source and rules.group.copies[source] do
source = rules.group.copies[source]
end
if source == "nom_m" then
return {{form = adjective.lemma}}
end
return rules:forms(source or slot) or {}
end
local forms = {}
for slot, adjective_slot in pairs(data.adjectival_slots[rule_gender]) do
forms[slot] = forms_of(adjective_slot)
end
if rule_gender ~= "m-pr" then
for slot, adjective_slot in pairs(data.adjectival_slots.plural) do
forms[slot] = forms_of(adjective_slot)
end
end
-- The word as given heads its table.
forms[plural and "nom_p" or "nom_s"] = {{form = word}}
return forms
end
--[==[
Resolve the lect of a `lect:` indicator or a `[lect:CODE:PLACE]` tag through the aliases in the data module of the lects
(`lect_module` in the language's data, which is [[Module:zlw-lch-IPA/data/pl]] for Polish). Return the code and the
name of the lect.
]==]
local function lect_of(data, code, text)
local lects = mw.loadData(data.lect_module)
code = lects.lect_aliases[code] or code
local lect = lects.lects[code]
if not lect then
local codes = {}
for known in pairs(lects.lects) do
table.insert(codes, known)
end
table.sort(codes)
spec_error(("Unrecognized lect '%s'; the lects are %s"):format(code, table.concat(codes, ", ")), text)
end
return code, lect.name
end
-- Return a footnote `[lect:CODE]` or `[lect:CODE:PLACE]` of a word of `base` as it's shown, with the name of the lect
-- formatted as its label is (linked to the article on the dialect) and the place. Return nil if the footnote isn't a
-- lect tag.
local function lect_footnote(base, footnote)
local code, place = mw.ustring.match(footnote, "^%[lect:([^:%]]+):?(.-)%]$")
if not code then
return nil
end
local _, name = lect_of(base.data, code, base.text)
local label = M.labels.get_label_info{label = name, lang = base.lang, nocat = true}.label
return "[" .. label .. (place ~= "" and " (" .. place .. ")" or "") .. "]"
end
-- Return the link target of a form of an attested lect, i.e. its modern spelling according to `respelling` (e.g.
-- ''ptåka'' → ''ptaka''). Return nil if it's spelled the same.
local function respelled(respelling, form)
local target = mw.ustring.gsub(form, ".", respelling)
return target ~= form and target or nil
end
-- Return a `generate_link` function for `show_forms` for the table of `spec`, which links a respelled form (one with a
-- `target`) to its modern spelling.
local function respelled_link(spec)
return function(data)
if data.form.target then
return M.links.full_link{lang = spec.lang, term = data.form.target, alt = data.form.formval_for_link,
tr = "-"} .. M.inflection_utilities.get_footnote_text(data.form.footnotes, data.footnote_obj)
end
end
end
--[==[
Return the forms of an attested table (Middle Polish `lect:mpl`, the `dialectal` table and every Old Polish table),
which are the cells given, exactly as given, and nothing else. In a dialectal table, every form must have a lect,
either from its own `[lect:...]` tag or from a tag given for the whole word.
]==]
local function attested_forms(base)
local forms = {}
local word_lect
local word_footnotes = {}
for _, note in ipairs(base.footnotes or {}) do
local shown = lect_footnote(base, note)
word_lect = word_lect or shown
table.insert(word_footnotes, shown or note)
end
-- the forms with a lect tag of their own, which the lect tag of the word doesn't go on
local own_lect = {}
local respelling = base.lect_table and base.lect_table.respelling and base.data[base.lect_table.respelling]
for slot, override in pairs(base.overrides) do
if not override.full then
spec_error(("An attested table takes whole forms: '%s:FORM'"):format(slot), base.text)
end
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
local footnotes, lect = {}, nil
for _, note in ipairs(value.footnotes or {}) do
local shown = lect_footnote(base, note)
lect = lect or shown
table.insert(footnotes, shown or note)
end
if base.indicators.dialectal then
if not lect and not word_lect then
spec_error(("The dialectal form '%s' needs [lect:CODE]"):format(value.form), base.text)
end
end
local form = {
form = value.form,
target = respelling and respelled(respelling, value.form) or nil,
footnotes = footnotes[1] and footnotes or nil,
}
own_lect[form] = lect and true or nil
table.insert(list, form)
end
end
forms[slot] = list
end
if base.footnotes then
base.footnotes, base.word_lect, base.own_lect = word_footnotes, word_lect, own_lect
end
return forms
end
-- Return the entry of a pronoun in the data's `pronouns` along with the ending its forms take. This is the lemma's own
-- entry (with no ending), or the entry of the pronoun it's made from plus one of the `pronoun_suffixes` (e.g.
-- ''cośkolwiek'' is ''co'' plus ''-śkolwiek'').
local function pronoun_entry(data, lemma)
local pronouns = data.pronouns
if pronouns[lemma] then
return pronouns[lemma], ""
end
for _, suffix in ipairs(data.pronoun_suffixes or {}) do
local head = mw.ustring.match(lemma, "^(.+)" .. suffix .. "$")
if head and pronouns[head] then
return pronouns[head], suffix
end
end
return nil
end
-- Return the forms of a pronoun (`<pron>`) with their notes. In an attested table (Old Polish), the forms given in the
-- spec go on top of them.
local function pronoun_forms(base, word)
local data = base.data
local pronoun, suffix = pronoun_entry(data, word)
if not pronoun then
local lemmas = {}
for lemma in pairs(data.pronouns) do
table.insert(lemmas, lemma)
end
table.sort(lemmas)
local message = ("No pronoun '%s'; the pronouns are %s"):format(word, table.concat(lemmas, ", "))
if data.pronoun_suffixes then
local suffixes = {}
for _, item in ipairs(data.pronoun_suffixes) do
table.insert(suffixes, "-" .. item)
end
message = message .. ", and these with " .. table.concat(suffixes, ", ")
end
spec_error(message, base.text)
end
base.pronoun = pronoun
local forms = {}
for slot, list in pairs(pronoun) do
if slot ~= "numbers" and slot ~= "numberless" then
forms[slot] = {}
for _, item in ipairs(list) do
local form = {form = (type(item) == "table" and item[1] or item) .. suffix}
if type(item) == "table" then
form.footnotes = {}
for _, note in ipairs(item.notes) do
table.insert(form.footnotes, "[" .. data.notes[note] .. "]")
end
end
table.insert(forms[slot], form)
end
end
end
if base.attested then
for slot, list in pairs(attested_forms(base)) do
forms[slot] = list
end
end
return forms
end
-- Return the rule of a numeral in `rules` (`numeral_rules` or `collective_rules` in the data), i.e. the rule of the
-- longest key that the lemma ends in, along with the lemma minus that key.
local function numeral_rule(rules, word, text)
for length = mw.ustring.len(word), 0, -1 do
local key = length == 0 and "" or mw.ustring.sub(word, -length)
if rules[key] then
return rules[key], mw.ustring.sub(word, 1, mw.ustring.len(word) - length)
end
end
spec_error(("No numeral declines like '%s'"):format(word), text)
end
-- Return the forms of a numeral (`<num>`), i.e. the endings of its rule added to its stem.
local function numeral_forms(rules, base, word)
local rule, stem = numeral_rule(rules, word, base.text)
local forms = {}
for slot, cell in pairs(rule) do
forms[slot] = {}
for _, ending in ipairs(cell_endings(cell)) do
table.insert(forms[slot], {form = stem .. ending[1],
footnotes = ending.note and {"[" .. base.data.notes[ending.note] .. "]"} or nil})
end
end
return forms
end
--[==[
Add the footnotes given for the whole word (`base.footnotes`) after the footnotes of every form, as new form objects,
since a copied slot shares the form objects of its source. In an attested table the word's lect tag
(`base.word_lect`) only goes on the forms without a lect tag of their own (`base.own_lect`). Return the forms.
]==]
local function add_word_footnotes(base, forms)
if not base.footnotes then
return forms
end
for slot, list in pairs(forms) do
local copy = {}
for _, form in ipairs(list) do
local footnotes = {}
for _, note in ipairs(form.footnotes or {}) do
table.insert(footnotes, note)
end
for _, note in ipairs(base.footnotes) do
if not (note == base.word_lect and base.own_lect[form]) then
table.insert(footnotes, note)
end
end
table.insert(copy, {form = form.form, footnotes = footnotes, target = form.target})
end
forms[slot] = copy
end
return forms
end
--[==[
Decline a single word. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]]. First the
rules fill every slot they cover. Then the overrides apply (an ending goes on the stem that the slot's rule uses, and a
form replaces the cell), followed by the copies (unless a copy is overridden itself), the deprecative forms of a
masculine personal noun (after its nominative plural, with a footnote) and finally the footnote for the whole word.
]==]
local function decline_word(base)
local word = base.indicators.decllemma or base.lemma
local forms, rules
if base.attested then
base.forms = add_word_footnotes(base, base.indicators.pron and pronoun_forms(base, word) or attested_forms(base))
return
elseif base.indicators.pron then
forms = pronoun_forms(base, word)
elseif base.indicators.num then
forms = numeral_forms(base.data.collective_rules, base, word)
elseif base.indicators.irreg or base.indicators.indecl then
forms = lexicon_forms(base, word)
elseif base.indicators["!"] then
-- A manual table has only the forms its overrides give.
forms = {}
elseif base.indicators["+"] then
forms = adjectival_forms(base, word)
else
rules = base.lect_table and base.lect_table.table == "paradigm"
and ParadigmRules.new(base, word, base.data[base.lect_table.rules], base.lect_name) or NounRules.new(base, word)
-- The lemma heads the table, even when another word is declined in its place (`decllemma`).
forms = {[rules.head_slot] = {{form = base.lemma}}}
-- The rules give the singular and the plural; only an attested table has the dual.
for _, entry in ipairs(M.data.noun_slots) do
local slot = entry.slot
if entry.number ~= "d" and slot ~= rules.head_slot and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
-- A form that is the declined word itself (e.g. an inanimate accusative) belongs to the lemma.
for _, form in ipairs(forms[slot] or {}) do
if form.form == word then
form.form = base.lemma
end
end
end
end
-- In a phrase the deprecative forms would agree with nothing (''pany młodzi''), so only a single word shows
-- them.
if not base.in_phrase then
forms.depr_p = rules:forms("depr_p")
end
end
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.default then
for _, form in ipairs(rules and rules:forms(slot) or {}) do
table.insert(list, form)
end
elseif override.full then
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
else
local form = rules and rules:form(rules:overrideLabel(slot, value.form), value.form) or {form = word .. value.form}
form.footnotes = value.footnotes
table.insert(list, form)
end
end
forms[slot] = list
end
if rules then
-- A copy can copy another copy (e.g. the vocative of a feminine consonant-stem noun is its locative, which is
-- its dative). Fill each one from the slot at the end of its chain, unless a slot along the way is overridden.
local copies = rules.group.copies
for slot in pairs(copies) do
if not base.overrides[slot] then
local source = copies[slot]
while copies[source] and not base.overrides[source] do
source = copies[source]
end
local list = {}
for _, form in ipairs(forms[source] or {}) do
table.insert(list, form)
end
forms[slot] = list
end
end
end
if forms.depr_p then
forms.nom_p = forms.nom_p or {}
-- A deprecative form that's the same as a virile form (e.g. ''zaklinacze'') isn't a separate form, so don't
-- show it twice.
local virile = {}
for _, form in ipairs(forms.nom_p) do
virile[form.form] = true
end
for _, form in ipairs(forms.depr_p) do
if not virile[form.form] then
table.insert(forms.nom_p, {form = form.form, footnotes = form.footnotes or {"[" .. base.data.notes.deprecative .. "]"}})
end
end
forms.depr_p = nil
end
base.forms = add_word_footnotes(base, forms)
-- Keep the rules the forms came from, and the alternations they used, for the categories.
base.rules = rules
end
-- Join an adjective stem and an ending. If the data's `adjective_dropped` says the last letter of the stem drops before
-- the first letter of the ending, drop it (e.g. ''moj-'' + ''-ich'' → ''moich'').
local function adjective_form(data, stem, ending)
local before = data.adjective_dropped[mw.ustring.sub(stem, -1)]
if before and mw.ustring.sub(ending, 1, mw.ustring.len(before)) == before then
return mw.ustring.sub(stem, 1, -2) .. ending
end
return stem .. ending
end
-- Return the forms of an irregular adjective from `irregular_adjectives`, along with the layout of the table it needs
-- (nil, `dwa` or `plonly`).
local function irregular_adjective_forms(base, word)
local data = base.data
for _, entry in ipairs(data.irregular_adjectives) do
local captured = mw.ustring.match(word, entry.pattern)
if captured or entry.stem and mw.ustring.find(word, entry.pattern) then
local forms = {}
local function add(slot, stem, endings, note)
if type(endings) == "string" then
endings = {endings}
end
for _, ending in ipairs(endings or {}) do
forms[slot] = forms[slot] or {}
local form = ending == "-" and base.lemma or adjective_form(data, stem, ending)
table.insert(forms[slot], {form = form, footnotes = note and {"[" .. note .. "]"} or nil})
end
end
if entry.table ~= "dwa" then
add("nom_m", nil, "-")
end
for _, set in ipairs(entry.sets) do
local stem = (entry.stem or captured) .. (set.add or "")
for slot, endings in pairs(set.endings or {}) do
add(slot, stem, endings, set.note)
for _, target in ipairs(data.adjective_shared[slot] or {}) do
add(target, stem, endings, set.note)
end
end
for slot, endings in pairs(set.own or {}) do
add(slot, stem, endings, set.note)
end
if set.archaic_dative and base.indicators.archdat then
add("dat_mn", stem, set.archaic_dative, data.notes[data.archaic_dative.note])
end
end
return forms, entry.table
end
end
error(("Unrecognized irregular adjective '%s'"):format(word), 0)
end
--[==[
Decline a single adjective. This is the `inflect_word_spec` callback passed to [[Module:inflection utilities]] for
{{tl|pl-adecl}}. The rules (or the lexicon of irregular adjectives) fill the slots; then the overrides apply, followed
by the accusatives taken from other slots (unless overridden) and the footnote for the whole word. An attested table
has the cells given and nothing else.
]==]
local function decline_adjective_word(base)
local data = base.data
local word = base.indicators.decllemma or base.lemma
local forms, layout
if base.attested then
-- The cells given and nothing else, with the dual columns if `du` is given.
forms, layout = attested_forms(base), base.indicators.du and "dual" or nil
elseif base.indicators.irreg then
forms, layout = irregular_adjective_forms(base, word)
elseif base.indicators.lect then
local paradigm = data[data.lect_tables[base.indicators.lect].rules]
if not paradigm.adjective then
spec_error(("The %s rules have no adjective declension"):format(base.lect_name), base.text)
end
forms = paradigm_adjective_forms(data, paradigm, word)
-- With `decllemma`, the lemma itself heads the table (''båbcyn'' declined as ''båbcyny'').
forms.nom_m = {{form = base.lemma}}
elseif base.indicators.num then
forms, layout = numeral_forms(data.numeral_rules, base, word), "plonly"
else
local rules = AdjectiveRules.new(base, word)
-- With `decllemma`, the lemma itself still heads the table (''wart'' declined as ''warty'').
forms = {nom_m = {{form = base.lemma}}}
for _, slot in ipairs(data.adjective_slots) do
if slot ~= "nom_m" and slot ~= "short" and not rules.group.copies[slot] then
forms[slot] = rules:forms(slot)
end
end
if base.indicators.archdat then
local archaic = data.archaic_dative
table.insert(forms.dat_mn, {form = rules.stem .. archaic[1], footnotes = {"[" .. data.notes[archaic.note] .. "]"}})
end
-- Keep the slots that every adjective shares as copies, so that an override of the source carries over.
for slot, source in pairs(rules.group.copies) do
local accusative = mw.ustring.find(slot, "^acc")
if not accusative and not base.overrides[slot] then
forms[slot] = forms[source]
end
end
end
if not base.attested then
for slot, override in pairs(base.overrides) do
local list = {}
for _, value in ipairs(override.values) do
if value.form ~= "" then
table.insert(list, {form = value.form, footnotes = value.footnotes})
end
end
forms[slot] = list
end
for _, pair in ipairs(data.adjective_accusatives) do
local source, target = pair[1], pair[2]
if not base.overrides[target] and forms[source] and not (base.indicators.irreg and forms[target]) then
forms[target] = forms[source]
end
end
end
base.forms = add_word_footnotes(base, forms)
base.layout = layout
end
-- Return the attested tables there are for `template` (`noun` or `adjective`), for the error messages: those of the
-- language's attested lects and its dialectal table, plus the templates of the languages whose tables of that kind are
-- all attested.
local function attested_tables(data, template)
local tables = {}
local codes = {}
for code, lect_table in pairs(data.lect_tables or {}) do
if lect_table.table == "attested" then
table.insert(codes, code)
end
end
table.sort(codes)
for _, code in ipairs(codes) do
table.insert(tables, "<lect:" .. code .. ">")
end
if data.indicators[template].dialectal then
table.insert(tables, "<dialectal>")
end
local languages = {}
for code, language in pairs(M.data.languages) do
if language[template] then
table.insert(languages, code)
end
end
table.sort(languages)
for _, code in ipairs(languages) do
if mw.loadData("Module:zlw-lch-decl/data/" .. code).attested then
table.insert(tables, "{{" .. M.data.languages[code][template] .. "}}")
end
end
return table.concat(tables, ", ")
end
-- Work out the table a base is for: its lect (`lect:CODE`), and whether the table is attested, i.e. has only the cells
-- given (for an attested lect, the dialectal table, or a language whose tables are all attested). Throw an error if
-- `recon` or `du` is given for a table that isn't attested, if a lect tag appears outside the dialectal table, or if a
-- dual slot is given without `du`.
local function resolve_table(base)
local data = base.data
if base.indicators.lect then
base.indicators.lect, base.lect_name = lect_of(data, base.indicators.lect, base.text)
base.lect_table = data.lect_tables[base.indicators.lect]
if not base.lect_table then
local codes = {}
for code in pairs(data.lect_tables) do
table.insert(codes, code)
end
table.sort(codes)
spec_error(("The lect '%s' has no table of its own (the lects with one are %s); give its forms in a "
.. "<dialectal> table"):format(base.indicators.lect, table.concat(codes, ", ")), base.text)
end
end
base.attested = data.attested or base.indicators.dialectal
or base.lect_table and base.lect_table.table == "attested" or nil
for _, name in ipairs({"recon", "du"}) do
if base.indicators[name] and not base.attested then
spec_error(("Only an attested table (%s) takes '%s'"):format(attested_tables(data, base.template), name),
base.text)
end
end
-- A form of a lect can only be tagged in the dialectal table, so that none ends up among the standard forms.
if not base.indicators.dialectal then
local function check(footnotes)
for _, footnote in ipairs(footnotes or {}) do
if mw.ustring.find(footnote, "^%[lect:") then
spec_error(("A lect's form (%s) belongs in a <dialectal> table"):format(footnote), base.text)
end
end
end
check(base.footnotes)
for _, override in pairs(base.overrides) do
for _, value in ipairs(override.values) do
check(value.footnotes)
end
end
end
if not base.indicators.du then
for slot in pairs(base.overrides) do
if mw.ustring.find(slot, "_d$") then
spec_error(("The dual slot '%s' needs the indicator 'du'"):format(slot), base.text)
end
end
end
end
-- Set the fields of a base that the rules use, based on its indicators.
local function normalize_base(base)
base.gender = base:group("gender")
base.animacy = base:group("animacy")
base.number = base:group("number")
base.kind = base:group("kind")
if base.indicators["*"] then
base.reducible = true
elseif base.indicators["-*"] then
base.reducible = false
end
base.quantity = base.indicators["#"] and "full" or base.indicators["-#"] and "none" or nil
if base.gender == "m" and not base.animacy then
base.animacy = "inan"
end
resolve_table(base)
end
------------------------------------------------------------------------------------------------------------------------
-- Output --
------------------------------------------------------------------------------------------------------------------------
--[==[
Object to render the declined words as a table with [[Module:inflection-table]], with a column for each number shown and
a row for each case. Each row has a `data-case` attribute so that scripts can reorder the cases. The cells come from
`show_forms` in [[Module:inflection utilities]], linked with accelerators for the lemma, and the footnotes go under the
table.
]==]
local TableRenderer = {}
TableRenderer.__index = TableRenderer
function TableRenderer.new(spec)
return setmetatable({spec = spec}, TableRenderer)
end
function TableRenderer:numbers()
local numbers = {}
for _, number in ipairs(M.data.numbers) do
if self.spec.numbers[number.code] then
table.insert(numbers, number)
end
end
return numbers
end
-- Return the title of a table: `title=` if given, otherwise what the table is (e.g. "Declension of " or "Attested
-- Middle Polish forms of ") followed by its head, unlinked. `suffix` follows the default title (`default_kind` and the
-- lemma), e.g. the declension kinds of an adjective.
function TableRenderer:title(default_kind, suffix)
local spec = self.spec
if spec.title then
return spec.title
end
local kind, head = default_kind, spec.forms.lemma
if spec.kind_title then
kind, head, suffix = spec.kind_title[1], spec.kind_title[2] or head, nil
end
return kind .. M.links.full_link({lang = spec.lang, alt = head}, "term") .. (suffix or "")
end
-- Return the first lines of a table titled `title`: the frame from [[Module:inflection-table]], with its first row
-- opened.
function TableRenderer:top(title)
return {M.inflection_table.make_top{
title = title,
palette = "blue",
tall = "yes",
lang = self.spec.lang:getCode(),
}}
end
-- Close the table in `lines` with its footnotes and categories, and return its wikitext.
function TableRenderer:finish(lines)
local spec = self.spec
table.insert(lines, M.inflection_table.make_bottom{notes = spec.forms.footnote or ""})
if spec.categories[1] and not spec.nocat then
table.insert(lines, M.utilities.format_categories(spec.categories, spec.lang))
end
return table.concat(lines, "\n")
end
function TableRenderer:render()
local spec = self.spec
local numbers = self:numbers()
local slot_list = {}
for _, case in ipairs(M.data.cases) do
for _, number in ipairs(numbers) do
-- A table with one number doesn't name it in its accelerators, and an attested or lect table has none
-- ("-").
local accel = (spec.attested or spec.lect) and "-" or #numbers > 1 and case.accel .. "|" .. number.accel or case.accel
table.insert(slot_list, {case.code .. "_" .. number.code, accel})
end
end
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
-- A Middle Polish form links to its modern spelling.
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của "))
-- make_top has already opened the first row.
table.insert(lines, '! class="outer" |')
for _, number in ipairs(numbers) do
-- A numberless pronoun (e.g. ''siebie'') has an empty header over its one column.
table.insert(lines, '! class="outer" | ' .. (spec.numberless and "" or number.name))
end
for _, case in ipairs(M.data.cases) do
table.insert(lines, ('|- data-case="%s"'):format(case.code))
table.insert(lines, ('! title="%s" | %s'):format(spec.data.case_titles[case.code], case.name))
for _, number in ipairs(numbers) do
local cell = spec.forms[case.code .. "_" .. number.code]
table.insert(lines, "| " .. (cell or "—"))
end
end
return self:finish(lines)
end
--[==[
The rows of an adjective table, by layout. Each row is a case and its cells, and each cell is a slot and the number of
columns it spans. The regular table has the masculine animate, masculine inanimate, feminine and neuter singular, then
the virile and non-virile plural, as in the former [[Module:pl-adjective]]. The dual table (an attested table with `du`)
puts the dual, masculine and feminine/neuter, between them.
]==]
local ADJECTIVE_LAYOUTS = {
regular = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_mp_pers"},
{"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_p", 2}}},
},
},
plonly = {
columns = {
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_p", 2}}},
{"dat", "dative", {{"dat_p", 2}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_p", 2}}},
{"loc", "locative", {{"loc_p", 2}}},
},
},
-- an attested table with the dual (`du`), between the singular and the plural
dual = {
columns = {
{"singular", 4, {"masculine animate", "masculine inanimate", "feminine", "neuter"}},
{"dual", 2, {"masculine", "feminine/<wbr />neuter"}},
{"plural", 2, {"virile (= masculine personal)", "non-virile"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_m", 2}, {"nom_f"}, {"nom_n"}, {"nom_m_d"}, {"nom_fn_d"},
{"nom_mp_pers"}, {"nom_p_not_mp_pers"}}},
{"gen", "genitive", {{"gen_mn", 2}, {"gen_f"}, {"gen_mn"}, {"gen_d", 2}, {"gen_p", 2}}},
{"dat", "dative", {{"dat_mn", 2}, {"dat_f"}, {"dat_mn"}, {"dat_d", 2}, {"dat_p", 2}}},
{"acc", "accusative", {{"acc_m_an"}, {"acc_m_in"}, {"acc_f"}, {"acc_n"}, {"acc_m_d"}, {"acc_fn_d"},
{"acc_mp_pers"}, {"acc_p_not_mp_pers"}}},
{"ins", "instrumental", {{"ins_mn", 2}, {"ins_f"}, {"ins_mn"}, {"ins_d", 2}, {"ins_p", 2}}},
{"loc", "locative", {{"loc_mn", 2}, {"loc_f"}, {"loc_mn"}, {"loc_d", 2}, {"loc_p", 2}}},
},
},
dwa = {
columns = {
{"plural", 4, {"masculine personal", "masculine non-personal", "feminine", "neuter"}},
},
rows = {
{"nom", "nominative/<wbr />vocative", {{"nom_mp_pers"}, {"nom_mp_npers"}, {"nom_fp"}, {"nom_np"}}},
{"gen", "genitive", {{"gen_p", 4}}},
{"dat", "dative", {{"dat_p", 4}}},
{"acc", "accusative", {{"acc_mp_pers"}, {"acc_mp_npers"}, {"acc_fp"}, {"acc_np"}}},
{"ins", "instrumental", {{"ins_mnp", 2}, {"ins_fp"}, {"ins_mnp"}}},
{"loc", "locative", {{"loc_p", 4}}},
},
},
}
function TableRenderer:renderAdjective()
local spec = self.spec
local layout = ADJECTIVE_LAYOUTS[spec.layout]
local slot_list = {}
for slot, accel in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, (spec.lect or spec.attested) and "-" or accel})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.show_forms(spec.forms, {
lang = spec.lang,
lemmas = spec.lemmas,
slot_list = slot_list,
generate_link = respelled_link(spec),
})
local lines = self:top(self:title("Biến cách của ",
spec.kinds[1] and " (" .. table.concat(spec.kinds, " // ") .. ")" or nil))
-- make_top has already opened the first row. Add the number headers, then the gender headers.
table.insert(lines, '! class="outer" rowspan="2" |')
for _, column in ipairs(layout.columns) do
table.insert(lines, ('! class="outer" colspan="%d" | %s'):format(column[2], column[1]))
end
table.insert(lines, "|- class=\"secondary\"")
for _, column in ipairs(layout.columns) do
for _, header in ipairs(column[3]) do
table.insert(lines, "! " .. header)
end
end
for _, row in ipairs(layout.rows) do
table.insert(lines, ('|- data-case="%s"'):format(row[1]))
table.insert(lines, "! " .. row[2])
for _, cell in ipairs(row[3]) do
local span = cell[2] and ('colspan="%d" | '):format(cell[2]) or ""
table.insert(lines, "| " .. span .. (spec.forms[cell[1]] or "—"))
end
end
if spec.forms.short and spec.forms.short ~= "—" then
table.insert(lines, '|- data-case="short"')
table.insert(lines, "! short")
table.insert(lines, '| colspan="2" | ' .. spec.forms.short)
end
return self:finish(lines)
end
------------------------------------------------------------------------------------------------------------------------
-- The call --
------------------------------------------------------------------------------------------------------------------------
--[==[
Decline a noun call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl` or `zlw-opl`). Return the
alternant multiword spec from [[Module:inflection utilities]], with the fields `forms` (a table mapping each slot to a
list of form objects), `numbers` (a set of `s`, `d` and `p`), `categories`, `title` and `nocat`.
]==]
function export.decline_noun(args, pagename, lang_code)
local data, lang = language_of(lang_code, "noun")
-- The angle brackets are omittable, so a bare word would be read as an indicator; with no spec, decline the page
-- name with no indicators.
local spec_text = args[1] or ""
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
local base = Spec.parse(angle_bracket_spec, "noun", data, lang)
normalize_base(base)
return base
end,
allow_blank_lemma = true,
angle_brackets_omittable = true,
}
local spec = M.inflection_utilities.parse_inflected_text(spec_text, parse_props)
local number, noun
local word_count = 0
M.inflection_utilities.map_word_specs(spec, function()
word_count = word_count + 1
end)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
-- An irregular noun has the gender and animacy of its lexicon entry. They're used if the spec gives none, and
-- giving others is an error.
local irregular = base.indicators.irreg and data.irregular_nouns[base.indicators.decllemma or base.lemma]
if irregular then
if base.gender and (base.gender ~= irregular.gender or base.animacy ~= irregular.animacy) then
spec_error(("The irregular noun '%s' is <%s>"):format(base.lemma,
irregular.gender .. (irregular.animacy and "." .. irregular.animacy or "")), base.text)
end
base.gender, base.animacy = irregular.gender, irregular.animacy
end
base.in_phrase = word_count > 1 and #spec.alternant_or_word_specs > 1 or nil
number = number or base.number
if not base.indicators["+"] and base.gender then
noun = noun or base
end
end)
-- An adjectival word (`+`) agrees with the noun of the phrase, taking whatever gender, animacy and number it
-- doesn't give itself.
M.inflection_utilities.map_word_specs(spec, function(base)
if base.indicators["+"] and noun then
base.gender = base.gender or noun.gender
if base.gender == noun.gender then
base.animacy = base.animacy or noun.animacy
end
base.number = base.number or noun.number
end
if base.indicators["+"] and not base.gender then
error(("The adjectival word '%s' needs a gender, or a noun in the phrase"):format(base.lemma), 0)
end
end)
local slot_list = {}
for _, entry in ipairs(M.data.noun_slots) do
table.insert(slot_list, {entry.slot, entry.slot})
end
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_word,
})
local first
M.inflection_utilities.map_word_specs(spec, function(base)
first = first or base
end)
spec.lang = lang
spec.data = data
spec.numbers = number == "sg" and {s = true} or number == "pl" and {p = true} or {s = true, p = true}
if first.indicators.du then
spec.numbers.d = true
end
-- A collective numeral has only the plural.
if first.indicators.num then
spec.numbers = {p = true}
end
if first.pronoun then
spec.numbers = {}
for _, number_code in ipairs(first.pronoun.numbers) do
spec.numbers[number_code] = true
end
spec.numberless = first.pronoun.numberless
end
spec.categories = {}
-- Only a table of the standard language is categorized; for the lects, the labels of the entry do that.
if not first.attested and not first.indicators.lect then
local function add(name, ...)
table.insert(spec.categories, data.categories[name]:format(...) .. " " .. lang:getCanonicalName())
end
if number == "sg" then
add("singularia_tantum")
elseif number == "pl" then
add("pluralia_tantum")
end
if word_count == 1 then
local indicators = first.indicators
if indicators.irreg then
add("irregular")
elseif indicators.indecl then
add("indeclinable")
elseif indicators["+"] then
add("adjectival")
elseif first.rules and first.rules.used then
local final = final_consonant(data, first.rules.stem)
local stem_type = data.stem_types.velar[final] and "âm vòm" or data.stem_types.soft[final] and "mềm"
or "cứng"
local gender = data.category_genders[first.gender]
if type(gender) == "table" then
gender = gender[first.animacy]
end
-- A plurale tantum has no gender to tell apart, except for a personal one.
if gender and (number ~= "pl" or first.animacy == "pr") then
add("stem", stem_type, gender)
end
local reducible = false
for part in pairs(first.rules.used) do
reducible = reducible or is_mobile(part)
end
if reducible then
add("reducible")
end
local used = first.rules.used
if used.shortened or used.lengthened then
add("quantitative")
end
end
end
end
-- An attested table says what it attests in its title. Its head is the nominative given, or the reconstructed one
-- starred.
spec.attested = first.attested
local head
if first.attested then
local nominative = spec.forms[number == "pl" and "nom_p" or "nom_s"]
head = first.indicators.recon and "*" .. first.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil
end
spec.lect = first.indicators.lect
if first.indicators.lect then
-- A paradigm's table is headed by the lemma, and an attested one by its nominative.
spec.kind_title = {data.lect_titles[first.indicators.lect], first.attested and head or nil}
elseif first.indicators.dialectal then
spec.kind_title = {data.lect_titles.dialectal, head}
elseif data.attested then
spec.kind_title = {"Biến cách của ", head}
end
spec.title = args.title
spec.nocat = args.nocat
spec.lemmas = {pagename}
return spec
end
-- Return the kind of declension of an adjective, for its title and category: `irregular`, or the kind of the first
-- entry in the data's `adjective_kinds` that its lemma matches (hard ''-y'', velar ''-ki'' and ''-gi'', or soft).
local function adjective_kind(base)
if base.indicators.irreg then
return "irregular"
end
local word = base.indicators.decllemma or base.lemma
for _, kind in ipairs(base.data.adjective_kinds) do
if mw.ustring.find(word, kind[1]) then
return kind[2]
end
end
end
--[==[
Decline an adjective call without a frame. `args` are the template's arguments (`1` is the spec, along with `title` and
`nocat`), `pagename` is the page the call is on and `lang_code` is the language code (`pl`). Return the alternant
multiword spec from [[Module:inflection utilities]], with the fields `forms`, `layout` (`regular`, `plonly`, `dwa` or
`dual`), `kinds` (the declension kinds of its words), `pos` (the part of speech of the table, from `pos:` on one of its
words), `categories`, `title` and `nocat`.
]==]
function export.decline_adjective(args, pagename, lang_code)
local data, lang = language_of(lang_code, "adjective")
local parse_props = {
parse_indicator_spec = function(angle_bracket_spec)
return Spec.parse(angle_bracket_spec, "adjective", data, lang)
end,
allow_default_indicator = true,
allow_blank_lemma = true,
}
local spec = M.inflection_utilities.parse_inflected_text(args[1] or pagename, parse_props)
M.inflection_utilities.map_word_specs(spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
base.lemma = M.links.remove_links(base.lemma)
-- The part of speech belongs to the whole table, so only one word may give it.
local pos = base.indicators.pos
if pos then
if not data.parts_of_speech[pos] then
local names = {}
for name in pairs(data.parts_of_speech) do
table.insert(names, name)
end
table.sort(names)
spec_error(("Unrecognized part of speech '%s'; the parts of speech are %s"):format(pos,
table.concat(names, ", ")), base.text)
elseif spec.pos then
spec_error("The part of speech ('pos:') is given on more than one word", base.text)
end
spec.pos = pos
end
resolve_table(base)
end)
local slot_list = {}
for slot in pairs(ADJECTIVE_ACCEL) do
table.insert(slot_list, {slot, slot})
end
table.sort(slot_list, function(a, b) return a[1] < b[1] end)
M.inflection_utilities.inflect_multiword_or_alternant_multiword_spec(spec, {
slot_list = slot_list,
inflect_word_spec = decline_adjective_word,
})
spec.pos = spec.pos or "adjective"
local plural_pos = data.parts_of_speech[spec.pos]
spec.layout, spec.kinds, spec.categories = "regular", {}, {}
local seen = {}
M.inflection_utilities.map_word_specs(spec, function(base)
-- A lect's table names its lect and isn't categorized, and neither is a numeral's. An attested table is headed
-- by the masculine nominative given, or the reconstructed lemma starred.
if base.attested then
local nominative = spec.forms.nom_m
spec.attested = true
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect or "dialectal"], base.indicators.recon and "*" .. base.indicators.recon
or nominative and nominative[1] and M.links.remove_links(nominative[1].form) or nil}
spec.layout = base.layout or base.indicators.plonly and "plonly" or spec.layout
return
elseif base.indicators.lect then
spec.lect = base.indicators.lect
spec.kind_title = {data.lect_titles[spec.lect]}
return
elseif base.indicators.num then
spec.layout = base.layout
return
end
local function add(name, ...)
table.insert(spec.categories, lang:getCanonicalName() .. " " .. data.categories[name]:format(...))
end
local kind = adjective_kind(base)
if not seen[kind] then
seen[kind] = true
table.insert(spec.kinds, kind)
add("adjective_kind", kind, plural_pos)
end
if base.overrides.short then
add("short_forms", plural_pos)
end
if base.indicators.decllemma then
add("irregular_stem", plural_pos)
end
if base.layout or base.indicators.plonly then
spec.layout = base.layout or "plonly"
end
end)
spec.title = args.title
spec.nocat = args.nocat
spec.lang = lang
spec.lemmas = {pagename}
return spec
end
-- Process the arguments of a call of the template of `entry` (`noun` or `adjective`). On the template's own page, a call
-- with no arguments declines the language's example (`examples` in [[Module:zlw-lch-decl/data]]) instead of the page
-- name.
local function process_args(frame, entry)
local language = M.data.languages[frame.args.lang]
return M.parameters.process(frame:getParent().args, {
[1] = {template_default = language and language.examples[entry]},
title = {},
nocat = {type = "boolean"},
json = {type = "boolean"},
pagename = {},
})
end
-- Run the template entry point `entry` (`noun` or `adjective`) on the call of `frame`: decline it with `decline`
-- (`export.decline_noun` or `export.decline_adjective`) and return its table, made by the `TableRenderer` method
-- `render`, or with json=1 the table's data, as `json_data` gives it from the declined spec.
local function run_entry(frame, entry, decline, render, json_data)
local args = process_args(frame, entry)
local spec = decline(args, args.pagename or M.headword_data.pagename, frame.args.lang)
if args.json then
return M.JSON.toJSON(json_data(spec))
end
local renderer = TableRenderer.new(spec)
return renderer[render](renderer)
end
--[==[
Entry point for {{tl|pl-ndecl}} and {{tl|zlw-opl-ndecl}}. Template-callable function to parse and decline a noun given
user-specified arguments and generate a displayable table of the declined forms, or the table's data as JSON with
{{para|json|1}}.
]==]
function export.noun(frame)
return run_entry(frame, "noun", export.decline_noun, "render", function(spec)
return {forms = spec.forms, numbers = spec.numbers, categories = spec.categories, title = spec.title}
end)
end
--[==[
Entry point for {{tl|pl-adecl}}. Template-callable function to parse and decline an adjective given user-specified
arguments and generate a displayable table of the declined forms, or the table's data as JSON with {{para|json|1}}.
]==]
function export.adjective(frame)
return run_entry(frame, "adjective", export.decline_adjective, "renderAdjective", function(spec)
return {forms = spec.forms, layout = spec.layout, kinds = spec.kinds, categories = spec.categories,
title = spec.title}
end)
end
return export
f6tend7d6j36s9w7xhalb9xb50gidtc
Mô đun:zlw-lch-decl/data/pl
828
421110
2573187
2572861
2026-10-24T09:07:23Z
Hiyuune
50834
2573187
Scribunto
text/plain
--[==[
Polish data for [[Module:zlw-lch-decl]]: the declension rules, the stem alternations they use, the irregular words,
the footnotes, and the indicators of {{tl|pl-ndecl}} and {{tl|pl-adecl}}.
TERMINOLOGY:
* "stem" = The lemma minus its nominative ending, e.g. ''kobiet-'' from ''kobieta'' and ''okn-'' from ''okno''. A
masculine noun ending in a consonant is its own stem (''pies'').
* "group" = The nouns that share one set of rules, i.e. those with the same gender (`m-pr` masculine personal,
`m-anml` masculine animal, `m-in` masculine inanimate, `f`, `n`), kind (common nouns, surnames, given names, place names and other names) and
nominative ending (`""` for a consonant, `a`, `o`, `e`, `ę`, `um`, `i`). Pluralia tantum have groups of their own,
by the ending of their nominative plural.
* "rule" = The forms of one slot for the nouns of a group whose stem ends in particular letters. The rule for the
longest such ending applies, and `""` holds the group's default. A form is an ending added either to the stem or to
the stem changed by an alternation (e.g. with `stem = "palatal"`, ''kobiet-'' becomes ''kobieci-'' before ''-e'').
* "copy" = A slot whose forms are always those of another slot in its group, e.g. the accusative singular of a
personal noun is its genitive.
]==]
local data = {}
------------------------------------------------------------------------------------------------------------------------
-- Alternations --
------------------------------------------------------------------------------------------------------------------------
-- The vowels, used by the rules that look for the last syllable of a stem.
data.vowels = "aąeęioóuy"
--[==[
The alternations a rule can ask for (`stem = "..."`). Several are joined with "+", in this order:
* `reduced`: drop the mobile ''e'' of the stem's last syllable (''pies'' → ''ps-'', ''sweter'' → ''swetr-'').
* `inserted_e`, `inserted_ie`: put in ''e'' or ''ie'' before the last consonant (''matk-'' → ''matek'', ''okn-'' →
''okien'').
* `truncated`: drop the end of the stem given by `truncate` (''Amerykanin'' → ''Amerykan-'', ''Amerykanie'').
* `spelled`: write the end of the stem as `spelled` gives it before an ending (''appendix'' → ''appendiks-'').
* `shortened`: change ''ó'' to ''o'' and ''ą'' to ''ę'' in the last syllable (''stół'' → ''stoł-'', ''ząb'' →
''zęb-'').
* `lengthened`: change ''o'' to ''ó'' and ''ę'' to ''ą'' in the last syllable (''drog-'' → ''dróg'', ''ręk-'' →
''rąk'').
* `fronted`: change ''o'' or ''a'' to ''e'' in the last syllable (''uczony'' → ''uczeni'', ''sąsiad'' → ''sąsiedzi'').
* `soft`, `palatal`, `virile`: change the last consonant (or two) using one of the tables below.
]==]
-- How `shortened` (''stół'' → ''stołu''), `lengthened` (''droga'' → ''dróg'') and `fronted` (''uczony'' → ''uczeni'',
-- ''sąsiad'' → ''sąsiedzi'') change the vowel of a stem's last syllable.
data.shorten = { ["ó"] = "o", ["ą"] = "ę" }
data.lengthen = { ["o"] = "ó", ["ę"] = "ą" }
data.front = { ["o"] = "e", ["a"] = "e" }
-- How `truncated` cuts a stem (the plural of the nouns in ''-anin'' has no ''-in'': ''mieszczanin'' → ''mieszczanie'',
-- ''mieszczan'') and how `spelled` writes one before an ending (''appendix'' → ''appendiksu'', ''appendiksie'').
data.truncate = { nin = "n" }
data.spelled = { x = "ks" }
-- How a soft consonant at the end of a stem is written before a vowel, e.g. ''koń'' → ''konia''.
data.soft = { ["dź"] = "dzi", ["ć"] = "ci", ["ń"] = "ni", ["ś"] = "si", ["ź"] = "zi" }
-- The reverse: how a stem's soft consonant spelled with ''i'' is written at the end of a word with no ending, e.g.
-- ''danie'' → ''dań''. The module also uses `soft` to respell a final soft consonant before a vowel, as Polish
-- spelling always does (''niedźwiedź'' + ''-a'' → ''niedźwiedzia''), so a rule's ending doesn't need `soft` for that.
data.final_soft = { ["dzi"] = "dź", ["ci"] = "ć", ["ni"] = "ń", ["si"] = "ś", ["zi"] = "ź" }
-- The consonants that stay soft when a mobile ''ie'' before them drops, e.g. ''goniec'' → ''gońca'', ''wrzesień'' →
-- ''września''. Before the other consonants, the ''i'' only marked their softness and goes with it (''pies'' →
-- ''psa'', ''łokieć'' → ''łokcia'').
data.reduced_soft = { n = "ń", s = "ś", z = "ź", c = "ć", dz = "dź" }
-- The first palatalization, before ''-e'' (in the locative singular and the feminine dative singular).
data.palatal = {
-- After ''c'', ''r'' and ''s'', the ''z'' of ''-zn-'' and ''-zł-'' is part of a digraph and doesn't soften
-- (''logiczny'' → ''logiczni'', ''Leszno'' → ''Lesznie'', ''zeszły'' → ''zeszli'', but ''żelazny'' → ''żelaźni'').
["czn"] = "czni", ["rzn"] = "rzni", ["szn"] = "szni", ["czł"] = "czl", ["rzł"] = "rzl", ["szł"] = "szl",
["st"] = "ści", ["zd"] = "ździ", ["sł"] = "śl", ["zł"] = "źl", ["sn"] = "śni", ["zn"] = "źni", ["sm"] = "śmi",
["zm"] = "źmi", ["ch"] = "sz", ["p"] = "pi", ["b"] = "bi", ["f"] = "fi", ["w"] = "wi", ["m"] = "mi", ["n"] = "ni",
["s"] = "si", ["z"] = "zi", ["t"] = "ci", ["d"] = "dzi", ["r"] = "rz", ["ł"] = "l", ["k"] = "c", ["g"] = "dz",
["h"] = "ż",
}
-- The tooltip over the row header of each case, giving its Polish name and questions.
data.case_titles = {
nom = "mianownik (kto? co?)", gen = "dopełniacz (kogo? czego?)", dat = "celownik (komu? czemu?)",
acc = "biernik (kogo? co?)", ins = "narzędnik (kim? czym?)", loc = "miejscownik (o kim? o czym?)", voc = "wołacz (o!)",
}
-- The nominative endings split off a lemma to get its stem, by gender (and `plural` for a plurale tantum), tried in
-- order. For example, ''kobieta'' is ''kobiet-'' plus ''-a'', a masculine in ''-y'' or ''-i'' is an adjectival noun
-- (''Kowalski''), and one in ''-e'' declines as an adjective in the singular (''Bethke'', ''Bethkego'', ''Bethkowie'').
-- A lemma with none of them is its own stem (''pies'').
data.nominative_endings = {
m = { "a", "o", "y", "i", "e" },
f = { "a", "i" },
n = { "um", "o", "e", "ę" },
plural = { "i", "y", "e", "a" },
}
-- The endings of `nominative_endings` that are only a nominative after a consonant, by gender. After a vowel they belong
-- to the stem (''playboy'', ''playboya''; ''Halley'', ''Halleya'').
data.nominative_after_consonant = { m = { y = true, i = true, e = true } }
-- The mobile vowels that `reduced` drops, tried in order: ''ie'' after a consonant, which stays soft according to
-- `soften` (''goniec'' → ''gońc-''), and ''e'' (''pies'' → ''ps-'').
data.mobile_vowels = {
{ "ie", after_consonant = true, soften = "reduced_soft" },
{ "e" },
}
-- The mobile vowel that `*` puts into a bare form: ''ie'' after the letters in `after` (''okno'' → ''okien'', ''igła''
-- → ''igieł''), and otherwise `default` (''matka'' → ''matek'').
data.inserted_vowel = { default = "e", after = { k = "ie", g = "ie" } }
-- The vowel used to spell a soft consonant before another vowel (''koń'' + ''-a'' → ''konia''). An ending that starts
-- with the same vowel merges with it (''goleń'' + ''-i'' → ''goleni'').
data.soft_vowel = "i"
-- The digraphs a stem can end in, which count as one consonant (for the stem type in the categories, and for Standard
-- Kurpie).
data.digraphs = { ch = true, cz = true, dz = true, ["dź"] = true, ["dż"] = true, rz = true, sz = true }
-- The softening in the masculine personal nominative plural (''student'' → ''studenci'', ''Polak'' → ''Polacy'').
data.virile = {
["st"] = "ści", ["ch"] = "s", ["t"] = "c", ["d"] = "dz", ["r"] = "rz", ["k"] = "c", ["g"] = "dz", ["ł"] = "l",
["sz"] = "s", ["s"] = "s", ["z"] = "z", ["n"] = "n", ["p"] = "p", ["b"] = "b", ["m"] = "m", ["w"] = "w",
["f"] = "f",
}
------------------------------------------------------------------------------------------------------------------------
-- Notes --
------------------------------------------------------------------------------------------------------------------------
-- The footnotes a rule or an override can give a form, by key: `note = "dated"` in a rule, or `[dated]` in a spec.
data.notes = {
archaic = "cổ xưa",
colloquial = "thông tục",
dated = "lỗi thời",
deprecative = "từ miệt thị",
dialectal = "phương ngữ",
humorous = "từ hài hước",
literary = "ngôn ngữ văn chương",
obsolete = "không còn dùng",
pejorative = "nghĩa xấu",
proscribed = "proscribed",
rare = "hiếm",
regional = "từ địa phương",
vulgar = "thô tục",
-- Notes for the forms of a pronoun that are only clitics (''go'', ''mi'') or only follow a preposition (''niego'').
unstressed = "không nhấn trọng âm",
after_preposition = "sau giới từ",
}
------------------------------------------------------------------------------------------------------------------------
-- Indicators --
------------------------------------------------------------------------------------------------------------------------
--[==[
The indicators of each template, by name. Indicators with the same `group` exclude each other, and the group names
what they set (read with `Spec:group`). `sets` is the value the indicator gives its group if that isn't its own name,
and `value` means it takes a value (e.g. `decllemma:dń`).
]==]
data.indicators = {
noun = {
m = { group = "gender" }, f = { group = "gender" }, n = { group = "gender" },
pr = { group = "animacy" }, anml = { group = "animacy" }, inan = { group = "animacy" },
sg = { group = "number" }, pl = { group = "number" },
["*"] = { group = "reducible" }, ["-*"] = { group = "reducible" },
["#"] = { group = "quantity" }, ["-#"] = { group = "quantity" },
surname = { group = "kind" }, given = { group = "kind" }, place = { group = "kind" },
proper = { group = "kind" },
irreg = { group = "type" }, indecl = { group = "type" }, ["!"] = { group = "type" }, ["+"] = { group = "type" },
pron = { group = "type" }, num = { group = "type" },
decllemma = { value = "word" },
lect = { group = "table", value = "code" }, dialectal = { group = "table" },
recon = { value = "word" }, du = {},
},
adjective = {
irreg = {}, plonly = {}, archdat = {},
decllemma = { value = "word" },
lect = { group = "table", value = "code" }, dialectal = { group = "table" }, num = {},
recon = { value = "word" }, du = {},
pos = { value = "part of speech" },
},
}
-- The parts of speech an adjective table can be categorized under (given with `pos:` on one of its words, with
-- `adjective` as the default), along with the plural its categories use ("Polish hard pronouns").
data.parts_of_speech = {
adjective = "tính từ",
pronoun = "đại từ",
determiner = "từ hạn định",
numeral = "số từ",
suffix = "hậu tố",
}
------------------------------------------------------------------------------------------------------------------------
-- Lects --
------------------------------------------------------------------------------------------------------------------------
--[==[
The lects that have a table of their own (`lect:CODE`), by their code in [[Module:zlw-lch-IPA/data/pl]]. An
"attested" table lists the forms given and nothing else (`respelling` gives the link target of each form), and a
"paradigm" generates the forms from the `rules` named. The forms of any other lect go in the `dialectal` table, each
tagged with its lect. The names of the lects are read from [[Module:zlw-lch-IPA/data/pl]].
]==]
data.lect_tables = {
-- The Middle Polish forms link to their modern spelling, using `middle_polish_respelling`.
mpl = { table = "attested", respelling = "middle_polish_respelling" },
-- The Standard Kurpie forms are generated from `kurpie`.
skur = { table = "paradigm", rules = "kurpie" },
}
-- The data module of the lects, with their codes, names and aliases.
data.lect_module = "Module:zlw-lch-IPA/data/pl"
-- The start of the title of a lect's table (or of the dialectal table), before its head.
data.lect_titles = {
mpl = "Attested Middle Polish forms of ",
skur = "Standard Kurpian declension of ",
dialectal = "Attested dialectal forms of ",
}
------------------------------------------------------------------------------------------------------------------------
-- Categories --
------------------------------------------------------------------------------------------------------------------------
--[==[
The categories of a table of the standard language, each after the language's name ("Polish singularia tantum"). A
noun table of one word is categorized by its stem type and gender (`stem`, e.g. "velar feminine nouns"), by what its
forms show (`reducible` for a mobile ''e'', `quantitative` for ''ó''/''o'' or ''ą''/''ę''), and by its type
(`irregular`, `adjectival`, `indeclinable`). A phrase, a pronoun or a numeral is only categorized by its number. An
adjective table is categorized by its kind and part of speech (`adjective_kind`, e.g. "hard adjectives" or "soft
pronouns"), and by any short forms and irregular stem.
]==]
data.categories = {
singularia_tantum = "chỉ có số ít",
pluralia_tantum = "chỉ có số nhiều",
stem = "Danh từ %s %s",
reducible = "Danh từ với thân từ rút gọn",
quantitative = "nouns with quantitative vowel alternation",
irregular = "Danh từ bất quy tắc",
adjectival = "Danh tính từ",
indeclinable = "Danh từ không biến cách",
adjective_kind = "%s %s",
short_forms = "%s với dạng ngắn",
irregular_stem = "%s với thân từ bất quy tắc",
}
-- The gender of a noun as its stem category names it, by gender and (for masculines) animacy.
data.category_genders = {
m = { pr = "giống đực nhân xưng", anml = "giống đực hữu sinh", inan = "giống đực vô sinh" },
f = "giống cái",
n = "giống trung",
}
-- The stem type of a noun by the last consonant of its stem: velar, soft (including the functionally soft ''c'',
-- ''cz'', ''dz'', ''dż'', ''rz'', ''sz'' and ''ż''), or otherwise hard.
data.stem_types = {
velar = { k = true, g = true, ch = true },
soft = {
["ć"] = true, ["ń"] = true, ["ś"] = true, ["ź"] = true, ["dź"] = true, j = true, l = true, i = true,
c = true, cz = true, dz = true, ["dż"] = true, rz = true, sz = true, ["ż"] = true,
},
}
-- The Middle Polish letters that are respelled in the link target of a form (''ptåka'' links to [[ptaka]]). The form
-- itself is shown as written.
data.middle_polish_respelling = {
["å"] = "a", ["á"] = "a", ["é"] = "e",
["Å"] = "A", ["Á"] = "A", ["É"] = "E",
}
--[==[
The Standard Kurpie paradigm (`lect:skur`)
* `palatal`: what the last consonant (or cluster) of a stem becomes before an ending with `stem = "palatal"`. The
velars only change before the ''-e'' of a feminine; a masculine or neuter velar takes ''-u''.
* `hardened`: the consonants after which an ending's ''ï'' is written ''y'' (''ulicy'', ''nocy'').
* `soft` and `velar`: the last consonants that make a stem soft or velar, which decide the type of a lemma.
* `nouns[GENDER][TYPE]`: the ending of each slot, as in `noun_groups` (a string, or `{ ending, stem = "palatal" }`).
The type comes from the lemma; see `paradigm_type` in [[Module:zlw-lch-decl]].
* `copies[GENDER]` and `animate_copies[ANIMACY]`: the slots that take the forms of another slot.
* `clear`, `clear_before_nasal` and `nasals`: the alternation of `#`, by which the slanted vowel of the last syllable
of a consonant-final lemma is clear before an ending (''kśądz'', ''kśę̈dza''). Before one of the `nasals`, where
''o'' is always written ''ó'', the slanted ''ó'' alternates with ''a''.
* `adjective`: the endings of the single adjective declension, by slot of `adjective_slots`, added to the lemma minus
its last letter.
]==]
data.kurpie = {
palatal = {
b = "bź", p = "pś", f = "ś", w = "ź", m = "ń", s = "ś", z = "ź", t = "ć", d = "dź", n = "ń", r = "rz",
["ł"] = "l", ch = "s", k = "c", g = "dz", st = "ść", zd = "źdź",
},
hardened = { c = true, cz = true, dz = true, ["dż"] = true, rz = true, sz = true, ["ż"] = true },
-- The type of a lemma, by gender. Take the first entry whose ending the lemma has (`""` for none; with
-- `consonant_final`, only if it doesn't end in one of the `vowels`). The type is that of the first class in the
-- entry's `by_final` that has the last consonant of the stem, and otherwise `default`; it is a type of the gender
-- `declension` if the entry gives one.
types = {
f = {
{ ending = "a", by_final = { { "soft", "soft" }, { "hardened", "soft" } }, default = "hard" },
-- After a soft consonant, the ending is written ''-å'' (''sukńå'').
{ ending = "å", default = "soft" },
{ ending = "", by_final = { { "soft", "soft_consonant" } }, default = "hard_consonant" },
},
n = {
{ ending = "um", default = "latinate" },
-- A final ''ę'' is written ''ë'' (''wyńë'').
{ ending = "ë", default = "nasal" },
-- A soft stem in ''-o'' is a j-stem (''jajo'').
{ ending = "o", by_final = { { "velar", "velar" }, { "hardened", "hardened" }, { "soft", "soft" } },
default = "hard" },
{ ending = "e", by_final = { { "hardened", "hardened" } }, default = "soft" },
},
m = {
{ ending = "", consonant_final = true,
by_final = { { "velar", "velar" }, { "soft", "soft" }, { "hardened", "soft" } }, default = "hard" },
-- An animate masculine in ''-a'' or ''-å'' (''starosta'', ''sę̈dźå'') declines as a feminine, with the
-- accusative plural of its animacy.
{ ending = "a", declension = "f", by_final = { { "soft", "soft" }, { "hardened", "soft" } }, default = "hard" },
{ ending = "å", declension = "f", default = "soft" },
},
},
-- The nominative plural endings a plurale tantum can have, tried in order (''Ńëmcy'').
plural_nominatives = { "y", "ï", "e", "a" },
vowels = "aąeęioóuyåéëï",
-- A personal or animal velar has a type of its own, with the genitive and accusative in ''-a'' (''ptaka'').
animate_types = { velar = "animate_velar" },
-- How the first letter of an ending is written after a hardened consonant (''ï'' as ''y'').
hardened_spelling = { ["ï"] = "y" },
soft = { ["ć"] = true, ["ń"] = true, ["ś"] = true, ["ź"] = true, ["dź"] = true, j = true, l = true },
velar = { k = true, g = true, ch = true },
-- The consonants after which an adjective has ''-ï'' for ''-y'' (''głupśï'').
adjective_soft = { ["ś"] = true, ["ź"] = true, ["ć"] = true, ["dź"] = true, ["ń"] = true, j = true },
clear = { ["ó"] = "o", ["é"] = "e", ["å"] = "a", ["ą"] = "ę̈" },
clear_before_nasal = { ["ó"] = "a" },
nasals = { m = true, n = true, ["ń"] = true },
nouns = {
m = {
hard = {
nom_p = "y", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm", acc_s = "a",
ins_s = "ëm", ins_p = "ańï", loc_s = { "e", stem = "palatal" }, loc_p = "ach",
},
velar = {
nom_p = "y", gen_s = "u", gen_p = "ów", dat_s = "oźu", dat_p = "óm", acc_s = "a",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
-- A personal or animal velar takes the genitive (and accusative) in ''-a'' (''ptaka'').
animate_velar = {
nom_p = "y", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm", acc_s = "a",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
soft = {
nom_p = "e", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm", acc_s = "a",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
},
f = {
hard = {
nom_p = "y", gen_s = "y", gen_p = "ów", dat_s = { "e", stem = "palatal" }, dat_p = "óm", acc_s = "ë",
ins_s = "ó", ins_p = "ańï", loc_s = { "e", stem = "palatal" }, loc_p = "ach", voc_s = "o",
},
soft = {
nom_p = "e", gen_s = "ï", gen_p = "ów", dat_s = "ï", dat_p = "óm", acc_s = "ë",
ins_s = "ó", ins_p = "ańï", loc_s = "ï", loc_p = "ach", voc_s = "o",
},
hard_consonant = {
nom_p = "e", gen_s = "y", gen_p = "ów", dat_s = "y", dat_p = "óm", acc_s = "",
ins_s = "ó", ins_p = "ańï", loc_s = "y", loc_p = "ach", voc_s = "y",
},
soft_consonant = {
nom_p = "e", gen_s = "ï", gen_p = "ów", dat_s = "ï", dat_p = "óm", acc_s = "",
ins_s = "ó", ins_p = "ańï", loc_s = "ï", loc_p = "ach", voc_s = "ï",
},
},
n = {
hard = {
nom_p = "a", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm",
ins_s = "ëm", ins_p = "ańï", loc_s = { "e", stem = "palatal" }, loc_p = "ach",
},
velar = {
nom_p = "a", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
soft = {
nom_p = "a", gen_s = "å", gen_p = "ów", dat_s = "u", dat_p = "óm",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
hardened = {
nom_p = "a", gen_s = "a", gen_p = "ów", dat_s = "oźu", dat_p = "óm",
ins_s = "ëm", ins_p = "ańï", loc_s = "u", loc_p = "ach",
},
nasal = {
nom_p = "óna", gen_s = "ëńå", gen_p = "ónów", dat_s = "ëńu", dat_p = "ónóm",
ins_s = "ëńëm", ins_p = "ónańï", loc_s = "ëńu", loc_p = "ónach",
},
latinate = {
nom_p = "a", gen_s = "um", gen_p = "ów", dat_s = "um", dat_p = "óm",
ins_s = "um", ins_p = "ańï", loc_s = "um", loc_p = "ach",
},
},
},
copies = {
m = { voc_s = "loc_s", voc_p = "nom_p" },
f = { acc_p = "nom_p", voc_p = "nom_p" },
n = { acc_s = "nom_s", voc_s = "nom_s", acc_p = "nom_p", voc_p = "nom_p" },
},
animate_copies = {
pr = { acc_p = "gen_p" },
anml = { acc_p = "nom_p" },
inan = { acc_s = "nom_s", acc_p = "nom_p" },
},
-- The other slots are shared as in the standard tables (e.g. the dative and locative feminine come from the
-- genitive), and the plural has one nominative for both genders.
adjective = {
nom_n = "e", nom_f = "å", nom_mp_pers = "e", nom_p_not_mp_pers = "e",
gen_mn = "égo", gen_f = "éj", gen_p = "éch",
dat_mn = "ëmu", dat_p = "ëm",
acc_f = "ó",
ins_mn = "ëm", ins_p = "ëńï",
},
}
-- The rule gender of each gender and animacy of a call.
data.rule_gender = {
m = { pr = "m-pr", anml = "m-anml", inan = "m-in" },
f = "f",
n = "n",
}
------------------------------------------------------------------------------------------------------------------------
-- Lexicon --
------------------------------------------------------------------------------------------------------------------------
-- The slots of a noun in the order the lexicon lists them in.
data.slot_order = {
"nom_s", "gen_s", "dat_s", "acc_s", "ins_s", "loc_s", "voc_s",
"nom_p", "gen_p", "dat_p", "acc_p", "ins_p", "loc_p", "voc_p",
}
-- The irregular nouns of `<irreg>`, by lemma, with their gender and animacy and every form, in `slot_order`.
data.irregular_nouns = {
["brat"] = { gender = "m", animacy = "pr",
"brat", "brata", "bratu", "brata", "bratem", "bracie", "bracie",
"bracia", "braci", "braciom", "braci", "braćmi", "braciach", "bracia",
},
["dziecko"] = { gender = "n",
"dziecko", "dziecka", "dziecku", "dziecko", "dzieckiem", "dziecku", "dziecko",
"dzieci", "dzieci", "dzieciom", "dzieci", "dziećmi", "dzieciach", "dzieci",
},
["ksiądz"] = { gender = "m", animacy = "pr",
"ksiądz", "księdza", "księdzu", "księdza", "księdzem", "księdzu", "księże",
"księża", "księży", "księżom", "księży", "księżmi", "księżach", "księża",
},
["książę"] = { gender = "m", animacy = "pr",
"książę", "księcia", "księciu", "księcia", "księciem", "księciu", "książę",
"książęta", "książąt", "książętom", "książąt", "książętami", "książętach", "książęta",
},
["rok"] = { gender = "m", animacy = "inan",
"rok", "roku", "rokowi", "rok", "rokiem", "roku", "roku",
"lata", "lat", "latom", "lata", "latami", "latach", "lata",
},
["arcyksiążę"] = { gender = "m", animacy = "pr",
"arcyksiążę", "arcyksięcia", "arcyksięciu", "arcyksięcia", "arcyksięciem", "arcyksięciu", "arcyksiążę",
"arcyksiążęta", "arcyksiążąt", "arcyksiążętom", "arcyksiążąt", "arcyksiążętami", "arcyksiążętach",
"arcyksiążęta",
},
}
------------------------------------------------------------------------------------------------------------------------
-- Pronouns, numerals and noun rules --
------------------------------------------------------------------------------------------------------------------------
--[==[
The pronouns of `<pron>`, by lemma, with the numbers of the table (`numberless` for ''siebie'') and the forms of each
slot, each a string or `{ form, notes = { KEY... } }` with keys of `notes`. A pronoun made of one of these plus an
ending in `pronoun_suffixes` (e.g. ''cośkolwiek'') declines like the pronoun, with the ending after every form.
]==]
data.pronouns = {
["co"] = {
numbers = { "s" },
nom_s = { "co" },
gen_s = { "czego", { "co", notes = { "rare" } } },
dat_s = { "czemu" },
acc_s = { "co" },
ins_s = { "czym" },
loc_s = { "czym" },
},
["cokolwiek"] = {
numbers = { "s" },
nom_s = { "cokolwiek" },
gen_s = { "czegokolwiek", { "cokolwiek", notes = { "rare" } } },
dat_s = { "czemukolwiek" },
acc_s = { "cokolwiek" },
ins_s = { "czymkolwiek" },
loc_s = { "czymkolwiek" },
},
["coś"] = {
numbers = { "s" },
nom_s = { "coś" },
gen_s = { "czegoś", { "coś", notes = { "rare" } } },
dat_s = { "czemuś" },
acc_s = { "coś" },
ins_s = { "czymś" },
loc_s = { "czymś" },
},
["cóż"] = {
numbers = { "s" },
nom_s = { "cóż" },
gen_s = { "czegoż", "czegóż", { "cóż", notes = { "rare" } } },
dat_s = { "czemuż" },
acc_s = { "cóż" },
ins_s = { "czymże" },
loc_s = { "czymże" },
},
["ja"] = {
numbers = { "s" },
nom_s = { "ja" },
gen_s = { "mnie", { "mię", notes = { "unstressed", "rare" } } },
dat_s = { "mnie", { "mi", notes = { "unstressed" } } },
acc_s = { "mnie", { "mię", notes = { "unstressed", "rare" } } },
ins_s = { "mną" },
loc_s = { "mnie" },
},
["kto"] = {
numbers = { "s" },
nom_s = { "kto" },
gen_s = { "kogo" },
dat_s = { "komu" },
acc_s = { "kogo" },
ins_s = { "kim" },
loc_s = { "kim" },
},
["ktokolwiek"] = {
numbers = { "s" },
nom_s = { "ktokolwiek" },
gen_s = { "kogokolwiek" },
dat_s = { "komukolwiek" },
acc_s = { "kogokolwiek" },
ins_s = { "kimkolwiek" },
loc_s = { "kimkolwiek" },
},
["ktoś"] = {
numbers = { "s" },
nom_s = { "ktoś" },
gen_s = { "kogoś" },
dat_s = { "komuś" },
acc_s = { "kogoś" },
ins_s = { "kimś" },
loc_s = { "kimś" },
},
["któż"] = {
numbers = { "s" },
nom_s = { "któż" },
gen_s = { "kogoż", "kogóż" },
dat_s = { "komuż" },
acc_s = { "kogoż", "kogóż" },
ins_s = { "kimże" },
loc_s = { "kimże" },
},
["my"] = {
numbers = { "p" },
nom_p = { "my" },
gen_p = { "nas" },
dat_p = { "nam" },
acc_p = { "nas" },
ins_p = { "nami" },
loc_p = { "nas" },
voc_p = { "my" },
},
["nic"] = {
numbers = { "s" },
nom_s = { "nic" },
gen_s = { "nic", "niczego" },
dat_s = { "niczemu" },
acc_s = { "nic" },
ins_s = { "niczym" },
loc_s = { "niczym" },
},
["nikt"] = {
numbers = { "s" },
nom_s = { "nikt" },
gen_s = { "nikogo" },
dat_s = { "nikomu" },
acc_s = { "nikogo" },
ins_s = { "nikim" },
loc_s = { "nikim" },
},
["on"] = {
numbers = { "s" },
nom_s = { "on" },
gen_s = { "jego", { "go", notes = { "unstressed" } }, { "niego", notes = { "after_preposition" } } },
dat_s = { "jemu", { "mu", notes = { "unstressed" } }, { "niemu", notes = { "after_preposition" } } },
acc_s = { "jego", { "go", notes = { "unstressed" } }, { "niego", notes = { "after_preposition" } } },
ins_s = { "nim" },
loc_s = { "nim" },
},
["ona"] = {
numbers = { "s" },
nom_s = { "ona" },
gen_s = { "jej", { "niej", notes = { "after_preposition" } } },
dat_s = { "jej", { "niej", notes = { "after_preposition" } } },
acc_s = { "ją", { "nią", notes = { "after_preposition" } } },
ins_s = { "nią" },
loc_s = { "niej" },
},
["one"] = {
numbers = { "p" },
nom_p = { "one" },
gen_p = { "ich", { "nich", notes = { "after_preposition" } } },
dat_p = { "im", { "nim", notes = { "after_preposition" } } },
acc_p = { "je", { "nie", notes = { "after_preposition" } } },
ins_p = { "nimi" },
loc_p = { "nich" },
},
["oni"] = {
numbers = { "p" },
nom_p = { "oni" },
gen_p = { "ich", { "nich", notes = { "after_preposition" } } },
dat_p = { "im", { "nim", notes = { "after_preposition" } } },
acc_p = { "ich", { "nich", notes = { "after_preposition" } } },
ins_p = { "nimi" },
loc_p = { "nich" },
},
["ono"] = {
numbers = { "s" },
nom_s = { "ono" },
gen_s = { "jego", { "go", notes = { "unstressed" } }, { "niego", notes = { "after_preposition" } } },
dat_s = { "jemu", { "mu", notes = { "unstressed" } }, { "niemu", notes = { "after_preposition" } } },
acc_s = { "je", { "nie", notes = { "after_preposition" } } },
ins_s = { "nim" },
loc_s = { "nim" },
},
["siebie"] = {
numbers = { "s" }, numberless = true,
gen_s = { "siebie", "się" },
dat_s = { "sobie", "se" },
acc_s = { "siebie", "się" },
ins_s = { "sobą" },
loc_s = { "sobie", "se" },
},
["ty"] = {
numbers = { "s" },
nom_s = { "ty" },
gen_s = { "ciebie", { "cię", notes = { "unstressed" } } },
dat_s = { "tobie", { "ci", notes = { "unstressed" } } },
acc_s = { "ciebie", { "cię", notes = { "unstressed" } } },
ins_s = { "tobą" },
loc_s = { "tobie" },
voc_s = { "ty", { "te", notes = { "proscribed", "colloquial" } } },
},
["wszystko"] = {
numbers = { "s" },
nom_s = { "wszystko" },
gen_s = { "wszystkiego" },
dat_s = { "wszystkiemu" },
acc_s = { "wszystko" },
ins_s = { "wszystkim" },
loc_s = { "wszystkim" },
},
["wy"] = {
numbers = { "p" },
nom_p = { "wy" },
gen_p = { "was" },
dat_p = { "wam" },
acc_p = { "was" },
ins_p = { "wami" },
loc_p = { "was" },
voc_p = { "wy" },
},
}
data.pronoun_suffixes = { "śkolwiek", "kolwiek", "ś" }
--[==[
The numerals of `<num>`, by the end of their lemma (the longest one a lemma ends in applies). `numeral_rules` has the
cardinals of {{tl|pl-adecl}} (''pięć'', ''trzy'', ''-naście'', ''-set''), with a virile and a non-virile column in the
slots of `adjective_slots`, and `collective_rules` has the collectives of {{tl|pl-ndecl}} (''pięcioro'', ''dwoje''), in
the plural slots of a noun. Each slot has the endings that follow the lemma minus its key, as in `noun_groups`, and the
comment on each rule names the numerals it was made from.
]==]
data.numeral_rules = {
["a"] = { -- kilka
nom_mp_pers = "u", nom_p_not_mp_pers = "a", gen_p = "u", dat_p = "u", acc_mp_pers = "u", acc_p_not_mp_pers = "a", ins_p = { "oma", "u" }, loc_p = "u",
},
["adziesiąt"] = { -- kilkadziesiąt
nom_mp_pers = { "udziesięciu", { "udziesiąt", note = "dated" } }, nom_p_not_mp_pers = "adziesiąt", gen_p = { "udziesięciu", { "udziesiąt", note = "dated" } }, dat_p = { "udziesięciu", { "udziesiąt", note = "dated" } }, acc_mp_pers = { "udziesięciu", { "udziesiąt", note = "dated" } }, acc_p_not_mp_pers = "adziesiąt", ins_p = { "udziesięcioma", "udziesięciu", { "udziesiąt", note = "dated" } }, loc_p = { "udziesięciu", { "udziesiąt", note = "dated" } },
},
["adzieścia"] = { -- dwadzieścia
nom_mp_pers = "udziestu", nom_p_not_mp_pers = "adzieścia", gen_p = "udziestu", dat_p = "udziestu", acc_mp_pers = "udziestu", acc_p_not_mp_pers = "adzieścia", ins_p = { "udziestoma", "udziestu" }, loc_p = "udziestu",
},
["akroć"] = { -- dwakroć
nom_mp_pers = "ukroć", nom_p_not_mp_pers = "akroć", gen_p = "ukroć", dat_p = "ukroć", acc_mp_pers = "ukroć", acc_p_not_mp_pers = "akroć", ins_p = { "ukroć", { "omakroć", note = "rare" } }, loc_p = "ukroć",
},
["anaście"] = { -- dwanaście, kilkanaście
nom_mp_pers = "unastu", nom_p_not_mp_pers = "anaście", gen_p = "unastu", dat_p = "unastu", acc_mp_pers = "unastu", acc_p_not_mp_pers = "anaście", ins_p = { "unastoma", "unastu" }, loc_p = "unastu",
},
["aset"] = { -- kilkaset
nom_mp_pers = "uset", nom_p_not_mp_pers = "aset", gen_p = "uset", dat_p = "uset", acc_mp_pers = "uset", acc_p_not_mp_pers = "aset", ins_p = { "uset", { "omaset", note = "rare" } }, loc_p = "uset",
},
["edziesiąt"] = { -- wieledziesiąt
nom_mp_pers = "udziesięciu", nom_p_not_mp_pers = "edziesiąt", gen_p = "udziesięciu", dat_p = "udziesięciu", acc_mp_pers = "udziesięciu", acc_p_not_mp_pers = "edziesiąt", ins_p = { "udziesięciu", { "udziesięcioma", note = "rare" } }, loc_p = "udziesięciu",
},
["ekolwiek"] = { -- ilekolwiek
nom_mp_pers = "ukolwiek", nom_p_not_mp_pers = "ekolwiek", gen_p = "ukolwiek", dat_p = "ukolwiek", acc_mp_pers = "ukolwiek", acc_p_not_mp_pers = "ekolwiek", ins_p = { "ukolwiek", { "omakolwiek", note = "rare" } }, loc_p = "ukolwiek",
},
["ele"] = { -- niewiele, wiele
nom_mp_pers = { "elu", { "ela", note = "dated" } }, nom_p_not_mp_pers = "ele", gen_p = { "elu", { "ela", note = "dated" } }, dat_p = { "elu", { "ela", note = "dated" } }, acc_mp_pers = { "elu", { "ela", note = "dated" } }, acc_p_not_mp_pers = "ele", ins_p = { "eloma", "elu", { "ela", note = "dated" }, { "elą", note = "dated" } }, loc_p = { "elu", { "ela", note = "dated" } },
},
["em"] = { -- siedem
nom_mp_pers = "miu", nom_p_not_mp_pers = { "em", { "m", note = "dated" } }, gen_p = "miu", dat_p = "miu", acc_mp_pers = "miu", acc_p_not_mp_pers = { "em", { "m", note = "dated" } }, ins_p = { "mioma", "miu" }, loc_p = "miu",
},
["emkroć"] = { -- siedemkroć
nom_mp_pers = "miukroć", nom_p_not_mp_pers = "emkroć", gen_p = "miukroć", dat_p = "miukroć", acc_mp_pers = "miukroć", acc_p_not_mp_pers = "emkroć", ins_p = { "miukroć", { "miomakroć", note = "rare" } }, loc_p = "miukroć",
},
["emset"] = { -- siedemset
nom_mp_pers = "miuset", nom_p_not_mp_pers = { "emset", { "mset", note = "dated" } }, gen_p = "miuset", dat_p = "miuset", acc_mp_pers = "miuset", acc_p_not_mp_pers = { "emset", { "mset", note = "dated" } }, ins_p = { "miuset", { "miomaset", note = "rare" } }, loc_p = "miuset",
},
["eset"] = { -- wieleset
nom_mp_pers = "uset", nom_p_not_mp_pers = "eset", gen_p = "uset", dat_p = "uset", acc_mp_pers = "uset", acc_p_not_mp_pers = "eset", ins_p = { "uset", { "omaset", note = "rare" } }, loc_p = "uset",
},
["eś"] = { -- ileś
nom_mp_pers = "uś", nom_p_not_mp_pers = "eś", gen_p = "uś", dat_p = "uś", acc_mp_pers = "uś", acc_p_not_mp_pers = "eś", ins_p = { "uś", { "omaś", note = "rare" } }, loc_p = "uś",
},
["eż"] = { -- ileż, tyleż, wieleż
nom_mp_pers = "uż", nom_p_not_mp_pers = "eż", gen_p = "uż", dat_p = "uż", acc_mp_pers = "uż", acc_p_not_mp_pers = "eż", ins_p = { "uż", { "omaż", note = "rare" } }, loc_p = "uż",
},
["ieście"] = { -- dwieście
nom_mp_pers = { "ustu", { "uset", note = "dated" }, { "óchset", note = "dated" } }, nom_p_not_mp_pers = "ieście", gen_p = { "ustu", { "uset", note = "dated" }, { "óchset", note = "dated" } }, dat_p = "ustu", acc_mp_pers = { "ustu", { "uset", note = "dated" }, { "óchset", note = "dated" } }, acc_p_not_mp_pers = "ieście", ins_p = { "ustu", { "omaset", note = "rare" }, { "ustoma", note = "rare" } }, loc_p = { "ustu", { "uset", note = "dated" }, { "óchset", note = "dated" } },
},
["ile"] = { -- ile
nom_mp_pers = "ilu", nom_p_not_mp_pers = "ile", gen_p = "ilu", dat_p = "ilu", acc_mp_pers = "ilu", acc_p_not_mp_pers = "ile", ins_p = { "iloma", "ilu" }, loc_p = "ilu",
},
["mset"] = { -- siedmset
nom_mp_pers = "miuset", nom_p_not_mp_pers = { "emset", "mset" }, gen_p = "miuset", dat_p = "miuset", acc_mp_pers = "miuset", acc_p_not_mp_pers = { "emset", "mset" }, ins_p = { "miuset", { "miomaset", note = "rare" } }, loc_p = "miuset",
},
["o"] = { -- sto
nom_mp_pers = "u", nom_p_not_mp_pers = "o", gen_p = "u", dat_p = "u", acc_mp_pers = "u", acc_p_not_mp_pers = "o", ins_p = { "u", { "oma", note = "rare" } }, loc_p = "u",
},
["siem"] = { -- osiem
nom_mp_pers = "śmiu", nom_p_not_mp_pers = { "siem", { "śm", note = "dated" } }, gen_p = "śmiu", dat_p = "śmiu", acc_mp_pers = "śmiu", acc_p_not_mp_pers = { "siem", { "śm", note = "dated" } }, ins_p = { "śmioma", "śmiu" }, loc_p = "śmiu",
},
["siemkroć"] = { -- osiemkroć
nom_mp_pers = "śmiukroć", nom_p_not_mp_pers = "siemkroć", gen_p = "śmiukroć", dat_p = "śmiukroć", acc_mp_pers = "śmiukroć", acc_p_not_mp_pers = "siemkroć", ins_p = { "śmiukroć", { "śmiomakroć", note = "rare" } }, loc_p = "śmiukroć",
},
["siemset"] = { -- osiemset
nom_mp_pers = "śmiuset", nom_p_not_mp_pers = { "siemset", { "śmset", note = "dated" } }, gen_p = "śmiuset", dat_p = "śmiuset", acc_mp_pers = "śmiuset", acc_p_not_mp_pers = { "siemset", { "śmset", note = "dated" } }, ins_p = { "śmiuset", { "śmiomaset", note = "rare" } }, loc_p = "śmiuset",
},
["y"] = { -- cztery, trzy
nom_mp_pers = { "ech", "ej" }, nom_p_not_mp_pers = "y", gen_p = "ech", dat_p = "em", acc_mp_pers = "ech", acc_p_not_mp_pers = "y", ins_p = "ema", loc_p = "ech",
},
["ykroć"] = { -- trzykroć
nom_mp_pers = "echkroć", nom_p_not_mp_pers = "ykroć", gen_p = "echkroć", dat_p = "echkroć", acc_mp_pers = "echkroć", acc_p_not_mp_pers = "ykroć", ins_p = { "echkroć", { "emakroć", note = "rare" } }, loc_p = "echkroć",
},
["yle"] = { -- tyle
nom_mp_pers = { "ylu", { "yla", note = "dated" } }, nom_p_not_mp_pers = "yle", gen_p = { "ylu", { "yla", note = "dated" } }, dat_p = { "ylu", { "yla", note = "dated" } }, acc_mp_pers = { "ylu", { "yla", note = "dated" } }, acc_p_not_mp_pers = "yle", ins_p = { "yloma", "ylu", { "yla", note = "dated" }, { "ylą", note = "dated" } }, loc_p = { "ylu", { "yla", note = "dated" } },
},
["ysta"] = { -- czterysta, trzysta
nom_mp_pers = { "ystu", { "echset", note = "rare" } }, nom_p_not_mp_pers = "ysta", gen_p = { "ystu", { "echset", note = "rare" } }, dat_p = "ystu", acc_mp_pers = { "ystu", { "echset", note = "rare" } }, acc_p_not_mp_pers = "ysta", ins_p = { "ystu", { "ystoma", note = "rare" } }, loc_p = { "ystu", { "echset", note = "rare" } },
},
["ąt"] = { -- dziewięćdziesiąt, osiemdziesiąt, ośmdziesiąt, pięćdziesiąt, siedemdziesiąt, siedmdziesiąt, sześćdziesiąt
nom_mp_pers = "ęciu", nom_p_not_mp_pers = "ąt", gen_p = "ęciu", dat_p = "ęciu", acc_mp_pers = "ęciu", acc_p_not_mp_pers = "ąt", ins_p = { "ęcioma", "ęciu" }, loc_p = "ęciu",
},
["ć"] = { -- dziesięć, dziewięć, pięć, sześć
nom_mp_pers = "ciu", nom_p_not_mp_pers = "ć", gen_p = "ciu", dat_p = "ciu", acc_mp_pers = "ciu", acc_p_not_mp_pers = "ć", ins_p = { "cioma", "ciu" }, loc_p = "ciu",
},
["ćkroć"] = { -- pięćkroć
nom_mp_pers = "ciukroć", nom_p_not_mp_pers = "ćkroć", gen_p = "ciukroć", dat_p = "ciukroć", acc_mp_pers = "ciukroć", acc_p_not_mp_pers = "ćkroć", ins_p = { "ciukroć", { "ciomakroć", note = "rare" } }, loc_p = "ciukroć",
},
["ćset"] = { -- dziewięćset, pięćset, sześćset
nom_mp_pers = "ciuset", nom_p_not_mp_pers = "ćset", gen_p = "ciuset", dat_p = "ciuset", acc_mp_pers = "ciuset", acc_p_not_mp_pers = "ćset", ins_p = { "ciuset", { "ciomaset", note = "rare" } }, loc_p = "ciuset",
},
["ę"] = { -- parę
nom_mp_pers = "u", nom_p_not_mp_pers = "ę", gen_p = "u", dat_p = "u", acc_mp_pers = "u", acc_p_not_mp_pers = "ę", ins_p = { "oma", "u" }, loc_p = "u",
},
["ędziesiąt"] = { -- parędziesiąt
nom_mp_pers = "udziesięciu", nom_p_not_mp_pers = "ędziesiąt", gen_p = "udziesięciu", dat_p = "udziesięciu", acc_mp_pers = "udziesięciu", acc_p_not_mp_pers = "ędziesiąt", ins_p = { "udziesięciu", { "udziesięcioma", note = "rare" } }, loc_p = "udziesięciu",
},
["ęnaście"] = { -- paręnaście
nom_mp_pers = "unastu", nom_p_not_mp_pers = "ęnaście", gen_p = "unastu", dat_p = "unastu", acc_mp_pers = "unastu", acc_p_not_mp_pers = "ęnaście", ins_p = { "unastoma", "unastu" }, loc_p = "unastu",
},
["ęset"] = { -- paręset
nom_mp_pers = "uset", nom_p_not_mp_pers = "ęset", gen_p = "uset", dat_p = "uset", acc_mp_pers = "uset", acc_p_not_mp_pers = "ęset", ins_p = { "uset", { "omaset", note = "rare" } }, loc_p = "uset",
},
["ści"] = { -- czterdzieści, trzydzieści
nom_mp_pers = "stu", nom_p_not_mp_pers = "ści", gen_p = "stu", dat_p = "stu", acc_mp_pers = "stu", acc_p_not_mp_pers = "ści", ins_p = { "stoma", "stu" }, loc_p = "stu",
},
["ście"] = { -- czternaście, dziewiętnaście, jedenaście, naście, osiemnaście, ośmnaście, piętnaście, siedemnaście, siedmnaście, szesnaście, trzynaście
nom_mp_pers = "stu", nom_p_not_mp_pers = "ście", gen_p = "stu", dat_p = "stu", acc_mp_pers = "stu", acc_p_not_mp_pers = "ście", ins_p = { "stoma", "stu" }, loc_p = "stu",
},
["śmset"] = { -- ośmset
nom_mp_pers = "śmiuset", nom_p_not_mp_pers = { "siemset", "śmset" }, gen_p = "śmiuset", dat_p = "śmiuset", acc_mp_pers = "śmiuset", acc_p_not_mp_pers = { "siemset", "śmset" }, ins_p = { "śmiuset", { "śmiomaset", note = "rare" } }, loc_p = "śmiuset",
},
}
data.collective_rules = {
["e"] = { -- dwoje, oboje, obydwoje, obydwoje, troje
nom_p = "e", gen_p = "ga", dat_p = "gu", acc_p = "e", ins_p = "giem", loc_p = "gu", voc_p = "e",
},
["o"] = { -- czterdzieścioro, czternaścioro, czworo, dwadzieścioro, dwanaścioro, dziesięcioro, dziewiętnaścioro, dziewięcioro, dziewięćdziesięcioro, jedenaścioro, kilkoro, kilkadziesięcioro, kilkanaścioro, naścioro, ośmioro, osiemdziesięcioro, osiemnaścioro, ośmdziesięcioro, ośmnaścioro, piętnaścioro, pięcioro, pięćdziesięcioro, siedmioro, siedemdziesięcioro, siedemnaścioro, siedmdziesięcioro, siedmnaścioro, szesnaścioro, sześcioro, sześćdziesięcioro, trzydzieścioro, trzynaścioro
nom_p = "o", gen_p = "ga", dat_p = "gu", acc_p = "o", ins_p = "giem", loc_p = "gu", voc_p = "o",
},
}
--[==[
The noun groups, keyed `GENDER KIND NUMBER NOMINATIVE` (e.g. `m-pr common sg `, `f common sg a`, `n place pl y`):
* `copies`: the slots that take the forms of another slot (e.g. `acc_s = "gen_s"`).
* `rules`: the forms of each slot, by the ending of the stem (`""` is the default). A slot's forms are an ending (a
string) or a list of endings, and an ending given as a table can name a `stem` alternation and a `note`.
]==]
data.noun_groups = {
["f common sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", depr_p = {}, gen_s = { "", stem = "soft" }, ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = { "", stem = "soft" } },
["D"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["V"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["c"] = { gen_s = "y", nom_p = "e" },
["e"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["edź"] = { nom_p = { "", stem = "soft" } },
["g"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["j"] = { nom_p = "e" },
["k"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["l"] = { gen_s = "i", nom_p = "e" },
["n"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["nt"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["o"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["oć"] = { nom_p = "e" },
["r"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["rś"] = { nom_p = { "", stem = "soft" } },
["s"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["tać"] = { nom_p = { { "", stem = "soft" }, "e" } },
["u"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["w"] = { dat_p = { "om", stem = "reduced+palatal" }, gen_s = { "", stem = "reduced+palatal" }, ins_p = { "ami", stem = "reduced+palatal" }, ins_s = { "ą", stem = "reduced+palatal" }, loc_p = { "ach", stem = "reduced+palatal" }, nom_p = { "e", stem = "reduced+palatal" } },
["y"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["z"] = { gen_s = "y", nom_p = "e" },
["é"] = { dat_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["ódź"] = { dat_p = { "om", stem = "shortened" }, gen_s = { "", stem = "shortened+soft" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "ą", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["ól"] = { dat_p = { "om", stem = "shortened" }, gen_s = { "i", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "ą", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["ąż"] = { dat_p = { "om", stem = "shortened" }, gen_s = { "y", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "ą", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["ęś"] = { ins_p = { "ami", "mi" }, nom_p = { "", stem = "soft" } },
["ń"] = { nom_p = "e" },
["ś"] = { nom_p = "e" },
["ź"] = { nom_p = "e" },
["ż"] = { gen_s = "y", nom_p = "e" },
},
},
["f common sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = {}, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "i", voc_s = "o" },
["acz"] = { gen_p = "" },
["ak"] = { gen_p = "" },
["all"] = { gen_p = { "", "i" } },
["ani"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["arł"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ast"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["awn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["b"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["bi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["bl"] = { gen_p = "i" },
["bn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e" },
["bni"] = { gen_p = "" },
["bol"] = { gen_p = "i" },
["bow"] = { voc_s = "a" },
["c"] = { dat_s = "y", gen_p = "", gen_s = "y", nom_p = "e" },
["ci"] = { dat_s = "", gen_p = { "", { "", stem = "final_soft" } }, gen_s = "", voc_s = "u" },
["cn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e" },
["cni"] = { gen_p = "" },
["cow"] = { voc_s = "a" },
["cz"] = { dat_s = "y", gen_p = { "", "y" }, nom_p = "e" },
["czi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["czm"] = { dat_s = "ie" },
["czn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["d"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["dl"] = { gen_p = "i" },
["dn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["dni"] = { gen_p = "" },
["dow"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "lengthened" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y" },
["dz"] = { dat_s = "y", nom_p = "e" },
["e"] = { dat_s = "i", gen_p = "i", nom_p = "e" },
["ebn"] = { voc_s = "a" },
["ecn"] = { voc_s = "a" },
["ek"] = { gen_p = "" },
["eni"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["eśn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["f"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["fi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["g"] = { gen_p = "" },
["gi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["gl"] = { gen_p = "i" },
["gog"] = { gen_p = "" },
["gł"] = { gen_p = { "", stem = "inserted_ie" } },
["h"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["hi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["hn"] = { gen_p = { "", stem = "inserted_e" } },
["hni"] = { gen_p = "" },
["how"] = { voc_s = "a" },
["hł"] = { gen_p = { "", stem = "inserted_e" } },
["i"] = { dat_s = "i", nom_p = "e" },
["ik"] = { gen_p = "" },
["ini"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["iod"] = { gen_p = "" },
["ion"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["izd"] = { dat_s = { "e", stem = "palatal" } },
["izi"] = { voc_s = "u" },
["j"] = { dat_s = "i", nom_p = "e" },
["jni"] = { gen_p = "" },
["jog"] = { gen_p = "" },
["jom"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ki"] = { gen_p = { "i", { "j", note = "archaic" } } },
["kk"] = { gen_p = "" },
["kl"] = { gen_p = "i" },
["kł"] = { gen_p = { "", stem = "inserted_ie" } },
["l"] = { dat_s = "i", gen_p = { "", "i" }, nom_p = "e" },
["li"] = { gen_p = { "i", { "j", note = "archaic" } } },
["ll"] = { gen_p = "i" },
["ln"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["lni"] = { gen_p = { "", { "", stem = "final_soft" } } },
["lsk"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["lsz"] = { gen_p = { "", "y" } },
["m"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["mi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["mij"] = { gen_p = "" },
["ml"] = { gen_p = "i" },
["mow"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "lengthened" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y" },
["msz"] = { gen_p = "y" },
["n"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["nan"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ni"] = { dat_s = "", gen_s = "" },
["nni"] = { gen_p = "" },
["nod"] = { gen_p = "" },
["od"] = { gen_p = { "", stem = "lengthened" } },
["odł"] = { gen_p = { "", stem = "inserted_e" } },
["og"] = { gen_p = { "", stem = "lengthened" } },
["ok"] = { gen_p = "" },
["omn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["oni"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["osm"] = { dat_s = "ie" },
["otw"] = { gen_p = { "", stem = "inserted_e" } },
["ow"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e" },
["oł"] = { gen_p = { "", stem = "lengthened" } },
["oźn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e" },
["p"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["pi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["pl"] = { gen_p = "i" },
["pn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["pow"] = { voc_s = "a" },
["r"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["raż"] = { gen_p = "y" },
["rl"] = { gen_p = "i" },
["rni"] = { gen_p = { "", { "", stem = "final_soft" } } },
["rol"] = { gen_p = "i" },
["rz"] = { dat_s = "y", nom_p = "e" },
["rzn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["rąż"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", voc_s = "a" },
["s"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["sc"] = { dat_s = "e", gen_p = { "", stem = "inserted_e" } },
["si"] = { dat_s = "", gen_p = { { "", note = "rare" }, { "", stem = "final_soft" } }, gen_s = "", voc_s = "u" },
["sl"] = { gen_p = "i" },
["sz"] = { dat_s = "y", nom_p = "e" },
["t"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["tel"] = { gen_p = "i" },
["tl"] = { gen_p = "i" },
["tn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["tni"] = { gen_p = "" },
["tod"] = { gen_p = "" },
["tł"] = { gen_p = { "", stem = "inserted_e" } },
["udł"] = { gen_p = { "", stem = "inserted_e" } },
["uk"] = { gen_p = "" },
["uni"] = { gen_p = { { "", note = "rare" }, { "", stem = "final_soft" } }, voc_s = "u" },
["uzd"] = { dat_s = { "e", stem = "palatal" } },
["w"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["wan"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["wi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["wl"] = { gen_p = "i" },
["wn"] = { gen_p = { "", stem = "inserted_ie" } },
["wni"] = { gen_p = "" },
["wol"] = { gen_p = "i" },
["wsk"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["yk"] = { gen_p = "" },
["z"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["zd"] = { dat_s = { "e", stem = "fronted+palatal" } },
["zdr"] = { gen_p = { "", stem = "inserted_e" } },
["zi"] = { dat_s = "", gen_p = { "", { "", stem = "final_soft" } }, gen_s = "" },
["zm"] = { dat_s = { "ie", { "e", stem = "palatal", note = "proscribed" } } },
["zni"] = { gen_p = "" },
["zon"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["zz"] = { dat_s = "y", nom_p = "e" },
["ój"] = { gen_p = "" },
["ók"] = { gen_p = "" },
["ąc"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", voc_s = "a" },
["ąk"] = { gen_p = "" },
["ąt"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ęcz"] = { gen_p = "" },
["ęk"] = { gen_p = "" },
["ępi"] = { dat_s = "", gen_p = "", gen_s = "" },
["ł"] = { gen_p = "", gen_s = "y", nom_p = "y" },
["łbi"] = { dat_s = "", gen_p = "", gen_s = "" },
["ńsk"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["ści"] = { voc_s = { "o", "u" } },
["śni"] = { gen_p = "" },
["źni"] = { gen_p = "" },
["ż"] = { dat_s = "y", gen_p = "", gen_s = "y", nom_p = "e" },
["żi"] = { gen_p = { "i", { "j", note = "archaic" } } },
["żn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["żni"] = { gen_p = "" },
["żon"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
},
},
["f common sg i"] = {
copies = { acc_p = "nom_p", dat_s = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { acc_s = { "ę", stem = "palatal" }, dat_p = { "om", stem = "palatal" }, depr_p = {}, gen_p = "i", gen_s = { "", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "ą", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["an"] = { acc_s = { "ą", stem = "palatal" } },
["can"] = { acc_s = { "ę", stem = "palatal" } },
["on"] = { acc_s = { "", stem = "palatal" }, dat_p = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["r"] = { acc_s = "i", dat_p = "i", gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", nom_p = "i" },
["san"] = { acc_s = { "ę", stem = "palatal" } },
["t"] = { acc_s = "i", dat_p = "i", gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", nom_p = "i" },
},
},
["f given sg "] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "", dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "", voc_s = "" },
},
},
["f given sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = {}, gen_p = "", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "y", voc_s = "o" },
["aj"] = { voc_s = { "o", "u" } },
["ak"] = { gen_p = "" },
["bi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["ci"] = { gen_p = { "", { "", stem = "final_soft" } } },
["di"] = { dat_s = "i", gen_s = "i" },
["e"] = { dat_s = "i", gen_p = "i", gen_s = "i", nom_p = "e" },
["fi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["g"] = { gen_s = "i", nom_p = "i" },
["gi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["i"] = { dat_s = "", gen_s = "", nom_p = "e", voc_s = "u" },
["ik"] = { gen_p = "" },
["j"] = { dat_s = "i", gen_s = "i", nom_p = "e" },
["k"] = { gen_p = { "", stem = "inserted_e" }, gen_s = "i", nom_p = "i" },
["ki"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["l"] = { dat_s = "i", gen_p = { "", "i" }, gen_s = "i", nom_p = "e", voc_s = { "o", "u" } },
["li"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["mi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["nc"] = { dat_s = "y", nom_p = "e" },
["ni"] = { gen_p = { { "", note = "rare" }, { "", stem = "final_soft" } } },
["nul"] = { gen_p = "", voc_s = "u" },
["pi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["ri"] = { dat_s = "i", gen_s = "i", voc_s = "o" },
["si"] = { gen_p = { { "", note = "rare" }, { "", stem = "final_soft" } } },
["sz"] = { dat_s = "y", nom_p = "e" },
["ti"] = { dat_s = "i", gen_s = "i", voc_s = "o" },
["wi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i", voc_s = "o" },
["wł"] = { gen_p = { "", stem = "inserted_e" } },
["yk"] = { gen_p = "" },
["zi"] = { gen_p = { "", { "", stem = "final_soft" } } },
["ż"] = { dat_s = "y", nom_p = "e" },
},
},
["f given sg i"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = { "", stem = "palatal" }, depr_p = {}, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
},
},
["f place sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", loc_s = "gen_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", dat_s = { "", stem = "soft" }, depr_p = {}, gen_p = { "", stem = "soft" }, gen_s = { "", stem = "soft" }, ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "e" },
["D"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["L"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-i" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, nom_p = { "", "-e" } },
["e"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["eś"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "", stem = "reduced+soft" }, gen_p = { "", stem = "reduced+soft" }, gen_s = { "", stem = "reduced+soft" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "ą", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, nom_p = { { "", stem = "reduced+soft" }, { "e", stem = "reduced" } } },
["gać"] = { nom_p = { "", stem = "soft" } },
["l"] = { dat_s = "i", gen_p = "i", gen_s = "i" },
["o"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["ość"] = { nom_p = { "", stem = "soft" } },
["s"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["w"] = { dat_p = { "om", stem = "reduced+palatal" }, dat_s = { "", stem = "reduced+palatal" }, gen_p = { "", stem = "reduced+palatal" }, gen_s = { "", stem = "reduced+palatal" }, ins_p = { "ami", stem = "reduced+palatal" }, ins_s = { "ą", stem = "reduced+palatal" }, loc_p = { "ach", stem = "reduced+palatal" }, nom_p = { "e", stem = "reduced+palatal" } },
["z"] = { dat_s = "y", gen_p = "y", gen_s = "y" },
["ż"] = { dat_s = "y", gen_p = "y", gen_s = "y" },
},
},
["f place sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = {}, gen_p = "", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "e", voc_s = "o" },
["ak"] = { gen_p = "" },
["ani"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["ask"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["aw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["b"] = { nom_p = "y" },
["bn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["c"] = { dat_s = "y" },
["ck"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["cz"] = { gen_p = { "", "y" } },
["czn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["d"] = { nom_p = "y" },
["di"] = { dat_s = "i", gen_s = "i" },
["dn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["dw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["e"] = { dat_s = "i", gen_p = "i", gen_s = "i" },
["ek"] = { gen_p = "" },
["el"] = { gen_p = { "", "i" } },
["eni"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["enn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ew"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["ewn"] = { acc_s = { "ą", "ę" }, dat_p = { "om", "ym" }, dat_s = { "ej", { "e", stem = "palatal" } }, gen_p = { "", "ych" }, gen_s = { "ej", "y" }, ins_p = { "ami", "ymi" }, loc_p = { "ach", "ych" }, nom_p = { "e", "y" }, voc_s = { "a", "o" } },
["ez"] = { dat_s = { "e", stem = "palatal" }, nom_p = "y" },
["eśn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["f"] = { nom_p = "y" },
["g"] = { gen_s = "i", nom_p = "i" },
["gi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["gol"] = { gen_p = { "", "i" } },
["h"] = { nom_p = "y" },
["i"] = { dat_s = "", gen_s = "" },
["ibi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["iel"] = { gen_p = "i" },
["ik"] = { gen_p = "" },
["ini"] = { gen_p = { "", { "", stem = "final_soft" } } },
["iw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["iz"] = { dat_s = { "e", stem = "palatal" }, nom_p = "y" },
["j"] = { dat_s = "i", gen_s = "i" },
["k"] = { gen_p = { "", stem = "inserted_e" }, gen_s = "i", nom_p = "i" },
["kol"] = { gen_p = { "", "i" } },
["kw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["l"] = { dat_s = "i", gen_p = "i", gen_s = "i" },
["li"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["ln"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["lsk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["lw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["lz"] = { dat_s = { "e", stem = "palatal" }, nom_p = "y" },
["m"] = { nom_p = "y" },
["mbi"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["mż"] = { gen_p = "y" },
["n"] = { nom_p = "y" },
["ob"] = { gen_p = { "", stem = "lengthened" } },
["od"] = { gen_p = { "", stem = "lengthened" } },
["odz"] = { gen_p = "y" },
["og"] = { gen_p = { "", stem = "lengthened" } },
["omn"] = { acc_s = { "ą", "ę" }, dat_p = { "om", "ym" }, dat_s = { "ej", { "e", stem = "palatal" } }, gen_p = { "", "ych" }, gen_s = { "ej", "y" }, ins_p = { "ami", "ymi" }, loc_p = { "ach", "ych" }, nom_p = { "e", "y" }, voc_s = { "a", "o" } },
["oni"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, gen_s = "i" },
["opn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["oz"] = { dat_s = { "e", stem = "palatal" }, nom_p = "y" },
["p"] = { nom_p = "y" },
["pcz"] = { gen_p = "y" },
["prz"] = { gen_p = { "", "y" } },
["r"] = { nom_p = "y" },
["rcz"] = { gen_p = "" },
["ri"] = { dat_s = "i", gen_s = "i" },
["rni"] = { gen_p = { "", { "", stem = "final_soft" } } },
["rw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["rz"] = { gen_p = "y" },
["rł"] = { gen_p = { "", stem = "inserted_e" } },
["s"] = { nom_p = "y" },
["sal"] = { gen_p = { "", "i" } },
["sk"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["sol"] = { gen_p = { "", "i" } },
["t"] = { nom_p = "y" },
["tcz"] = { gen_p = "y" },
["ti"] = { dat_s = "i", gen_s = "i" },
["tn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["tok"] = { gen_p = "" },
["u"] = { dat_s = "i", gen_p = "i", gen_s = { "i", "y" }, nom_p = "y" },
["udz"] = { gen_p = { "", "y" } },
["usk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["uz"] = { dat_s = { "e", stem = "palatal" }, nom_p = "y" },
["w"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", voc_s = "a" },
["wcz"] = { gen_p = "y" },
["yk"] = { gen_p = "" },
["yni"] = { gen_p = { "", { "", stem = "final_soft" } } },
["yst"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["z"] = { dat_s = "y" },
["zi"] = { gen_p = { "", { "", stem = "final_soft" } } },
["zw"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["ąc"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", voc_s = "a" },
["ąck"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ąk"] = { gen_p = "" },
["ąsk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ęcz"] = { gen_p = "" },
["ędz"] = { gen_p = { "", "y" } },
["ęk"] = { gen_p = "" },
["ł"] = { nom_p = "y" },
["źn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ż"] = { dat_s = "y" },
["żn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
},
},
["f place sg i"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = { "", stem = "palatal" }, depr_p = {}, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["r"] = { dat_p = "i", gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", nom_p = "i" },
},
},
["f proper sg "] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "", dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "", voc_s = "" },
["C"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-a" }, ins_p = { "", "-ami" }, ins_s = { "", "-iem" }, loc_p = { "", "-ach" }, loc_s = { "", "-u" }, nom_p = { "", "-i" }, voc_s = { "", "-u" } },
["EP"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["F"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["M"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["N"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["OK"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-iem" }, loc_p = { "", "-ach" }, loc_s = { "", "-u" }, nom_p = { "", "-i" }, voc_s = { "", "-u" } },
["OP"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["PR"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ze" }, nom_p = { "", "-y" }, voc_s = { "", "-ze" } },
["S"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_s = { "", "-ie" } },
["Z"] = { loc_s = { "", "-ecie" }, voc_s = { "", "-ecie" } },
},
},
["f proper sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = {}, gen_p = "", gen_s = "i", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "y", voc_s = "o" },
["at"] = { gen_s = "y" },
["c"] = { dat_s = "y", gen_s = "y", nom_p = "e" },
["d"] = { gen_s = "y" },
["e"] = { dat_s = "i", gen_p = "i", nom_p = "e" },
["g"] = { nom_p = "i" },
["h"] = { gen_s = "y" },
["i"] = { dat_s = "i", gen_p = { "i", { "j", note = "archaic" } }, nom_p = "e" },
["j"] = { nom_p = "e" },
["k"] = { gen_p = { "", stem = "inserted_e" }, nom_p = "i" },
["n"] = { gen_s = "y" },
["r"] = { gen_s = "y" },
["z"] = { gen_s = "y" },
},
},
["f surname sg "] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "", depr_p = {}, gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
},
},
["f surname sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ą", dat_p = "im", dat_s = "iej", depr_p = {}, gen_p = "ich", gen_s = "iej", ins_p = "imi", ins_s = "ą", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["adł"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ajn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ak"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["an"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["awn"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["azł"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["b"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["bk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["c"] = { acc_s = "ę", dat_p = "om", dat_s = "y", gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["cz"] = { dat_s = "y", nom_p = "e" },
["czm"] = { dat_s = "ie" },
["d"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["dk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["dni"] = { acc_s = "ą", dat_p = "m", dat_s = "ej", gen_p = "ch", gen_s = "ej", ins_p = "mi", loc_p = "ch", voc_s = "a" },
["dz"] = { dat_s = "y", nom_p = "e" },
["dzk"] = { acc_s = "ą", dat_p = "im", dat_s = "iej", gen_p = "ich", gen_s = "iej", ins_p = "imi", loc_p = "ich", nom_p = "ie", voc_s = "a" },
["ek"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["en"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["esk"] = { dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i" },
["f"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["fk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["g"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["gł"] = { acc_s = "ą", gen_s = "ej", nom_p = "e", voc_s = "a" },
["h"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["hn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["i"] = { acc_s = "ę", dat_p = "om", dat_s = "", gen_p = "", gen_s = "", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["ian"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["ik"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["in"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["izn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["j"] = { acc_s = "ę", dat_p = "om", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["jew"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["jk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["jn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["kat"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["l"] = { acc_s = "ę", dat_p = "om", dat_s = "i", gen_p = { "", "i" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["lan"] = { acc_s = "ą", gen_s = "ej", nom_p = "e", voc_s = "a" },
["lk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["m"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["mk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["n"] = { dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e" },
["nk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["od"] = { gen_p = { "", stem = "lengthened" } },
["ok"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["on"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["osk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["osn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["ow"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["own"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["p"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["pi"] = { dat_s = "i", gen_p = "i", gen_s = "i" },
["pk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["r"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["rk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["rz"] = { nom_p = "e" },
["s"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["sm"] = { dat_s = "ie" },
["sz"] = { dat_s = "y", nom_p = "e" },
["t"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["tk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["uk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["un"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["urz"] = { dat_s = "y" },
["w"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["wan"] = { acc_s = "ą", dat_p = "ym", dat_s = "ej", gen_p = "ych", gen_s = "ej", ins_p = "ymi", loc_p = "ych", nom_p = "e", voc_s = "a" },
["wi"] = { dat_s = "i", gen_p = "i", gen_s = "i" },
["wk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["wn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_ie" }, gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["x"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "spelled+palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["y"] = { acc_s = "ę", dat_p = "om", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["yk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["yn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["yzm"] = { dat_s = { "ie", { "e", stem = "palatal", note = "proscribed" } } },
["z"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["zk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ąk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ćk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ęk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ł"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["łk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["łn"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "y", voc_s = "o" },
["ńk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["śk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
["ż"] = { acc_s = "ę", dat_p = "om", dat_s = "y", gen_p = "", gen_s = "y", ins_p = "ami", loc_p = "ach", nom_p = "e", voc_s = "o" },
["żk"] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, gen_p = { "", stem = "inserted_e" }, gen_s = "i", ins_p = "ami", loc_p = "ach", nom_p = "i", voc_s = "o" },
},
},
["f surname sg i"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "i", depr_p = {}, gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", nom_p = "i" },
["m"] = { dat_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["n"] = { dat_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["s"] = { dat_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["z"] = { dat_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
},
},
["m-pr common pl "] = {
copies = { acc_p = "gen_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = {}, dat_s = {}, depr_p = {}, gen_p = {}, gen_s = {}, ins_p = { "m", stem = "fronted" }, ins_s = {}, loc_p = {}, loc_s = {}, nom_s = {}, voc_s = {} },
},
},
["m-pr common pl e"] = {
copies = { acc_p = "gen_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = { "dziadków", stem = "irregular" }, gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
},
},
["m-pr common pl i"] = {
copies = { acc_p = "gen_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "zym", dat_s = {}, depr_p = {}, gen_p = "zych", gen_s = {}, ins_p = "zymi", ins_s = {}, loc_p = "zych", loc_s = {}, nom_s = {}, voc_s = {} },
["o"] = { dat_p = "im", gen_p = "ich", ins_p = "imi", loc_p = "ich" },
},
},
["m-pr common pl y"] = {
copies = { },
rules = {
[""] = { acc_p = "ów", acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_p = "y", voc_s = {} },
},
},
["m-pr common sg "] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "om", dat_s = "owi", depr_p = "y", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = { "y", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["ad"] = { nom_p = { "", stem = "palatal" } },
["al"] = { gen_p = { "i", "ów" } },
["ard"] = { nom_p = { "", stem = "palatal" } },
["ast"] = { nom_p = "owie" },
["az"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["aść"] = { dat_s = { "", stem = "soft" }, gen_s = { "", stem = "soft" }, ins_s = "ą", loc_s = { "", stem = "soft" }, nom_p = { "e", "owie" }, voc_s = { "", stem = "soft" } },
["bel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["bp"] = { nom_p = { "", stem = "palatal" } },
["c"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "y", stem = "reduced" }, voc_s = { { "u", stem = "reduced" }, { "ze", stem = "reduced" } } },
["cel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_p = { { "i", stem = "reduced" }, { "ów", stem = "reduced" } }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["cik"] = { nom_p = "owie" },
["cz"] = { gen_p = { "y", "ów" } },
["dan"] = { nom_p = "owie" },
["dr"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["dur"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["dyw"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["ek"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "i", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "owie", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["erk"] = { nom_p = "owie" },
["eus"] = { nom_p = "owie" },
["eń"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["eś"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["eż"] = { depr_p = "e", loc_s = "u", nom_p = "e", voc_s = "u" },
["f"] = { nom_p = "owie" },
["fel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_p = { { "i", stem = "reduced" }, { "ów", stem = "reduced" } }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["fil"] = { gen_p = { { "i", note = "rare" }, "ów" } },
["g"] = { depr_p = "i", ins_s = "iem", loc_s = "u", nom_p = { { "y", stem = "palatal" }, "owie" }, voc_s = "u" },
["ger"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["h"] = { loc_s = "u", nom_p = "owie", voc_s = "u" },
["hot"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["ib"] = { nom_p = "owie" },
["ic"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["icz"] = { gen_p = "ów" },
["id"] = { nom_p = { "", stem = "palatal" } },
["ieć"] = { loc_s = "u", nom_p = "e", voc_s = "u" },
["iks"] = { nom_p = "owie" },
["il"] = { gen_p = { "i", "ów" } },
["ior"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["ir"] = { nom_p = "owie" },
["iz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["iór"] = { nom_p = "owie" },
["j"] = { depr_p = "e", loc_s = "u", nom_p = "e", voc_s = "u" },
["jas"] = { nom_p = "owie" },
["jeb"] = { nom_p = "owie" },
["jor"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["k"] = { depr_p = "i", ins_s = "iem", loc_s = "u", voc_s = "u" },
["kon"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["kup"] = { nom_p = { "", stem = "palatal" } },
["l"] = { depr_p = "e", gen_p = "i", loc_s = "u", nom_p = "e", voc_s = "u" },
["lan"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["lar"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["len"] = { nom_p = "owie" },
["leń"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = { { "", stem = "soft" }, "ów" }, gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["lub"] = { nom_p = { "", stem = "palatal" } },
["m"] = { nom_p = "owie" },
["n"] = { nom_p = { "", stem = "palatal" } },
["nc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["nel"] = { gen_p = { "i", "ów" } },
["ng"] = { nom_p = "owie" },
["nin"] = { dat_p = { "om", stem = "truncated" }, depr_p = { "y", stem = "truncated" }, gen_p = { "", stem = "truncated" }, ins_p = { "ami", stem = "truncated" }, loc_p = { "ach", stem = "truncated" }, nom_p = { "e", stem = "truncated+palatal" } },
["nuk"] = { nom_p = "owie" },
["nuś"] = { nom_p = { "e", "owie" } },
["ob"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["ojk"] = { nom_p = "owie" },
["ont"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["op"] = { nom_p = { "", stem = "palatal" } },
["ord"] = { nom_p = "owie" },
["otr"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["oz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["oń"] = { depr_p = "e", gen_p = { { "", stem = "soft" }, "ów" }, loc_s = "u", nom_p = "e", voc_s = "u" },
["pan"] = { dat_s = "u", loc_s = "u", nom_p = "owie" },
["pel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["pis"] = { nom_p = "owie" },
["ral"] = { gen_p = "i" },
["rb"] = { nom_p = "owie" },
["rel"] = { gen_p = { "i", "ów" } },
["rep"] = { nom_p = "owie" },
["rl"] = { gen_p = "ów", nom_p = { "e", "owie" } },
["rz"] = { gen_p = { "y", { "ów", note = "rare" } } },
["róg"] = { dat_s = { "owi", stem = "shortened" }, voc_s = { "u", stem = "shortened" } },
["rż"] = { depr_p = "e", gen_p = { "y", "ów" }, loc_s = "u", voc_s = "u" },
["s"] = { nom_p = { "", stem = "palatal" } },
["san"] = { nom_p = "owie" },
["seł"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "y", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "owie", stem = "reduced" }, voc_s = { "e", stem = "reduced+palatal" } },
["sik"] = { nom_p = "owie" },
["sz"] = { gen_p = { "y", "ów" } },
["t"] = { nom_p = { "", stem = "palatal" } },
["trz"] = { gen_p = "ów", nom_p = { "e", "owie" } },
["tur"] = { nom_p = "owie" },
["uaw"] = { nom_p = { "", stem = "palatal" } },
["uc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", voc_s = "u" },
["ud"] = { nom_p = { "owie", { "", stem = "palatal" } } },
["ul"] = { gen_p = "ów" },
["uz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = { "", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["uń"] = { depr_p = "e", loc_s = "u", voc_s = "u" },
["wed"] = { nom_p = { "", stem = "palatal" } },
["wun"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["wód"] = { nom_p = { "owie", stem = "shortened" } },
["wój"] = { depr_p = { "e", stem = "shortened" } },
["wór"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, voc_s = { "e", stem = "shortened+palatal" } },
["x"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, depr_p = { "y", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, gen_s = { "a", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "owie", stem = "spelled" }, voc_s = { "e", stem = "spelled+palatal" } },
["y"] = { depr_p = "e", loc_s = "u", nom_p = "e", voc_s = "u" },
["yc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["yd"] = { nom_p = { "", stem = "palatal" } },
["yz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["z"] = { depr_p = "e", loc_s = "u", nom_p = "e", voc_s = "u" },
["zcz"] = { gen_p = "ów" },
["zes"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["zeń"] = { nom_p = { "owie", stem = "reduced" } },
["zuk"] = { nom_p = "owie" },
["zuń"] = { nom_p = "e" },
["zyr"] = { nom_p = "owie" },
["ób"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { { "", stem = "shortened+palatal" }, { "owie", stem = "shortened" } }, voc_s = { "e", stem = "shortened+palatal" } },
["ód"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, voc_s = { "e", stem = "shortened+palatal" } },
["ódz"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "e", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "owie", stem = "shortened" }, voc_s = { "u", stem = "shortened" } },
["óg"] = { dat_p = { "om", stem = "shortened" }, depr_p = { "i", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "owie", stem = "shortened" } },
["ójt"] = { nom_p = "owie" },
["ól"] = { gen_p = "ów" },
["ów"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "owie", stem = "shortened" }, voc_s = { "e", stem = "shortened+palatal" } },
["ół"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, voc_s = { "e", stem = "shortened+palatal" } },
["óż"] = { depr_p = "e", gen_p = { "y", "ów" }, loc_s = "u", voc_s = "u" },
["ąc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", voc_s = "u" },
["ć"] = { depr_p = "e", gen_p = { "", stem = "soft" } },
["ę"] = { dat_p = "tom", depr_p = "ta", gen_p = { "t", stem = "lengthened" }, ins_p = "tami", loc_p = "tach", nom_p = "ta", voc_s = "" },
["ł"] = { nom_p = "owie" },
["łaz"] = { nom_p = { "", stem = "palatal" } },
["łup"] = { nom_p = "owie" },
["ś"] = { depr_p = "e", loc_s = "u", nom_p = "e", voc_s = "u" },
["ź"] = { depr_p = "e", loc_s = "u", nom_p = { "e", "owie" }, voc_s = "u" },
["żer"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["żeń"] = { gen_p = { "ów", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
},
},
["m-pr common sg a"] = {
copies = { acc_p = "gen_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = "y", gen_p = "ów", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = { "", stem = "palatal" }, voc_s = "o" },
["adż"] = { nom_p = "owie" },
["ak"] = { nom_p = { "y", stem = "palatal" } },
["b"] = { nom_p = "owie" },
["c"] = { dat_s = "y", depr_p = "e", nom_p = "y" },
["d"] = { nom_p = "owie" },
["dok"] = { nom_p = { "y", stem = "palatal" } },
["dyk"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["ek"] = { nom_p = { "y", stem = "palatal" } },
["f"] = { nom_p = "owie" },
["g"] = { depr_p = "i", gen_s = "i", nom_p = { "y", stem = "palatal" } },
["h"] = { nom_p = "owie" },
["i"] = { acc_s = { "ego", "ę" }, dat_s = { "", "emu" }, depr_p = "e", gen_s = { "", "ego" }, nom_p = "owie" },
["id"] = { nom_p = { "", stem = "palatal" } },
["j"] = { depr_p = "e", nom_p = "e" },
["k"] = { depr_p = "i", gen_s = "i", nom_p = "owie" },
["l"] = { dat_s = "i", depr_p = "e", gen_s = "i", nom_p = "e" },
["m"] = { nom_p = "owie" },
["odż"] = { nom_p = "owie" },
["p"] = { nom_p = "owie" },
["ped"] = { nom_p = { "", stem = "palatal" } },
["r"] = { nom_p = { "y", stem = "palatal" } },
["ri"] = { acc_s = "ę", dat_s = "i", gen_s = "i" },
["rz"] = { dat_s = { "e", stem = "palatal" }, depr_p = "y" },
["tw"] = { nom_p = "owie" },
["usz"] = { nom_p = "e" },
["uz"] = { dat_s = { "e", stem = "palatal" }, depr_p = "y" },
["yd"] = { nom_p = { "", stem = "palatal" } },
["z"] = { dat_s = "y", depr_p = "e", nom_p = "owie" },
["ór"] = { nom_p = "owie" },
["ł"] = { nom_p = "owie" },
["łk"] = { gen_p = { { "", stem = "inserted_e" }, "ów" } },
["ż"] = { dat_s = "y", depr_p = "e" },
},
},
["m-pr common sg e"] = {
copies = { },
rules = {
[""] = { acc_p = { "e", "ów" }, acc_s = { "a", "e" }, dat_p = { "e", "om" }, dat_s = "e'owi", depr_p = "e", gen_p = { "e", "ów" }, gen_s = { "a", "e" }, ins_p = { "ami", "e" }, ins_s = { "e", "em" }, loc_p = { "ach", "e" }, loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_p = "e'owie", voc_s = "e" },
},
},
["m-pr common sg i"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "im", dat_s = "iemu", depr_p = "ie", gen_p = "ich", gen_s = "iego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = { "y", stem = "palatal" } },
["b"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { "owie", stem = "palatal" } },
["c"] = { nom_p = "iowie" },
["d"] = { nom_p = "iowie" },
["n"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" } },
["tn"] = { nom_p = { "", stem = "palatal" } },
["z"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { "owie", stem = "palatal" } },
["źn"] = { nom_p = { "", stem = "palatal" } },
["ż"] = { nom_p = "iowie" },
},
},
["m-pr common sg o"] = {
copies = { acc_p = "gen_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "a", dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie", voc_s = "u" },
["d"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
["g"] = { depr_p = "i", ins_s = "iem" },
["gol"] = { acc_s = { "a", "o" }, dat_p = { "o", "om" }, dat_s = { "o", "owi" }, depr_p = { "e", "o" }, gen_p = { "o", "ów" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", "u" }, nom_p = { "o", "owie" } },
["jł"] = { depr_p = { "a", "y" } },
["k"] = { depr_p = "i", ins_s = "iem" },
["ol"] = { voc_s = "o" },
["r"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
["z"] = { voc_s = "o" },
["ł"] = { acc_s = "ę", dat_s = { "e", stem = "palatal" }, gen_s = "y", ins_s = "ą", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
},
},
["m-pr common sg y"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = { "", stem = "fronted+palatal" } },
["t"] = { nom_p = { "", stem = "palatal" } },
["z"] = { nom_p = { "i", stem = "virile" } },
["ł"] = { nom_p = { "i", stem = "palatal" } },
},
},
["m-pr given sg "] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", dat_s = "owi", depr_p = "y", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["aak"] = { nom_p = "owie" },
["ad"] = { nom_p = { "owie", { "", stem = "palatal" } } },
["ak"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u" },
["ck"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["der"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "y", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" } },
["dot"] = { nom_p = "owie" },
["e"] = { depr_p = "" },
["eg"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["ew"] = { nom_p = "owie" },
["g"] = { depr_p = "i", ins_s = "iem", loc_s = "u" },
["h"] = { loc_s = "u" },
["ier"] = { nom_p = "owie" },
["ik"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["j"] = { depr_p = "e", loc_s = "u", nom_p = { "e", "owie" } },
["jan"] = { nom_p = "owie" },
["k"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "i", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "owie", stem = "reduced" } },
["l"] = { depr_p = "e", loc_s = "u", nom_p = { "e", "owie" } },
["las"] = { nom_p = "owie" },
["lf"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["n"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["op"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["r"] = { nom_p = { "owie", { "y", stem = "palatal" } } },
["ros"] = { nom_p = "owie" },
["ryc"] = { nom_p = { "e", "owie" } },
["s"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["ses"] = { nom_p = "owie" },
["st"] = { nom_p = "owie" },
["t"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["tan"] = { nom_p = "owie" },
["uk"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ur"] = { nom_p = "owie" },
["v"] = { loc_s = "ie" },
["van"] = { nom_p = "owie" },
["w"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["weł"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "y", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "owie", stem = "reduced" } },
["x"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, depr_p = { "y", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, gen_s = { "a", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "owie", stem = "spelled" } },
["yc"] = { depr_p = "e", loc_s = "u" },
["yk"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["yp"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["z"] = { depr_p = "e", loc_s = "u", nom_p = { "e", "owie" } },
["zor"] = { nom_p = "owie" },
["óg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "i", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "owie", stem = "shortened" } },
["ój"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "e", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { { "e", stem = "shortened" }, { "owie", stem = "shortened" } } },
["ąd"] = { nom_p = { "owie", { "", stem = "palatal" } } },
["łk"] = { dat_p = "om", dat_s = "owi", depr_p = "i", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ś"] = { depr_p = "e", loc_s = "u", nom_p = { "e", "owie" } },
},
},
["m-pr given sg a"] = {
copies = { acc_p = "gen_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = "y", gen_p = "ów", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "owie", voc_s = "o" },
["l"] = { dat_s = "i", depr_p = "e", gen_s = "i" },
["sz"] = { dat_s = "y", depr_p = "e" },
["u"] = { dat_s = "i", gen_s = { "i", "y" } },
},
},
["m-pr given sg e"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_s = { "e", stem = "palatal" } },
},
},
["m-pr given sg i"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { "owie", stem = "palatal" } },
},
},
["m-pr given sg o"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie", voc_s = "u" },
["an"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
["at"] = { dat_p = "onom", dat_s = "onowi", depr_p = "ony", gen_p = "onów", gen_s = "ona", ins_p = "onami", ins_s = "onem", loc_p = "onach", loc_s = "onie", nom_p = "onowie", voc_s = { "o", "onie" } },
["c"] = { voc_s = "o" },
["k"] = { depr_p = "i", ins_s = "iem" },
["l"] = { voc_s = "o" },
["rt"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
["st"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, voc_s = "o" },
},
},
["m-pr proper sg "] = {
copies = { acc_s = "gen_s" },
rules = {
[""] = { acc_p = "ów", dat_p = "om", dat_s = "owi", depr_p = "y", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie", voc_p = "owie", voc_s = "u" },
["iek"] = { acc_p = {}, dat_p = {}, depr_p = {}, gen_p = {}, ins_p = {}, loc_p = {}, nom_p = {}, voc_p = {}, voc_s = {} },
["k"] = { depr_p = "i", ins_s = "iem" },
["l"] = { depr_p = "e" },
["n"] = { loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["ng"] = { depr_p = "i", ins_s = "iem" },
["s"] = { loc_s = { "e", stem = "palatal" }, voc_s = { "e", stem = "palatal" } },
["z"] = { depr_p = "e" },
},
},
["m-pr proper sg a"] = {
copies = { acc_p = "gen_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = "y", gen_p = "ów", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "owie", voc_s = "o" },
["g"] = { depr_p = "i", gen_s = "i" },
},
},
["m-pr surname sg "] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", dat_s = "owi", depr_p = "y", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ac"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["acz"] = { nom_p = "owie" },
["ai"] = { dat_p = { "m", "om" }, dat_s = { "emu", "owi" }, gen_p = { "ch", "ów" }, gen_s = { "a", "ego" }, ins_p = { "ami", "mi" }, ins_s = { "em", "m" }, loc_p = { "ach", "ch" }, loc_s = { "m", "u" } },
["az"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["b"] = { loc_s = { "e", stem = "palatal" } },
["bót"] = { dat_p = { { "om", stem = "shortened" }, "om" }, dat_s = { { "owi", stem = "shortened" }, "owi" }, depr_p = { { "y", stem = "shortened" }, "y" }, gen_p = { { "ów", stem = "shortened" }, "ów" }, gen_s = { { "a", stem = "shortened" }, "a" }, ins_p = { { "ami", stem = "shortened" }, "ami" }, ins_s = { { "em", stem = "shortened" }, "em" }, loc_p = { { "ach", stem = "shortened" }, "ach" }, loc_s = { { "e", stem = "shortened+palatal" }, { "e", stem = "palatal" } }, nom_p = { { "owie", stem = "shortened" }, "owie" } },
["c"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "e", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "owie", stem = "reduced" } },
["d"] = { loc_s = { "e", stem = "palatal" } },
["dz"] = { nom_p = "owie" },
["ecz"] = { nom_p = "owie" },
["ek"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, depr_p = { "i", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "owie", stem = "reduced" } },
["el"] = { dat_p = { "om", { "om", stem = "reduced" } }, dat_s = { "owi", { "owi", stem = "reduced" } }, depr_p = { "e", { "e", stem = "reduced" } }, gen_p = { "ów", { "ów", stem = "reduced" } }, gen_s = { "a", { "a", stem = "reduced" } }, ins_p = { "ami", { "ami", stem = "reduced" } }, ins_s = { "em", { "em", stem = "reduced" } }, loc_p = { "ach", { "ach", stem = "reduced" } }, loc_s = { "u", { "u", stem = "reduced" } }, nom_p = { "owie", { "owie", stem = "reduced" } } },
["ez"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["eł"] = { dat_p = { "om", { "om", stem = "reduced" } }, dat_s = { "owi", { "owi", stem = "reduced" } }, depr_p = { "y", { "y", stem = "reduced" } }, gen_p = { "ów", { "ów", stem = "reduced" } }, gen_s = { "a", { "a", stem = "reduced" } }, ins_p = { "ami", { "ami", stem = "reduced" } }, ins_s = { "em", { "em", stem = "reduced" } }, loc_p = { "ach", { "ach", stem = "reduced" } }, loc_s = { { "e", stem = "palatal" }, { "e", stem = "reduced+palatal" } }, nom_p = { "owie", { "owie", stem = "reduced" } } },
["f"] = { loc_s = { "e", stem = "palatal" } },
["g"] = { depr_p = "i", ins_s = "iem" },
["i"] = { depr_p = "e" },
["ic"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["iel"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ieł"] = { dat_p = "om", dat_s = "owi", depr_p = "y", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["ix"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, depr_p = { "y", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, gen_s = { "a", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "owie", stem = "spelled" } },
["iz"] = { nom_p = "owie" },
["j"] = { depr_p = "e" },
["jc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["k"] = { depr_p = "i", ins_s = "iem" },
["kój"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "e", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "owie", stem = "shortened" } },
["l"] = { depr_p = "e" },
["lc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["lcz"] = { nom_p = "owie" },
["lz"] = { nom_p = "owie" },
["m"] = { loc_s = { "e", stem = "palatal" } },
["n"] = { loc_s = { "e", stem = "palatal" } },
["nc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ncz"] = { nom_p = "owie" },
["nz"] = { nom_p = "owie" },
["oc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ocz"] = { nom_p = "owie" },
["oe"] = { loc_s = { "", "m" } },
["oz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["p"] = { loc_s = { "e", stem = "palatal" } },
["pc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["r"] = { loc_s = { "e", stem = "palatal" } },
["rc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["rcz"] = { nom_p = "owie" },
["reć"] = { dat_p = { { "om", stem = "reduced" }, "om" }, dat_s = { { "owi", stem = "reduced" }, "owi" }, depr_p = { { "e", stem = "reduced" }, "e" }, gen_p = { { "ów", stem = "reduced" }, "ów" }, gen_s = { { "a", stem = "reduced" }, "a" }, ins_p = { { "ami", stem = "reduced" }, "ami" }, ins_s = { { "em", stem = "reduced" }, "em" }, loc_p = { { "ach", stem = "reduced" }, "ach" }, loc_s = { { "u", stem = "reduced" }, "u" }, nom_p = { { "owie", stem = "reduced" }, "owie" } },
["rp"] = { dat_p = { { "om", stem = "palatal" }, "om" }, dat_s = { { "owi", stem = "palatal" }, "owi" }, depr_p = { { "e", stem = "palatal" }, "y" }, gen_p = { { "ów", stem = "palatal" }, "ów" }, gen_s = { "a", { "a", stem = "palatal" } }, ins_p = { "ami", { "ami", stem = "palatal" } }, ins_s = { "em", { "em", stem = "palatal" } }, loc_p = { "ach", { "ach", stem = "palatal" } }, loc_s = { { "e", stem = "palatal" }, { "u", stem = "palatal" } }, nom_p = { { "owie", stem = "palatal" }, "owie" } },
["rz"] = { nom_p = "owie" },
["rót"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "owie", stem = "shortened" } },
["róz"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "owie", stem = "shortened" } },
["s"] = { loc_s = { "e", stem = "palatal" } },
["t"] = { loc_s = { "e", stem = "palatal" } },
["tz"] = { nom_p = "owie" },
["u"] = { loc_s = "" },
["uc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ucz"] = { nom_p = "owie" },
["uz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["w"] = { loc_s = { "e", stem = "palatal" } },
["wc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["wec"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["y"] = { depr_p = "e" },
["yc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ycz"] = { nom_p = "owie" },
["yz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["z"] = { depr_p = "e", nom_p = { "e", "owie" } },
["zcz"] = { nom_p = "owie" },
["ód"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "owie", stem = "shortened" } },
["óg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "i", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "owie", stem = "shortened" } },
["ój"] = { dat_p = { { "om", stem = "shortened" }, "om" }, dat_s = { { "owi", stem = "shortened" }, "owi" }, depr_p = { { "e", stem = "shortened" }, "e" }, gen_p = { { "ów", stem = "shortened" }, "ów" }, gen_s = { { "a", stem = "shortened" }, "a" }, ins_p = { { "ami", stem = "shortened" }, "ami" }, ins_s = { { "em", stem = "shortened" }, "em" }, loc_p = { { "ach", stem = "shortened" }, "ach" }, loc_s = { { "u", stem = "shortened" }, "u" }, nom_p = { { "owie", stem = "shortened" }, "owie" } },
["ól"] = { dat_p = { { "om", stem = "shortened" }, "om" }, dat_s = { { "owi", stem = "shortened" }, "owi" }, depr_p = { { "e", stem = "shortened" }, "e" }, gen_p = { { "ów", stem = "shortened" }, "ów" }, gen_s = { { "a", stem = "shortened" }, "a" }, ins_p = { { "ami", stem = "shortened" }, "ami" }, ins_s = { { "em", stem = "shortened" }, "em" }, loc_p = { { "ach", stem = "shortened" }, "ach" }, loc_s = { { "u", stem = "shortened" }, "u" }, nom_p = { { "owie", stem = "shortened" }, "owie" } },
["ór"] = { dat_p = { { "om", stem = "shortened" }, "om" }, dat_s = { { "owi", stem = "shortened" }, "owi" }, depr_p = { { "y", stem = "shortened" }, "y" }, gen_p = { { "ów", stem = "shortened" }, "ów" }, gen_s = { { "a", stem = "shortened" }, "a" }, ins_p = { { "ami", stem = "shortened" }, "ami" }, ins_s = { { "em", stem = "shortened" }, "em" }, loc_p = { { "ach", stem = "shortened" }, "ach" }, loc_s = { { "e", stem = "shortened+palatal" }, { "e", stem = "palatal" } }, nom_p = { { "owie", stem = "shortened" }, "owie" } },
["ów"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, depr_p = { "y", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "owie", stem = "shortened" } },
["ół"] = { dat_p = { { "om", stem = "shortened" }, "om" }, dat_s = { { "owi", stem = "shortened" }, "owi" }, depr_p = { { "y", stem = "shortened" }, "y" }, gen_p = { { "ów", stem = "shortened" }, "ów" }, gen_s = { { "a", stem = "shortened" }, "a" }, ins_p = { { "ami", stem = "shortened" }, "ami" }, ins_s = { { "em", stem = "shortened" }, "em" }, loc_p = { { "ach", stem = "shortened" }, "ach" }, loc_s = { { "e", stem = "shortened+palatal" }, { "e", stem = "palatal" } }, nom_p = { { "owie", stem = "shortened" }, "owie" } },
["ąc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ącz"] = { nom_p = "owie" },
["ąz"] = { depr_p = "y", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["ć"] = { depr_p = "e" },
["ęc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["ęcz"] = { nom_p = "owie" },
["ł"] = { loc_s = { "e", stem = "palatal" } },
["łc"] = { dat_p = "om", dat_s = "owi", depr_p = "e", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "owie" },
["łcz"] = { nom_p = "owie" },
["ń"] = { depr_p = "e" },
["ńcz"] = { nom_p = "owie" },
["ś"] = { depr_p = "e", nom_p = { "e", "owie" } },
["ź"] = { depr_p = "e" },
["ż"] = { depr_p = "e" },
},
},
["m-pr surname sg a"] = {
copies = { acc_p = "gen_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = "y", gen_p = "ów", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "owie", voc_s = "o" },
["c"] = { dat_s = "y", depr_p = "e" },
["cz"] = { dat_s = "y", depr_p = "e" },
["czm"] = { dat_s = "ie" },
["dz"] = { dat_s = "y", depr_p = "e" },
["g"] = { depr_p = "i", gen_s = "i" },
["i"] = { dat_s = "", depr_p = "e", gen_s = "" },
["j"] = { depr_p = "e" },
["k"] = { depr_p = "i", gen_s = "i" },
["l"] = { dat_s = "i", depr_p = "e", gen_s = "i" },
["pi"] = { dat_s = "i", gen_s = "i" },
["ri"] = { dat_s = "i", gen_s = "i" },
["rz"] = { dat_s = "y", depr_p = "e" },
["sm"] = { dat_s = "ie" },
["sz"] = { dat_s = "y", depr_p = "e" },
["v"] = { dat_s = "ie" },
["wi"] = { dat_s = "i", gen_s = "i" },
["x"] = { dat_s = { "e", stem = "spelled+palatal" } },
["y"] = { depr_p = "e" },
["yzm"] = { dat_s = { "ie", { "e", stem = "palatal", note = "proscribed" } } },
["ż"] = { dat_s = "y", depr_p = "e" },
},
},
["m-pr surname sg e"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "om", dat_s = "emu", depr_p = "e", gen_p = "ów", gen_s = "ego", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "em", nom_p = "owie", voc_s = "e" },
["ak"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "i", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "iem", loc_p = "e'ach", loc_s = "e'u", nom_p = "e'owie", voc_s = "e'u" },
["ant"] = { dat_p = "om", dat_s = "emu", depr_p = "e", gen_p = "ów", gen_s = "ego", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "em", nom_p = "owie", voc_s = "e" },
["bl"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'e", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = "e'u", nom_p = "e'owie", voc_s = "e'u" },
["c"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", nom_p = "e'owie" },
["gn"] = { depr_p = "e'e", loc_s = "e'u", voc_s = "e'u" },
["id"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_s = { "e", stem = "palatal" } },
["ion"] = { depr_p = "e", voc_s = "e" },
["n"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_s = { "e", stem = "palatal" } },
["ow"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = "e", nom_p = "e'owie" },
["r"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_s = { "e", stem = "palatal" } },
["rt"] = { dat_p = "om", dat_s = "emu", depr_p = "e", gen_p = "ów", gen_s = "ego", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "em", nom_p = "owie", voc_s = "e" },
["t"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'owie", voc_s = { "e", stem = "palatal" } },
["v"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'y", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", nom_p = "e'owie" },
["yl"] = { dat_p = "e'om", dat_s = "e'owi", depr_p = "e'e", gen_p = "e'ów", gen_s = "e'a", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = "e'u", nom_p = "e'owie", voc_s = "e'u" },
},
},
["m-pr surname sg i"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "im", dat_s = "iemu", depr_p = "ie", gen_p = "ich", gen_s = "iego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = { "y", stem = "palatal" } },
["ak"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["c"] = { nom_p = { "i", "iowie" } },
["czk"] = { nom_p = "owie" },
["d"] = { nom_p = { "i", "iowie" } },
["dk"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["f"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { { "", stem = "palatal" }, { "owie", stem = "palatal" } } },
["g"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["h"] = { nom_p = { "i", "iowie" } },
["hk"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["lk"] = { nom_p = "owie" },
["m"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { { "", stem = "palatal" }, { "owie", stem = "palatal" } } },
["n"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { { "", stem = "palatal" }, { "owie", stem = "palatal" } } },
["r"] = { nom_p = { "i", "iowie" } },
["s"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { { "", stem = "palatal" }, { "owie", stem = "palatal" } } },
["t"] = { nom_p = { "i", "iowie" } },
["tk"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
["z"] = { dat_p = { "m", stem = "palatal" }, dat_s = { "emu", stem = "palatal" }, depr_p = { "e", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, gen_s = { "ego", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, ins_s = { "m", stem = "palatal" }, loc_p = { "ch", stem = "palatal" }, loc_s = { "m", stem = "palatal" }, nom_p = { { "", stem = "palatal" }, { "owie", stem = "palatal" } } },
["śk"] = { nom_p = { { "y", stem = "palatal" }, "owie" } },
},
},
["m-pr surname sg o"] = {
copies = { acc_p = "gen_p", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = "i", gen_p = "ów", gen_s = "i", ins_p = "ami", ins_s = "ą", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "owie" },
["and"] = { acc_s = { "a", "ę" }, dat_s = { "owi", { "e", stem = "palatal" } }, gen_s = { "a", "y" }, ins_s = { "em", "ą" } },
["d"] = { depr_p = "y" },
["ejn"] = { acc_s = { "a", "o", "ę" }, dat_p = { "o", "om" }, dat_s = { { "e", stem = "palatal" }, "o", "owi" }, depr_p = { "o", "y" }, gen_p = { "o", "ów" }, gen_s = { "a", "o", "y" }, ins_p = { "ami", "o" }, ins_s = { "em", "o", "ą" }, loc_p = { "ach", "o" }, loc_s = { { "e", stem = "palatal" }, "o" }, nom_p = { "o", "owie" } },
["ett"] = { acc_s = "a", dat_s = "owi", gen_s = "a", ins_s = "em" },
["h"] = { depr_p = "y", gen_s = "y" },
["i"] = { acc_s = "a", dat_s = "owi", depr_p = "e", gen_s = "a", ins_s = "em", loc_s = "u" },
["ied"] = { acc_s = { "a", "o" }, dat_p = { "o", "om" }, dat_s = { "o", "owi" }, depr_p = { "o", "y" }, gen_p = { "o", "ów" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", { "e", stem = "palatal" } }, nom_p = { "o", "owie" } },
["j"] = { acc_s = "a", dat_s = "owi", depr_p = "e", gen_s = "a", ins_s = "em", loc_s = "u" },
["jd"] = { acc_s = { "a", "ę" }, dat_s = { "owi", { "e", stem = "palatal" } }, gen_s = { "a", "y" }, ins_s = { "em", "ą" } },
["jm"] = { depr_p = "y", gen_s = "y" },
["l"] = { acc_s = "a", dat_s = "owi", depr_p = "e", gen_s = "a", ins_s = "em", loc_s = "u" },
["mb"] = { dat_p = { "o", "om" }, depr_p = { "o", "y" }, gen_p = { "o", "ów" }, ins_p = { "ami", "o" }, loc_p = { "ach", "o" }, nom_p = { "o", "owie" } },
["n"] = { depr_p = "y", gen_s = "y" },
["ng"] = { acc_s = { "a", "o", "ę" }, dat_p = { "o", "om" }, dat_s = { { "e", stem = "palatal" }, "o", "owi" }, depr_p = { "i", "o" }, gen_p = { "o", "ów" }, gen_s = { "a", "i", "o" }, ins_p = { "ami", "o" }, ins_s = { "iem", "o", "ą" }, loc_p = { "ach", "o" }, loc_s = { { "e", stem = "palatal" }, "o", "u" }, nom_p = { "o", "owie" } },
["nt"] = { acc_s = { "a", "o", "ę" }, dat_p = { "o", "om" }, dat_s = { { "e", stem = "palatal" }, "o", "owi" }, depr_p = { "o", "y" }, gen_p = { "o", "ów" }, gen_s = { "a", "o", "y" }, ins_p = { "ami", "o" }, ins_s = { "em", "o", "ą" }, loc_p = { "ach", "o" }, loc_s = { { "e", stem = "palatal" }, "o" }, nom_p = { "o", "owie" } },
["ott"] = { acc_s = "a", dat_s = "owi", gen_s = "a", ins_s = "em" },
["p"] = { depr_p = "y", gen_s = "y" },
["r"] = { depr_p = "y", gen_s = "y" },
["rd"] = { acc_s = { "a", "ę" }, dat_s = { "owi", { "e", stem = "palatal" } }, gen_s = { "a", "y" }, ins_s = { "em", "ą" } },
["rr"] = { acc_s = "a", dat_s = "owi", gen_s = "a", ins_s = "em" },
["ss"] = { acc_s = "a", dat_s = "owi", depr_p = "y", gen_s = "a", ins_s = "em" },
["t"] = { depr_p = "y", gen_s = "y" },
["yd"] = { acc_s = { "a", "ę" }, dat_s = { "owi", { "e", stem = "palatal" } }, gen_s = { "a", "y" }, ins_s = { "em", "ą" } },
["z"] = { acc_s = { "a", "ę" }, dat_s = { "owi", "y" }, depr_p = "e", gen_s = { "a", "y" }, ins_s = { "em", "ą" }, loc_s = { "u", "y" } },
["zad"] = { acc_s = { "a", "ę" }, dat_s = { "owi", { "e", stem = "palatal" } }, gen_s = { "a", "y" }, ins_s = { "em", "ą" } },
["ł"] = { depr_p = "y", gen_s = "y" },
["łd"] = { gen_s = "y" },
["ńd"] = { gen_s = "y" },
},
},
["m-pr surname sg y"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = { { "i", stem = "palatal" }, "owie" }, voc_s = "y" },
["r"] = { dat_s = "y'emu", depr_p = "y'e", gen_s = "y'ego", nom_p = "y" },
["sk"] = { dat_p = "im", depr_p = "ie", gen_p = "ich", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = { "y", stem = "palatal" } },
["t"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["wat"] = { nom_p = { "", stem = "palatal" } },
},
},
["m-anml common sg "] = {
copies = { acc_p = "nom_p", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { acc_s = "a", dat_p = "om", dat_s = "owi", depr_p = {}, gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "y" },
["ac"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", loc_p = "ach", loc_s = "u" },
["arp"] = { gen_p = { "", stem = "palatal" } },
["art"] = { acc_s = { "", "a" }, gen_s = { "a", "u" } },
["az"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["aź"] = { nom_p = "e" },
["b"] = { loc_s = { "e", stem = "palatal" } },
["bal"] = { gen_p = "i" },
["bel"] = { acc_s = { "a", stem = "reduced" }, dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["c"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["d"] = { loc_s = { "e", stem = "palatal" } },
["dał"] = { acc_s = { "", "a" } },
["del"] = { acc_s = { "a", stem = "reduced" }, dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["dz"] = { gen_p = "ów" },
["ec"] = { acc_s = { { "a", stem = "reduced" }, "" } },
["edź"] = { gen_p = { "", stem = "soft" }, nom_p = "e" },
["eet"] = { acc_s = { "", "a" }, gen_s = { "a", "u" } },
["ek"] = { acc_s = { "a", stem = "reduced" }, dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "i", stem = "reduced" } },
["f"] = { loc_s = { "e", stem = "palatal" } },
["g"] = { ins_s = "iem", nom_p = "i" },
["iel"] = { gen_p = "i" },
["ieł"] = { loc_s = { "e", stem = "reduced+palatal" } },
["iz"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["j"] = { nom_p = "e" },
["jec"] = { acc_s = { "a", stem = "reduced" } },
["k"] = { ins_s = "iem", nom_p = "i" },
["l"] = { gen_p = { "i", "ów" }, nom_p = "e" },
["lac"] = { gen_p = "ów" },
["lec"] = { acc_s = { "a", stem = "reduced" } },
["m"] = { loc_s = { "e", stem = "palatal" } },
["mul"] = { gen_p = "i" },
["n"] = { loc_s = { "e", stem = "palatal" } },
["niś"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["oll"] = { gen_p = "i" },
["ont"] = { acc_s = { "", "a" }, gen_s = { "a", "u" } },
["oz"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["oś"] = { gen_p = { "", stem = "soft" } },
["p"] = { loc_s = { "e", stem = "palatal" } },
["paw"] = { acc_s = { "a", stem = "palatal" }, dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["peć"] = { acc_s = { { "a", stem = "reduced" }, "" }, dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["r"] = { loc_s = { "e", stem = "palatal" } },
["raś"] = { gen_p = { "", stem = "soft" } },
["rp"] = { acc_s = { "a", stem = "palatal" }, dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["s"] = { loc_s = { "e", stem = "palatal" } },
["sz"] = { gen_p = { "y", "ów" } },
["t"] = { loc_s = { "e", stem = "palatal" } },
["tat"] = { acc_s = { "", "a" } },
["tu"] = { depr_p = "" },
["tw"] = { loc_s = { "e", stem = "palatal" } },
["u"] = { acc_s = "", dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["uc"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["uz"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["wół"] = { acc_s = { { "a", stem = "shortened" }, { "u", stem = "shortened" } }, gen_s = { { "a", stem = "shortened" }, { "u", stem = "shortened" } } },
["x"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "y", stem = "spelled" } },
["y"] = { nom_p = "e" },
["yz"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["yś"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["z"] = { gen_p = { "y", { "ów", note = "rare" } }, nom_p = "e" },
["zal"] = { gen_p = "i" },
["é"] = { acc_s = "", dat_p = "", dat_s = "", depr_p = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["ód"] = { acc_s = { "a", stem = "shortened" }, dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["óg"] = { acc_s = { "a", stem = "shortened" }, dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ór"] = { acc_s = { "a", stem = "shortened" }, dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ów"] = { acc_s = { "a", stem = "shortened" }, dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ół"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ąc"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ć"] = { nom_p = "e" },
["ł"] = { loc_s = { "e", stem = "palatal" } },
["ław"] = { loc_s = { "e", stem = "palatal" } },
["łż"] = { gen_p = { "y", "ów" } },
["ń"] = { gen_p = { "", stem = "soft" }, nom_p = "e" },
["ś"] = { nom_p = "e" },
["ż"] = { nom_p = "e" },
["żec"] = { acc_s = { "a", stem = "reduced" } },
},
},
["m-anml common sg a"] = {
copies = { acc_p = "nom_p", loc_s = "dat_s", voc_p = "nom_p" },
rules = {
[""] = { acc_s = "ę", dat_p = "om", dat_s = { "e", stem = "palatal" }, depr_p = {}, gen_p = "ów", gen_s = "y", ins_p = "ami", ins_s = "ą", loc_p = "ach", nom_p = "y", voc_s = "o" },
["c"] = { dat_s = "y", nom_p = "e" },
["j"] = { dat_s = "i", gen_p = "i", gen_s = "i", nom_p = "e" },
["k"] = { gen_s = "i", nom_p = "i" },
["l"] = { dat_s = "i", gen_p = "i", gen_s = "i", nom_p = "e" },
["o"] = { acc_s = "a", dat_p = "a", dat_s = "a", gen_p = "a", gen_s = "a", ins_p = "a", ins_s = "a", loc_p = "a", nom_p = "a", voc_s = "a" },
["u"] = { acc_s = "a", dat_p = "a", dat_s = "a", gen_p = "a", gen_s = "a", ins_p = "a", ins_s = "a", loc_p = "a", nom_p = "a", voc_s = "a" },
},
},
["m-anml common sg e"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "e", dat_s = "e", depr_p = {}, gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["z"] = { depr_p = "e" },
},
},
["m-anml common sg i"] = {
copies = { acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { acc_p = "i", dat_p = "i", dat_s = "i", depr_p = {}, gen_p = "i", gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", loc_s = "i", nom_p = "i" },
["s"] = { acc_p = { "", stem = "palatal" }, dat_p = { "", stem = "palatal" }, dat_s = { "", stem = "palatal" }, depr_p = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, loc_s = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["sk"] = { acc_p = "ie", dat_p = "im", dat_s = "iemu", gen_p = "ich", gen_s = "iego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = "ie" },
["z"] = { nom_p = { "", stem = "palatal" } },
},
},
["m-anml common sg o"] = {
copies = { voc_p = "nom_p" },
rules = {
[""] = { acc_p = "o", acc_s = "o", dat_p = "o", dat_s = "o", depr_p = {}, gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o", voc_s = "o" },
["er"] = { depr_p = "o" },
["ni"] = { acc_p = "e", acc_s = "a", dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["si"] = { acc_p = "e", acc_s = "a", dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
["ud"] = { acc_p = { "o", "y" }, acc_s = { "a", "o" }, dat_p = { "o", "om" }, dat_s = { "o", "owi" }, gen_p = { "o", "ów" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", { "e", stem = "palatal" } }, nom_p = { "o", "y" } },
},
},
["m-anml common sg y"] = {
copies = { voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { acc_p = "ych", acc_s = "ego", dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = { "", stem = "palatal" } },
["asz"] = { nom_p = "owie" },
["c"] = { nom_p = "y" },
["etw"] = { acc_p = "e", depr_p = {}, nom_p = "e" },
["on"] = { acc_p = "e", depr_p = {}, nom_p = "e" },
["ryw"] = { acc_p = "e", depr_p = {}, nom_p = "e" },
["rz"] = { nom_p = "owie" },
["t"] = { acc_p = "e", acc_s = { "ego", "y" }, depr_p = {}, nom_p = "e" },
["usz"] = { nom_p = "owie" },
["z"] = { nom_p = { "owie", "y" } },
["ór"] = { nom_p = { "y", stem = "palatal" } },
["ł"] = { nom_p = { "i", stem = "palatal" } },
["ż"] = { nom_p = "owie" },
},
},
["m-anml given sg "] = {
copies = { acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { acc_p = "y", dat_p = "om", dat_s = "owi", depr_p = {}, gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "", voc_s = "" },
["e"] = { acc_p = "ch", dat_p = "m", dat_s = "mu", depr_p = "", gen_p = "ch", gen_s = "go", ins_p = "mi", ins_s = "m", loc_p = "ch", loc_s = "m" },
["ks"] = { nom_p = "y", voc_s = { "e", stem = "palatal" } },
["r"] = { nom_p = "y", voc_s = { "e", stem = "palatal" } },
["u"] = { acc_p = "", dat_p = "", dat_s = "", depr_p = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "" },
},
},
["m-anml given sg e"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "e", dat_s = "e", depr_p = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
},
},
["m-anml given sg i"] = {
copies = { acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { acc_p = "ich", dat_p = "im", dat_s = "emu", depr_p = "e", gen_p = "ich", gen_s = "ego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = "owie" },
},
},
["m-anml given sg o"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "o", dat_s = "o", depr_p = { "a", "o" }, gen_p = "o", gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = "o", nom_p = "o" },
},
},
["m-anml given sg y"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "owie" },
["rr"] = { dat_s = { "emu", "y'emu" }, depr_p = { "e", "y'e" }, gen_s = { "ego", "y'ego" }, nom_p = { "owie", "y" } },
},
},
["m-anml proper sg "] = {
copies = { acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { acc_p = "y", dat_p = "om", dat_s = "owi", depr_p = {}, gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y", voc_s = { "e", stem = "palatal" } },
["ec"] = { acc_p = { "e", stem = "reduced" }, dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" }, voc_s = { "u", stem = "reduced" } },
["k"] = { acc_p = "i", ins_s = "iem", loc_s = "u", nom_p = "i", voc_s = "u" },
["sz"] = { acc_p = "e", gen_p = { "y", "ów" }, loc_s = "u", nom_p = "e", voc_s = "u" },
["u"] = { depr_p = "", nom_p = "", voc_s = "" },
["x"] = { acc_p = { "y", stem = "spelled" }, dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, gen_s = { "a", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "y", stem = "spelled" }, voc_s = { "e", stem = "spelled+palatal" } },
},
},
["m-anml proper sg e"] = {
copies = { },
rules = {
[""] = { acc_p = "e", acc_s = "e", dat_p = "e", dat_s = "e", depr_p = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e", voc_p = "e", voc_s = "e" },
},
},
["m-anml proper sg o"] = {
copies = { },
rules = {
[""] = { acc_p = "o", acc_s = "o", dat_p = "o", dat_s = "o", depr_p = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o", voc_p = "o", voc_s = "o" },
},
},
["m-anml proper sg y"] = {
copies = { },
rules = {
[""] = { acc_p = "ych", acc_s = "ego", dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = { "", stem = "palatal" }, voc_p = { "", stem = "palatal" }, voc_s = "y" },
},
},
["m-anml surname sg "] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "", dat_s = "", depr_p = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "", voc_s = "" },
["cu"] = { dat_p = "", dat_s = "", depr_p = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["d"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, depr_p = { "", "y" }, gen_p = { "", "ów" }, gen_s = { "", "a" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "owie" }, voc_s = { "", { "e", stem = "palatal" } } },
["eau"] = { dat_p = "", dat_s = "", depr_p = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", nom_p = "" },
["es"] = { dat_p = "'om", dat_s = "'owi", gen_p = "'ów", gen_s = "'a", ins_p = "'ami", loc_p = "'ach", loc_s = "'u", nom_p = "'owie", voc_s = "'u" },
["eu"] = { depr_p = "", nom_p = "" },
["i"] = { dat_p = { "", "m" }, gen_p = { "", "ch" }, ins_p = { "", "mi" }, ins_s = { "", "m" }, loc_p = { "", "ch" }, loc_s = { "", "m" } },
["ieu"] = { dat_p = { "", "m" }, dat_s = { "", "mu" }, gen_p = { "", "ch" }, gen_s = { "", "go" }, ins_p = { "", "mi" }, ins_s = { "", "m" }, loc_p = { "", "ch" }, loc_s = { "", "m" } },
["que"] = { dat_p = "'om", dat_s = "'owi", gen_p = "'ów", gen_s = "'a", ins_p = "'ami", loc_p = "'ach", loc_s = "'u", nom_p = "'owie", voc_s = "'u" },
["u"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, depr_p = { "", "y" }, gen_p = { "", "ów" }, gen_s = { "", "a" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, nom_p = { "", "owie" } },
},
},
["m-anml surname sg e"] = {
copies = { },
rules = {
[""] = { acc_p = "e", acc_s = "e", dat_p = "e", dat_s = "e", depr_p = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e", voc_p = "e", voc_s = "e" },
},
},
["m-anml surname sg i"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "im", dat_s = "emu", depr_p = "e", gen_p = "ich", gen_s = "ego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = "i" },
["l"] = { nom_p = { "i", "owie" } },
},
},
["m-anml surname sg o"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "o", depr_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", nom_p = "o" },
},
},
["m-anml surname sg y"] = {
copies = { acc_p = "gen_p", acc_s = "gen_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = "e", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "owie" },
["ern"] = { nom_p = "owie" },
["h"] = { nom_p = { "owie", { "i", stem = "virile" } } },
["iad"] = { nom_p = { "owie", { "", stem = "palatal" } } },
["l"] = { dat_p = "im", gen_p = "ich", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im" },
["n"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["st"] = { nom_p = { "owie", { "", stem = "palatal" } } },
["sł"] = { nom_p = { "owie", { "i", stem = "palatal" } } },
["w"] = { nom_p = { { "", stem = "palatal" }, "owie" } },
["ąc"] = { nom_p = { "owie", "y" } },
["źn"] = { nom_p = "owie" },
},
},
["m-in common sg "] = {
copies = { acc_p = "nom_p", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { acc_s = "", dat_p = "om", dat_s = "owi", depr_p = {}, gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["A"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["AN"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["AT"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, nom_p = { "", "-y" } },
["C"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["CD"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["CR"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ze", nom_p = "-y" },
["DD"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["DL"] = { gen_p = "-i", gen_s = "-u" },
["I"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["IT"] = { dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, nom_p = { "", "-y" } },
["K"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["L"] = { dat_p = "-om", dat_s = "-owi", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-u", nom_p = "-e" },
["M"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["ML"] = { acc_s = { "", "-a" }, gen_p = { "-i", "-ów" }, gen_s = { "-a", "-u" } },
["OP"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["OR"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ze", nom_p = "-y" },
["P"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["S"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["V"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["abl"] = { gen_s = "a" },
["ac"] = { dat_p = "om", dat_s = "owi", ins_p = "ami", loc_p = "ach", loc_s = "u" },
["ak"] = { gen_s = "a" },
["am"] = { loc_s = { "e", stem = "palatal" } },
["arc"] = { gen_s = "u" },
["az"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["bel"] = { gen_p = { "i", stem = "reduced" } },
["ber"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "y", stem = "reduced" } },
["bul"] = { gen_s = "u" },
["c"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["cel"] = { dat_p = "om", dat_s = "owi", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["cer"] = { gen_s = "a" },
["cik"] = { gen_s = "u" },
["dej"] = { gen_s = { "a", "u" } },
["dol"] = { gen_p = { "i", "ów" } },
["ecz"] = { gen_s = "u" },
["ek"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "i", stem = "reduced" } },
["el"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["em"] = { loc_s = { "e", stem = "palatal" } },
["enc"] = { gen_s = "a" },
["eus"] = { gen_s = "a" },
["ez"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["eć"] = { gen_p = { "", stem = "reduced+soft" } },
["eł"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "y", stem = "reduced" } },
["fel"] = { gen_p = { "i", stem = "reduced" } },
["g"] = { ins_s = "iem", loc_s = "u", nom_p = "i" },
["ger"] = { gen_s = "a" },
["gor"] = { gen_s = "u" },
["gół"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["h"] = { loc_s = "u" },
["hej"] = { gen_s = { "a", "u" } },
["her"] = { gen_s = "a" },
["hol"] = { gen_p = { "i", "ów" } },
["hyl"] = { gen_p = "i" },
["hór"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["i"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["ial"] = { gen_p = { "i", "ów" } },
["ic"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["idz"] = { gen_p = "ów" },
["iej"] = { gen_s = "a" },
["iek"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["ień"] = { gen_p = { "", stem = "soft" } },
["ij"] = { gen_s = "a" },
["ik"] = { gen_s = "a" },
["il"] = { gen_p = { "i", "ów" } },
["im"] = { loc_s = { "e", stem = "palatal" } },
["ior"] = { gen_s = "u" },
["isz"] = { gen_s = "u" },
["itr"] = { gen_s = "a" },
["iz"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["izd"] = { loc_s = { "e", stem = "palatal" } },
["iąc"] = { gen_p = { "y", stem = "shortened" } },
["iąk"] = { gen_s = "u" },
["iąz"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["iść"] = { ins_p = "mi" },
["j"] = { loc_s = "u", nom_p = "e" },
["jas"] = { gen_s = "a" },
["jem"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "u", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "y", stem = "reduced" } },
["jm"] = { loc_s = { "e", stem = "palatal" } },
["k"] = { ins_s = "iem", loc_s = "u", nom_p = "i" },
["kal"] = { gen_p = "i" },
["kch"] = { gen_s = { "a", "u" } },
["kej"] = { acc_s = { "", "a" }, gen_s = "a" },
["ker"] = { gen_s = "a" },
["kic"] = { gen_s = "u" },
["kl"] = { gen_p = { "i", "ów" } },
["kor"] = { gen_s = "u" },
["koń"] = { gen_p = { "", stem = "soft" } },
["kul"] = { gen_s = "u" },
["l"] = { loc_s = "u", nom_p = "e" },
["laż"] = { gen_p = "y" },
["lc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ler"] = { gen_s = "a" },
["leń"] = { gen_p = { "", stem = "soft" } },
["ll"] = { gen_p = { "i", "ów" } },
["lm"] = { loc_s = { "e", stem = "palatal" } },
["lor"] = { gen_s = "u" },
["lus"] = { gen_s = "a" },
["ląt"] = { gen_s = "u" },
["m"] = { loc_s = { "ie", { "e", stem = "palatal", note = "proscribed" } } },
["maj"] = { gen_s = "a" },
["mbl"] = { gen_p = { "i", "ów" } },
["mik"] = { gen_s = "u" },
["mor"] = { gen_s = "u" },
["nal"] = { gen_p = { "i", "ów" } },
["nar"] = { gen_s = "a" },
["nc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["nch"] = { nom_p = "e" },
["nek"] = { gen_s = { "u", stem = "reduced" } },
["nel"] = { dat_p = "om", dat_s = "owi", gen_p = { "i", "ów" }, gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ner"] = { gen_s = "a" },
["neż"] = { gen_p = "y", gen_s = { "a", "u" } },
["nol"] = { gen_p = "i" },
["nor"] = { gen_s = "u" },
["nsz"] = { gen_s = "u" },
["nur"] = { gen_s = "a" },
["nus"] = { gen_s = { "a", "u" } },
["nyp"] = { gen_s = "a" },
["nóż"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { { "y", stem = "shortened" }, { "ów", stem = "shortened" } }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["oc"] = { dat_p = "om", dat_s = "owi", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["och"] = { gen_s = "a" },
["ocz"] = { gen_s = "u" },
["oik"] = { gen_s = "u" },
["om"] = { loc_s = { "e", stem = "palatal" } },
["ool"] = { gen_p = "i" },
["or"] = { gen_s = "a" },
["otl"] = { gen_p = { "i", "ów" } },
["our"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "y" } },
["oz"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["pel"] = { gen_p = { "i", stem = "reduced" } },
["per"] = { gen_s = "a" },
["pik"] = { gen_s = "u" },
["pol"] = { gen_p = { "i", "ów" } },
["por"] = { gen_s = "u" },
["prz"] = { gen_s = "u" },
["ral"] = { gen_p = { "i", "ów" } },
["rc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["rcz"] = { gen_s = "u" },
["rel"] = { dat_p = "om", dat_s = "owi", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["reń"] = { dat_p = { "om", { "om", stem = "reduced" } }, dat_s = { "owi", { "owi", stem = "reduced" } }, gen_s = { "a", { "a", stem = "reduced" } }, ins_p = { "ami", { "ami", stem = "reduced" } }, ins_s = { "em", { "em", stem = "reduced" } }, loc_p = { "ach", { "ach", stem = "reduced" } }, loc_s = { "u", { "u", stem = "reduced" } }, nom_p = { "e", { "e", stem = "reduced" } } },
["rm"] = { loc_s = { "e", stem = "palatal" } },
["rol"] = { gen_p = "i" },
["ror"] = { gen_s = "u" },
["rsz"] = { gen_s = "u" },
["rus"] = { acc_s = { "", "a" }, gen_s = "a" },
["rąg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["sar"] = { gen_s = "a" },
["sel"] = { gen_p = { "i", stem = "reduced" } },
["ser"] = { gen_s = "a" },
["sh"] = { nom_p = "e" },
["sm"] = { loc_s = "ie" },
["sz"] = { gen_p = { "y", "ów" } },
["tal"] = { gen_p = "i" },
["tch"] = { nom_p = "e" },
["til"] = { gen_p = "ów" },
["tm"] = { loc_s = { "e", stem = "palatal" } },
["tol"] = { gen_p = { "i", "ów" } },
["tus"] = { gen_s = "a" },
["tyk"] = { gen_s = "u" },
["u"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["uc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["uel"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ul"] = { gen_p = { "i", "ów" }, gen_s = "a" },
["um"] = { loc_s = { "e", stem = "palatal" } },
["unk"] = { acc_s = { "", "a" } },
["urz"] = { gen_s = "u" },
["uz"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["wl"] = { gen_p = "i" },
["wor"] = { gen_s = "u" },
["wyk"] = { gen_s = "u" },
["wyż"] = { gen_p = "ów" },
["x"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, gen_s = { "u", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "y", stem = "spelled" } },
["y"] = { loc_s = "u", nom_p = "e" },
["yc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["yj"] = { gen_s = "a" },
["yk"] = { gen_s = "a" },
["yl"] = { gen_p = { "i", "ów" } },
["ym"] = { loc_s = { "e", stem = "palatal" } },
["ysz"] = { gen_s = "u" },
["yz"] = { gen_p = "ów", gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["z"] = { gen_p = { "y", { "ów", note = "rare" } }, gen_s = "a", loc_s = "u", nom_p = "e" },
["zac"] = { gen_p = "ów" },
["zcz"] = { gen_s = "u" },
["zd"] = { loc_s = { "e", stem = "fronted+palatal" } },
["zel"] = { gen_p = { "i", stem = "reduced" } },
["zer"] = { gen_s = "a" },
["zeń"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["zol"] = { gen_p = "i" },
["ząg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ób"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ód"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["óg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ój"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["ól"] = { gen_p = { "i", "ów" } },
["ór"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["órg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ót"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ów"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["óz"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ół"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ąb"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ąc"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ąk"] = { gen_s = "a" },
["ąp"] = { dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["ąt"] = { gen_s = "a" },
["ć"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["łat"] = { gen_s = { "a", "u" } },
["łn"] = { gen_s = "a" },
["łup"] = { gen_s = "a" },
["łąg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ń"] = { gen_s = "a", loc_s = "u", nom_p = "e" },
["ńc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ś"] = { gen_s = "a", loc_s = "u", nom_p = "e" },
["ść"] = { dat_p = "om", dat_s = "owi", gen_p = { "", stem = "soft" }, gen_s = "a", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ź"] = { gen_s = "a", loc_s = "u", nom_p = "e" },
["ż"] = { gen_p = { "y", "ów" }, loc_s = "u", nom_p = "e" },
["żel"] = { dat_p = "om", dat_s = "owi", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["życ"] = { gen_s = "a" },
["żyk"] = { gen_s = "u" },
},
},
["m-in common sg a"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", gen_p = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "a", depr_p = {}, gen_s = "a", ins_p = "a", ins_s = "a", loc_p = "a", nom_p = "a" },
},
},
["m-in common sg e"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { acc_s = "e", dat_p = "e'om", dat_s = "e'owi", depr_p = {}, gen_p = "e'ów", gen_s = "e'u", ins_p = "e'ami", ins_s = "e'em", loc_p = "e'ach", loc_s = { "e", stem = "palatal" }, nom_p = "e'y" },
["air"] = { gen_s = "e'a" },
["g"] = { loc_s = "e'u", nom_p = "e'e" },
["hon"] = { acc_s = { "e", "e'a" }, gen_s = "e'a" },
["lag"] = { gen_p = { "e'y", "e'ów" } },
["ll"] = { loc_s = "e'u", nom_p = "e'e" },
["z"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
},
},
["m-in common sg i"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { acc_s = "i", dat_p = "im", dat_s = "iemu", depr_p = {}, gen_p = "ich", gen_s = "iego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = "ie" },
["an"] = { dat_p = { "", stem = "palatal" }, dat_s = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, loc_s = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["l"] = { dat_p = "i", dat_s = "i", gen_p = "i", gen_s = "i", ins_p = "i", ins_s = "i", loc_p = "i", loc_s = "i", nom_p = "i" },
["m"] = { acc_s = { "", stem = "palatal" }, dat_p = { "", stem = "palatal" }, dat_s = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, loc_s = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
["n"] = { acc_s = { "", stem = "palatal" } },
},
},
["m-in common sg o"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p" },
rules = {
[""] = { dat_p = "o", dat_s = "o", depr_p = {}, gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o", voc_s = "o" },
["i"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e", voc_s = "u" },
},
},
["m-in common sg y"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = {}, gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "e" },
},
},
["m-in place sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", dat_s = "owi", depr_p = {}, gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["Kum"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "y" } },
["N"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["R"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["adz"] = { gen_p = { "y", "ów" } },
["aj"] = { gen_s = "u" },
["ak"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["al"] = { gen_p = "i" },
["am"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["an"] = { gen_s = "u" },
["ask"] = { gen_s = "u" },
["aw"] = { dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_p = { { "", stem = "palatal" }, { "ów", stem = "palatal" } }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["az"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["azd"] = { loc_s = { "e", stem = "fronted+palatal" } },
["ał"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["bcz"] = { gen_p = "ów" },
["bel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "i", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["ber"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "y", stem = "reduced" } },
["biń"] = { gen_p = { "", stem = "soft" } },
["boń"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["byl"] = { gen_p = { "i", "ów" } },
["c"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["ceń"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["ck"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["d"] = { gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["der"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "e", stem = "reduced+palatal" }, nom_p = { "y", stem = "reduced" } },
["doń"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["duń"] = { gen_p = { "", stem = "soft" } },
["dyń"] = { gen_p = { "", stem = "soft" } },
["dz"] = { gen_p = "ów" },
["ew"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["eń"] = { gen_p = { "", stem = "soft" } },
["eść"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["g"] = { ins_s = "iem", loc_s = "u", nom_p = "i" },
["gal"] = { gen_p = { "i", "ów" } },
["goń"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["h"] = { loc_s = "u", nom_p = "y" },
["hel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "i", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["ic"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ik"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["j"] = { loc_s = "u", nom_p = "e" },
["k"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_p = { "ów", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "iem", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "i", stem = "reduced" } },
["kok"] = { gen_s = "u" },
["l"] = { loc_s = "u", nom_p = "e" },
["las"] = { loc_s = { "e", stem = "fronted+palatal" } },
["lc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["lep"] = { gen_s = "u" },
["leń"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["lk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["lm"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["m"] = { dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_p = { { "", stem = "palatal" }, { "ów", stem = "palatal" } }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["n"] = { loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ng"] = { gen_s = "u" },
["nim"] = { dat_p = { { "om", stem = "palatal" }, "om" }, dat_s = { { "owi", stem = "palatal" }, "owi" }, gen_p = { { "ów", stem = "palatal" }, "ów" }, gen_s = { "a", { "a", stem = "palatal" } }, ins_p = { "ami", { "ami", stem = "palatal" } }, ins_s = { "em", { "em", stem = "palatal" } }, loc_p = { "ach", { "ach", stem = "palatal" } }, loc_s = { { "e", stem = "palatal" }, { "u", stem = "palatal" } }, nom_p = { { "e", stem = "palatal" }, "y" } },
["ok"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["ol"] = { gen_p = "i" },
["on"] = { gen_s = "u" },
["ork"] = { gen_s = "a" },
["oń"] = { gen_p = { "", stem = "soft" } },
["oś"] = { gen_p = { "", stem = "soft" } },
["ość"] = { gen_p = { { "", stem = "soft" }, "ów" } },
["p"] = { loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["pas"] = { gen_s = "a" },
["pcz"] = { gen_p = "ów" },
["pel"] = { dat_p = { "om", stem = "reduced" }, dat_s = { "owi", stem = "reduced" }, gen_s = { "a", stem = "reduced" }, ins_p = { "ami", stem = "reduced" }, ins_s = { "em", stem = "reduced" }, loc_p = { "ach", stem = "reduced" }, loc_s = { "u", stem = "reduced" }, nom_p = { "e", stem = "reduced" } },
["r"] = { gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ral"] = { gen_p = { "i", "ów" } },
["rb"] = { gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["rc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["rk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["rp"] = { dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_p = { "ów", stem = "palatal" }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["rsz"] = { gen_p = "y" },
["ryń"] = { gen_p = { "", stem = "soft" } },
["rój"] = { gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" } },
["róz"] = { gen_s = { { "a", stem = "shortened" }, { "u", stem = "shortened" } } },
["s"] = { gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["sk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["t"] = { gen_s = "u", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["tul"] = { gen_p = "i" },
["u"] = { dat_p = "", dat_s = "", gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["ub"] = { dat_p = { "om", stem = "palatal" }, dat_s = { "owi", stem = "palatal" }, gen_p = { { "", stem = "palatal" }, { "ów", stem = "palatal" } }, gen_s = { "a", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, ins_s = { "em", stem = "palatal" }, loc_p = { "ach", stem = "palatal" }, loc_s = { "u", stem = "palatal" }, nom_p = { "e", stem = "palatal" } },
["ud"] = { gen_s = "a" },
["uk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["um"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["us"] = { gen_s = "a" },
["uz"] = { gen_p = "ów", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["uł"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["vik"] = { gen_s = "u" },
["w"] = { dat_p = { "om", stem = "shortened" }, dat_s = { { "owi", stem = "shortened" }, { "u", stem = "shortened", note = "archaic" } }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" } },
["wil"] = { gen_p = { "i", "ów" } },
["wój"] = { gen_p = { "ów", stem = "shortened" } },
["yc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["yk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["yż"] = { gen_p = "ów" },
["z"] = { gen_p = { "y", "ów" }, loc_s = "u", nom_p = "e" },
["zk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["zok"] = { gen_s = "a" },
["zyż"] = { gen_p = { "y", "ów" } },
["ód"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["óg"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "iem", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "i", stem = "shortened" } },
["ój"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["ór"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, gen_s = { "u", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["órz"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "y", stem = "shortened" }, gen_s = { "a", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "u", stem = "shortened" }, nom_p = { "e", stem = "shortened" } },
["óz"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" }, loc_s = { "e", stem = "shortened+palatal" }, nom_p = { "y", stem = "shortened" } },
["ół"] = { gen_s = { "u", stem = "shortened" } },
["ąb"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" } },
["ąc"] = { dat_p = "om", dat_s = "owi", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ć"] = { loc_s = "u", nom_p = "e" },
["ęc"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["ędz"] = { gen_p = { "y", "ów" } },
["ęk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["ęp"] = { gen_s = "u" },
["ł"] = { dat_p = { "om", stem = "shortened" }, dat_s = { "owi", stem = "shortened" }, gen_p = { "ów", stem = "shortened" }, ins_p = { "ami", stem = "shortened" }, ins_s = { "em", stem = "shortened" }, loc_p = { "ach", stem = "shortened" } },
["łak"] = { gen_s = "u" },
["łk"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["łm"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["łub"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ń"] = { gen_p = { { "", stem = "soft" }, "ów" }, loc_s = "u", nom_p = "e" },
["ś"] = { loc_s = "u", nom_p = "e" },
["śl"] = { gen_p = { "i", "ów" } },
["ź"] = { gen_p = { "", stem = "soft" }, loc_s = "u", nom_p = "e" },
["ż"] = { gen_p = { "y", "ów" }, loc_s = "u", nom_p = "e" },
},
},
["m-in place sg e"] = {
copies = { },
rules = {
[""] = { acc_p = { "e", "e'y" }, acc_s = "e", dat_p = { "e", "e'om" }, dat_s = { "e", "e'owi" }, depr_p = {}, gen_p = { "e", "e'ów" }, gen_s = { "e", "e'u" }, ins_p = { "e", "e'ami" }, ins_s = { "e", "e'em" }, loc_p = { "e", "e'ach" }, loc_s = { "e", { "e", stem = "palatal" } }, nom_p = { "e", "e'y" }, voc_p = { "e", "e'y" }, voc_s = { "e", { "e", stem = "palatal" } } },
},
},
["m-in place sg i"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "im", dat_s = "iemu", depr_p = {}, gen_p = "ich", gen_s = "iego", ins_p = "imi", ins_s = "im", loc_p = "ich", loc_s = "im", nom_p = "ie" },
["p"] = { dat_p = { "", stem = "palatal" }, dat_s = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, gen_s = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, ins_s = { "", stem = "palatal" }, loc_p = { "", stem = "palatal" }, loc_s = { "", stem = "palatal" }, nom_p = { "", stem = "palatal" } },
},
},
["m-in place sg y"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ym", dat_s = "emu", depr_p = {}, gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "e" },
},
},
["m-in proper sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["J"] = { dat_p = { "", "-otom" }, dat_s = { "", "-otowi" }, gen_p = { "", "-otów" }, gen_s = { "", "-otu" }, ins_p = { "", "-otami" }, ins_s = { "", "-otem" }, loc_p = { "", "-otach" }, loc_s = { "", "-ocie" }, nom_p = { "", "-oty" } },
["L"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-i", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-u", nom_p = "-e" },
["M"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["N"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["OT"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", nom_p = "-y" },
["R"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ze", nom_p = "-y" },
["S"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-ie", nom_p = "-y" },
["Z"] = { dat_p = { "-etom", "-om" }, dat_s = { "-etowi", "-owi" }, gen_p = { "-etów", "-ów" }, gen_s = { "-etu", "-u" }, ins_p = { "-ami", "-etami" }, ins_s = { "-em", "-etem" }, loc_p = { "-ach", "-etach" }, loc_s = "-ecie", nom_p = { "-ety", "-y" } },
["am"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ax"] = { gen_s = { "u", stem = "spelled" } },
["b"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ch"] = { gen_p = "ów", gen_s = "u", nom_p = "y" },
["d"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["el"] = { gen_s = "a" },
["ex"] = { gen_s = { "u", stem = "spelled" } },
["g"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["h"] = { dat_p = "om", dat_s = "owi", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u" },
["iD"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-zie", nom_p = "-y" },
["iK"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-iem", loc_p = "-ach", loc_s = "-u", nom_p = "-i" },
["ic"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", loc_p = "ach", loc_s = "u" },
["k"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", ins_p = "ami", ins_s = "iem", loc_p = "ach", loc_s = "u", nom_p = "i" },
["kot"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { { "e", stem = "palatal" }, "" }, nom_p = { "", "y" } },
["l"] = { dat_p = "om", dat_s = "owi", gen_p = { "i", "ów" }, gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "e" },
["n"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["ok"] = { gen_s = "a" },
["r"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["s"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["t"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["x"] = { dat_p = { "om", stem = "spelled" }, dat_s = { "owi", stem = "spelled" }, gen_p = { "ów", stem = "spelled" }, ins_p = { "ami", stem = "spelled" }, ins_s = { "em", stem = "spelled" }, loc_p = { "ach", stem = "spelled" }, loc_s = { "e", stem = "spelled+palatal" }, nom_p = { "y", stem = "spelled" } },
["ł"] = { dat_p = "om", dat_s = "owi", gen_p = "ów", gen_s = "u", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "y" },
["Ś"] = { dat_p = "-om", dat_s = "-owi", gen_p = "-ów", gen_s = "-u", ins_p = "-ami", ins_s = "-em", loc_p = "-ach", loc_s = "-u", nom_p = "-e" },
},
},
["n common pl "] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "", dat_s = {}, depr_p = {}, gen_p = "", gen_s = {}, ins_p = "", ins_s = {}, loc_p = "", loc_s = {}, nom_s = {}, voc_s = {} },
},
},
["n common pl a"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["ci"] = { gen_p = { "", stem = "final_soft" } },
["ekt"] = { gen_p = "ów" },
["ik"] = { gen_p = "ów" },
["it"] = { gen_p = "ów" },
["k"] = { gen_p = { "", stem = "inserted_e" } },
["l"] = { gen_p = "i" },
["ni"] = { gen_p = { "", stem = "final_soft" } },
["nt"] = { gen_p = "ów" },
["t"] = { gen_p = { "", stem = "lengthened" } },
["ust"] = { gen_p = "" },
["zwi"] = { gen_p = "" },
["ł"] = { gen_p = { "", stem = "inserted_e" } },
},
},
["n common pl e"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "ym", dat_s = {}, depr_p = {}, gen_p = "ych", gen_s = {}, ins_p = "ymi", ins_s = {}, loc_p = "ych", loc_s = {}, nom_s = {}, voc_s = {} },
["ani"] = { gen_p = { "", { "", stem = "final_soft" } }, ins_p = { "ami", { "mi", stem = "final_soft" } } },
["bi"] = { gen_p = "" },
["c"] = { dat_p = "om", ins_p = "ami", loc_p = "ach" },
["gi"] = { dat_p = "m", gen_p = "ch", ins_p = "mi", loc_p = "ch" },
["i"] = { dat_p = "om", ins_p = "ami", loc_p = "ach" },
["ic"] = { gen_p = "" },
["iej"] = { gen_p = "ów" },
["j"] = { dat_p = "om", ins_p = "ami", loc_p = "ach" },
["jc"] = { gen_p = "ów" },
["ki"] = { dat_p = "m", gen_p = "ch", ins_p = "mi", loc_p = "ch" },
["l"] = { dat_p = "om", gen_p = "i", ins_p = "ami", loc_p = "ach" },
["ns"] = { dat_p = "om", gen_p = "ów", ins_p = "ami", loc_p = "ach" },
["pi"] = { gen_p = "" },
["rc"] = { gen_p = "ów" },
["sat"] = { dat_p = "e", gen_p = "e", ins_p = "e", loc_p = "e" },
["z"] = { dat_p = "om", gen_p = "y", ins_p = "ami", loc_p = "ach" },
["ąc"] = { dat_p = "ym", ins_p = "ymi", loc_p = "ych" },
["ńc"] = { gen_p = "ów" },
["ż"] = { dat_p = "om", gen_p = "y", ins_p = "ami", loc_p = "ach" },
},
},
["n common pl i"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["ajk"] = { gen_p = { "", stem = "inserted_e" } },
["c"] = { dat_p = "iom", gen_p = "i", ins_p = "iami", loc_p = "iach" },
["jtk"] = { gen_p = { "", stem = "inserted_e" } },
["l"] = { dat_p = "i", gen_p = "i", ins_p = "i", loc_p = "i" },
["n"] = { dat_p = { "om", stem = "palatal" }, gen_p = { "", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, loc_p = { "ach", stem = "palatal" } },
["nk"] = { gen_p = { "", stem = "inserted_e" } },
["rk"] = { gen_p = { "", stem = "inserted_e" } },
["unk"] = { gen_p = "ów" },
["w"] = { dat_p = { "om", stem = "palatal" }, gen_p = { "", stem = "palatal" }, ins_p = { "ami", stem = "palatal" }, loc_p = { "ach", stem = "palatal" } },
["wk"] = { gen_p = { "", stem = "inserted_e" } },
["łk"] = { gen_p = { "", stem = "inserted_e" } },
},
},
["n common pl y"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["m"] = { gen_p = "" },
["n"] = { gen_p = "" },
["om"] = { gen_p = "ów" },
["on"] = { gen_p = "ów" },
},
},
["n common sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["ema"] = { dat_p = "tom", gen_p = "tów", ins_p = "tami", loc_p = "tach", nom_p = "ta" },
["lon"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "y" } },
},
},
["n common sg e"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "om", dat_s = "u", depr_p = {}, gen_p = { "", stem = "final_soft" }, gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "a" },
["aci"] = { gen_p = "" },
["aj"] = { gen_p = "" },
["al"] = { dat_s = "e", gen_s = "e", ins_s = "e", loc_s = "e" },
["b"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["bi"] = { gen_p = "" },
["bil"] = { dat_p = "e", gen_p = "e", ins_p = "e", loc_p = "e", nom_p = "e" },
["d"] = { nom_p = "e" },
["dni"] = { gen_p = "" },
["e"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["eci"] = { gen_p = "" },
["eł"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e" },
["f"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["gi"] = { nom_p = "e" },
["il"] = { dat_s = "e", gen_s = "e", ins_s = "e", loc_s = "e" },
["jni"] = { gen_p = "" },
["k"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["ki"] = { nom_p = "e" },
["kni"] = { gen_p = "" },
["l"] = { gen_p = "i" },
["m"] = { nom_p = "e" },
["mi"] = { gen_p = "" },
["mil"] = { dat_p = "iom", gen_p = "iów", ins_p = "iami", loc_p = "iach", nom_p = "ia" },
["n"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "e" },
["nal"] = { dat_p = "e", gen_p = "e", ins_p = "e", loc_p = "e", nom_p = "e" },
["nci"] = { gen_p = "" },
["o"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["oci"] = { gen_p = "" },
["ogi"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e" },
["pi"] = { gen_p = "" },
["r"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["rc"] = { gen_p = "" },
["si"] = { gen_p = "" },
["ski"] = { dat_p = "m", dat_s = "emu", gen_p = "ch", gen_s = "ego", ins_p = "mi", ins_s = "m", loc_p = "ch", loc_s = "m" },
["st"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym" },
["t"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["tel"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["um"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e" },
["w"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", ins_s = "ym", loc_p = "ych", loc_s = "ym", nom_p = "e" },
["wal"] = { dat_s = "u", gen_s = "a", ins_s = "em", loc_s = "u" },
["wc"] = { gen_p = { "", "ów" } },
["wi"] = { gen_p = "" },
["woj"] = { dat_s = "emu", gen_s = "ego", nom_p = "e" },
["z"] = { gen_p = "y" },
["zc"] = { gen_p = { "", stem = "inserted_ie" } },
["zi"] = { gen_p = "" },
["é"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["ąci"] = { gen_p = "" },
["ł"] = { nom_p = "e" },
["śni"] = { gen_p = "" },
["ż"] = { gen_p = "y" },
["żci"] = { gen_p = "" },
},
},
["n common sg o"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "om", dat_s = "u", depr_p = {}, gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "a" },
["al"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["arn"] = { gen_p = { { "", stem = "inserted_e" }, "" } },
["ast"] = { loc_s = { "e", stem = "fronted+palatal" } },
["at"] = { dat_p = { "o", "om" }, dat_s = { "o", "u" }, gen_p = { "", "o" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { { "e", stem = "palatal" }, "o" }, nom_p = { "a", "o" } },
["atł"] = { loc_s = { "e", stem = "fronted+palatal" } },
["ał"] = { gen_p = "" },
["b"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["c"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["cer"] = { dat_p = { "o", "om" }, dat_s = { "o", "u" }, gen_p = { "o", "ów" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", { "e", stem = "palatal" } }, nom_p = { "a", "o" } },
["de"] = { dat_p = { "o", { "om", note = "rare" } }, dat_s = { "o", { "u", note = "rare" } }, gen_p = { "o", { "ów", note = "rare" } }, gen_s = { { "a", note = "rare" }, "o" }, ins_p = { { "ami", note = "rare" }, "o" }, ins_s = { { "em", note = "rare" }, "o" }, loc_p = { { "ach", note = "rare" }, "o" }, loc_s = { "o", { "u", note = "rare" } }, nom_p = { { "a", note = "rare" }, "o" } },
["dk"] = { gen_p = { "", stem = "inserted_e" } },
["dr"] = { gen_p = { "", stem = "inserted_e" } },
["ebr"] = { gen_p = { "", stem = "inserted_e" } },
["eg"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["eł"] = { gen_p = "" },
["f"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["fot"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["gn"] = { gen_p = { "", stem = "inserted_ie" } },
["gł"] = { gen_p = { "", stem = "inserted_ie" } },
["h"] = { loc_s = "u" },
["i"] = { gen_p = "ów", loc_s = "u" },
["int"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["jk"] = { gen_p = { "", stem = "inserted_e" } },
["k"] = { ins_s = "iem", loc_s = "u" },
["kid"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["kł"] = { gen_p = { "", stem = "inserted_ie" } },
["ll"] = { loc_s = "u" },
["mk"] = { gen_p = { "", stem = "inserted_e" } },
["ng"] = { ins_s = "iem", loc_s = "u" },
["nk"] = { gen_p = { "", stem = "inserted_e" } },
["o"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ol"] = { dat_p = { "o", "om" }, dat_s = { "o", "u" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", "u" }, nom_p = { "a", "o" } },
["ors"] = { dat_p = { "o", "om" }, dat_s = { "o", "u" }, gen_p = { "", "o" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { { "e", stem = "palatal" }, "o" }, nom_p = { "a", "o" } },
["oł"] = { gen_p = { "", stem = "lengthened" } },
["pk"] = { gen_p = { "", stem = "inserted_e" } },
["pn"] = { gen_p = { { "", stem = "inserted_ie" }, "" } },
["pol"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ps"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["re"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["red"] = { dat_p = { "o", "om" }, dat_s = { "o", "u" }, gen_p = { "", "o" }, gen_s = { "a", "o" }, ins_p = { "ami", "o" }, ins_s = { "em", "o" }, loc_p = { "ach", "o" }, loc_s = { "o", { "e", stem = "palatal" } }, nom_p = { "a", "o" } },
["rk"] = { gen_p = { "", stem = "inserted_e" } },
["rzm"] = { loc_s = "ie" },
["tk"] = { gen_p = { "", stem = "inserted_e" } },
["ukn"] = { gen_p = { "", stem = "inserted_ie" } },
["wk"] = { gen_p = { "", stem = "inserted_e" } },
["wn"] = { gen_p = { "", stem = "inserted_ie" } },
["zk"] = { gen_p = { "", stem = "inserted_e" } },
["ókn"] = { gen_p = { "", stem = "inserted_ie" } },
["ł"] = { gen_p = { "", stem = "inserted_e" } },
["łk"] = { gen_p = { "", stem = "inserted_e" } },
["łn"] = { gen_p = { "", stem = "inserted_e" } },
["łow"] = { gen_p = { "", stem = "lengthened" } },
},
},
["n common sg um"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", depr_p = {}, gen_p = "ów", gen_s = "um", ins_p = "ami", ins_s = "um", loc_p = "ach", nom_p = "a" },
},
},
["n common sg ę"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "ętom", dat_s = "ęciu", depr_p = {}, gen_p = "ąt", gen_s = "ęcia", ins_p = "ętami", ins_s = "ęciem", loc_p = "ętach", nom_p = "ęta" },
["mi"] = { dat_p = "onom", dat_s = "eniu", gen_p = "on", gen_s = "enia", ins_p = "onami", ins_s = "eniem", loc_p = "onach", nom_p = "ona" },
},
},
["n place pl a"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["ot"] = { gen_p = "" },
["t"] = { gen_p = { "", stem = "lengthened" } },
["yt"] = { gen_p = "" },
["ł"] = { gen_p = { "", stem = "inserted_e" } },
},
},
["n place pl e"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["aj"] = { gen_p = "ów" },
["alc"] = { gen_p = "ów" },
["ki"] = { dat_p = "m", gen_p = "ch", ins_p = "mi", loc_p = "ch" },
["l"] = { gen_p = "i" },
["n"] = { dat_p = "ym", gen_p = "ych", ins_p = "ymi", loc_p = "ych" },
["ni"] = { gen_p = { "", stem = "final_soft" } },
["oc"] = { gen_p = "ów" },
["oj"] = { gen_p = "ów" },
["pel"] = { gen_p = { "i", "ów" } },
["r"] = { dat_p = "ym", gen_p = "ych", ins_p = "ymi", loc_p = "ych" },
["rz"] = { gen_p = "y" },
["sel"] = { gen_p = "" },
["t"] = { dat_p = "ym", gen_p = "ych", ins_p = "ymi", loc_p = "ych" },
["tel"] = { gen_p = "" },
["ul"] = { gen_p = "" },
["upc"] = { gen_p = { "", stem = "inserted_ie" } },
["w"] = { dat_p = "ym", gen_p = "ych", ins_p = "ymi", loc_p = "ych" },
["wc"] = { gen_p = { "", stem = "inserted_ie" } },
["wel"] = { gen_p = "" },
["ł"] = { dat_p = "ym", gen_p = "ych", ins_p = "ymi", loc_p = "ych" },
},
},
["n place pl i"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = { "", stem = "inserted_e" }, gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["ag"] = { gen_p = "" },
["ak"] = { gen_p = "ów" },
["ek"] = { gen_p = "" },
["ik"] = { gen_p = "" },
["isk"] = { gen_p = "" },
["kok"] = { gen_p = "ów" },
["og"] = { gen_p = "ów" },
["ok"] = { gen_p = "" },
["org"] = { gen_p = "ów" },
["ośk"] = { gen_p = "ów" },
["ruk"] = { gen_p = "ów" },
["rąg"] = { gen_p = "ów" },
["sęk"] = { gen_p = "ów" },
["ug"] = { gen_p = "" },
["uk"] = { gen_p = "" },
["yg"] = { gen_p = "" },
["yk"] = { gen_p = "" },
["zeg"] = { gen_p = "ów" },
["zg"] = { gen_p = "" },
["ók"] = { gen_p = "" },
["ąg"] = { gen_p = "" },
["łak"] = { gen_p = "" },
},
},
["n place pl y"] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_s = {} },
["abł"] = { gen_p = "ów" },
["ach"] = { gen_p = "ów" },
["br"] = { gen_p = "ów" },
["ep"] = { gen_p = "ów" },
["gon"] = { gen_p = "ów" },
["gw"] = { gen_p = { "", stem = "inserted_ie" } },
["hab"] = { gen_p = "ów" },
["hł"] = { gen_p = { "", stem = "inserted_e" } },
["id"] = { gen_p = { "", "ów" } },
["kan"] = { gen_p = "ów" },
["ndr"] = { gen_p = "ów" },
["ord"] = { gen_p = "ów" },
["os"] = { gen_p = "ów" },
["ow"] = { gen_p = { "", stem = "lengthened" } },
["ozd"] = { gen_p = "ów" },
["rob"] = { gen_p = "ów" },
["rod"] = { gen_p = { "", stem = "lengthened" } },
["roz"] = { gen_p = "ów" },
["rąd"] = { gen_p = "ów" },
["sł"] = { gen_p = "ów" },
["tos"] = { gen_p = "" },
["tr"] = { gen_p = "ów" },
["um"] = { gen_p = "ów" },
["was"] = { gen_p = "ów" },
["wł"] = { gen_p = "ów" },
["zch"] = { gen_p = "ów" },
["zyb"] = { gen_p = "ów" },
["ąs"] = { gen_p = "ów" },
["ład"] = { gen_p = "ów" },
["łod"] = { gen_p = "ów" },
["łoz"] = { gen_p = { "", stem = "lengthened" } },
["łyn"] = { gen_p = "ów" },
},
},
["n place sg "] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "" },
["nd"] = { dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "y" } },
},
},
["n place sg e"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "om", dat_s = "u", depr_p = {}, gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "a" },
["b"] = { nom_p = "e" },
["ci"] = { gen_p = { "", stem = "final_soft" } },
["e"] = { dat_p = "e", dat_s = "e", gen_p = "e", gen_s = "e", ins_p = "e", ins_s = "e", loc_p = "e", loc_s = "e", nom_p = "e" },
["gi"] = { dat_p = "m", dat_s = "emu", gen_p = "ch", gen_s = "ego", ins_p = "mi", loc_p = "ch", loc_s = "em", nom_p = "e" },
["h"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["ki"] = { dat_p = "m", dat_s = "emu", gen_p = "ch", gen_s = "ego", ins_p = "mi", loc_p = "ch", loc_s = "em", nom_p = "e" },
["l"] = { gen_p = "i" },
["n"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["ni"] = { gen_p = { "", stem = "final_soft" } },
["oci"] = { gen_p = "" },
["oni"] = { gen_p = "" },
["p"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["r"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["s"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["t"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["w"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["z"] = { gen_p = "y" },
["ł"] = { dat_p = "ym", dat_s = "emu", gen_p = "ych", gen_s = "ego", ins_p = "ymi", loc_p = "ych", loc_s = "em", nom_p = "e" },
["ż"] = { gen_p = "y" },
},
},
["n place sg o"] = {
copies = { acc_p = "nom_p", acc_s = "nom_s", voc_p = "nom_p", voc_s = "nom_s" },
rules = {
[""] = { dat_p = "om", dat_s = "u", depr_p = {}, gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "a" },
["ad"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ag"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ajn"] = { gen_p = { "", stem = "inserted_e" } },
["amn"] = { gen_p = { { "", stem = "inserted_ie" }, "" } },
["arn"] = { gen_p = { { "", stem = "inserted_e" }, "" } },
["c"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ck"] = { gen_p = "" },
["e"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ew"] = { gen_p = "" },
["ewn"] = { gen_p = { "", stem = "inserted_ie" } },
["hn"] = { gen_p = { "", stem = "inserted_e" } },
["iw"] = { gen_p = "" },
["izn"] = { loc_s = "ie" },
["k"] = { gen_p = { "", stem = "inserted_e" }, ins_s = "iem", loc_s = "u" },
["kn"] = { gen_p = { "", stem = "inserted_ie" } },
["kł"] = { gen_p = { "", stem = "inserted_ie" } },
["l"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["ong"] = { ins_s = "iem", loc_s = "u" },
["osn"] = { gen_p = { "", stem = "inserted_ie" }, loc_s = { "e", stem = "palatal" } },
["oł"] = { gen_p = { "", stem = "lengthened" } },
["pn"] = { gen_p = { "", stem = "inserted_ie" } },
["sk"] = { gen_p = "" },
["sn"] = { loc_s = "ie" },
["st"] = { dat_p = "om", dat_s = "u", gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "fronted+palatal" }, nom_p = "a" },
["t"] = { dat_p = "o", dat_s = "o", gen_p = "o", gen_s = "o", ins_p = "o", ins_s = "o", loc_p = "o", loc_s = "o", nom_p = "o" },
["tw"] = { gen_p = "" },
["udn"] = { gen_p = { "", stem = "inserted_e" } },
["w"] = { gen_p = { "", "ów", { "", stem = "lengthened" } } },
["ówn"] = { gen_p = { "", stem = "inserted_ie" } },
["ł"] = { gen_p = { "", stem = "inserted_e" } },
["łot"] = { dat_p = "om", dat_s = "u", gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = { "e", stem = "palatal" }, nom_p = "a" },
},
},
["n place sg um"] = {
copies = { },
rules = {
[""] = { acc_p = { "a", "um" }, acc_s = "um", dat_p = { "om", "um" }, dat_s = "um", depr_p = {}, gen_p = "um", gen_s = "um", ins_p = { "ami", "um" }, ins_s = "um", loc_p = { "ach", "um" }, loc_s = "um", nom_p = { "a", "um" }, voc_p = { "a", "um" }, voc_s = "um" },
},
},
["n proper pl "] = {
copies = { acc_p = "nom_p", voc_p = "nom_p" },
rules = {
[""] = { acc_s = {}, dat_p = "", dat_s = {}, depr_p = {}, gen_p = "", gen_s = {}, ins_p = "", ins_s = {}, loc_p = "", loc_s = {}, nom_s = {}, voc_s = {} },
},
},
["n proper pl e"] = {
copies = { },
rules = {
[""] = { acc_p = "e", acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_p = "e", voc_s = {} },
},
},
["n proper pl y"] = {
copies = { },
rules = {
[""] = { acc_p = "y", acc_s = {}, dat_p = "om", dat_s = {}, depr_p = {}, gen_p = "ów", gen_s = {}, ins_p = "ami", ins_s = {}, loc_p = "ach", loc_s = {}, nom_s = {}, voc_p = "y", voc_s = {} },
},
},
["n proper sg "] = {
copies = { acc_s = "nom_s" },
rules = {
[""] = { acc_p = "", dat_p = "", dat_s = "", depr_p = {}, gen_p = "", gen_s = "", ins_p = "", ins_s = "", loc_p = "", loc_s = "", nom_p = "", voc_p = "", voc_s = "" },
["BS"] = { acc_p = { "", "-y" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_p = { "", "-y" }, voc_s = { "", "-ie" } },
["F"] = { acc_p = { "", "-y" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_p = { "", "-y" }, voc_s = { "", "-ie" } },
["J"] = { acc_p = { "", "-oty" }, dat_p = { "", "-otom" }, dat_s = { "", "-otowi" }, gen_p = { "", "-otów" }, gen_s = { "", "-otu" }, ins_p = { "", "-otami" }, ins_s = { "", "-otem" }, loc_p = { "", "-otach" }, loc_s = { "", "-ocie" }, nom_p = { "", "-oty" }, voc_p = { "", "-oty" }, voc_s = { "", "-ocie" } },
["L"] = { acc_p = { "", "-e" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-i" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-u" }, nom_p = { "", "-e" }, voc_p = { "", "-e" }, voc_s = { "", "-u" } },
["N"] = { acc_p = { "", "-y" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_p = { "", "-y" }, voc_s = { "", "-ie" } },
["OS"] = { acc_p = { "", "-y" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ie" }, nom_p = { "", "-y" }, voc_p = { "", "-y" }, voc_s = { "", "-ie" } },
["R"] = { acc_p = { "", "-y" }, dat_p = { "", "-om" }, dat_s = { "", "-owi" }, gen_p = { "", "-ów" }, gen_s = { "", "-u" }, ins_p = { "", "-ami" }, ins_s = { "", "-em" }, loc_p = { "", "-ach" }, loc_s = { "", "-ze" }, nom_p = { "", "-y" }, voc_p = { "", "-y" }, voc_s = { "", "-ze" } },
["k"] = { acc_p = {}, dat_p = {}, gen_p = {}, ins_p = {}, loc_p = {}, nom_p = {}, voc_p = {}, voc_s = {} },
["m"] = { acc_p = { "", "y" }, dat_p = { "", "om" }, dat_s = { "", "owi" }, gen_p = { "", "ów" }, gen_s = { "", "u" }, ins_p = { "", "ami" }, ins_s = { "", "em" }, loc_p = { "", "ach" }, loc_s = { "", { "e", stem = "palatal" } }, nom_p = { "", "y" }, voc_p = { "", "y" }, voc_s = { "", { "e", stem = "palatal" } } },
["ś"] = { acc_p = {}, dat_p = {}, gen_p = {}, ins_p = {}, loc_p = {}, nom_p = {}, voc_p = {}, voc_s = {} },
},
},
["n proper sg e"] = {
copies = { acc_s = "nom_s" },
rules = {
[""] = { acc_p = "a", dat_p = "om", dat_s = "u", depr_p = {}, gen_p = "", gen_s = "a", ins_p = "ami", ins_s = "em", loc_p = "ach", loc_s = "u", nom_p = "a", voc_p = "a", voc_s = "e" },
},
},
["n proper sg o"] = {
copies = { acc_s = "nom_s" },
rules = {
[""] = { acc_p = {}, dat_p = {}, dat_s = "emu", depr_p = {}, gen_p = {}, gen_s = "ego", ins_p = {}, ins_s = "ym", loc_p = {}, loc_s = "ym", nom_p = {}, voc_p = {}, voc_s = {} },
},
},
["n proper sg um"] = {
copies = { acc_p = "nom_p", acc_s = "gen_s", dat_s = "gen_s", loc_s = "dat_s", voc_p = "nom_p", voc_s = "loc_s" },
rules = {
[""] = { dat_p = "om", depr_p = {}, gen_p = "ów", gen_s = "um", ins_p = "ami", ins_s = "um", loc_p = "ach", nom_p = "a" },
},
},
}
------------------------------------------------------------------------------------------------------------------------
-- Adjective rules --
------------------------------------------------------------------------------------------------------------------------
-- The slots of an adjective in table order: the singular by gender column (the masculine animate and inanimate share
-- most of them), then the virile and non-virile plural.
data.adjective_slots = {
"nom_m", "nom_f", "nom_n", "nom_mp_pers", "nom_p_not_mp_pers",
"gen_mn", "gen_f", "gen_p",
"dat_mn", "dat_f", "dat_p",
"acc_m_an", "acc_m_in", "acc_f", "acc_n", "acc_mp_pers", "acc_p_not_mp_pers",
"ins_mn", "ins_f", "ins_p",
"loc_mn", "loc_f", "loc_p",
"short",
}
-- The nominative endings of an adjective's lemma (its masculine singular), which pick its group in `adjective_groups`.
data.adjective_nominatives = { "y", "i" }
-- The kind of an adjective, for its title and category, given by the first pattern its lemma matches.
data.adjective_kinds = { { "y$", "hard" }, { "[kg]i$", "velar" }, { "", "soft" } }
-- How to find the masculine of an adjectival word given in another gender (''teściowa'' → ''teściowy'', ''tania'' →
-- ''tani'', ''wielkie'' → ''wielki'', and likewise a non-virile plural such as ''Zjednoczone''). Take the first ending
-- of its rule gender (`plural` for a plural) that it has, and replace it with the soft masculine ending if the ending
-- is `soft` or the stem ends in a letter of `soft_after`, and with the hard one otherwise.
data.adjective_lemma = {
endings = {
f = { { "ia", soft = true }, { "a" } },
n = { { "ie", soft = true }, { "e" } },
plural = { { "ie", soft = true }, { "e" } },
},
soft = "i",
hard = "y",
soft_after = { k = true, g = true },
}
-- The endings that follow the softened consonant of a virile nominative plural (''krew|ni'', ''pols|c|y''), used to
-- find the masculine of a virile adjectival word.
data.virile_endings = { "", "y" }
-- The noun slot that each adjective slot of an adjectival word fills, by the rule gender of the noun. `plural` is the
-- plural of every rule gender except `m-pr`, whose plural is in its own entry. The vocative is the nominative.
data.adjectival_slots = {
["m-pr"] = {
nom_s = "nom_m", gen_s = "gen_mn", dat_s = "dat_mn", acc_s = "acc_m_an", ins_s = "ins_mn", loc_s = "loc_mn",
voc_s = "nom_m", nom_p = "nom_mp_pers", acc_p = "acc_mp_pers", voc_p = "nom_mp_pers",
gen_p = "gen_p", dat_p = "dat_p", ins_p = "ins_p", loc_p = "loc_p",
},
["m-anml"] = {
nom_s = "nom_m", gen_s = "gen_mn", dat_s = "dat_mn", acc_s = "acc_m_an", ins_s = "ins_mn", loc_s = "loc_mn",
voc_s = "nom_m",
},
["m-in"] = {
nom_s = "nom_m", gen_s = "gen_mn", dat_s = "dat_mn", acc_s = "acc_m_in", ins_s = "ins_mn", loc_s = "loc_mn",
voc_s = "nom_m",
},
f = {
nom_s = "nom_f", gen_s = "gen_f", dat_s = "dat_f", acc_s = "acc_f", ins_s = "ins_f", loc_s = "loc_f",
voc_s = "nom_f",
},
n = {
nom_s = "nom_n", gen_s = "gen_mn", dat_s = "dat_mn", acc_s = "acc_n", ins_s = "ins_mn", loc_s = "loc_mn",
voc_s = "nom_n",
},
plural = {
nom_p = "nom_p_not_mp_pers", gen_p = "gen_p", dat_p = "dat_p", acc_p = "acc_p_not_mp_pers",
ins_p = "ins_p", loc_p = "loc_p", voc_p = "nom_p_not_mp_pers",
},
}
-- The adjective slots that always have the forms of another slot, by source slot: the dative, instrumental and
-- locative feminine singular come from the genitive and accusative, the locative masculine singular from the
-- instrumental, and the locative plural from the genitive.
data.adjective_shared = {
gen_f = { "dat_f", "loc_f" }, acc_f = { "ins_f" }, ins_mn = { "loc_mn" }, gen_p = { "loc_p" },
}
-- The accusatives an adjective takes from other slots, as pairs of source and accusative.
data.adjective_accusatives = {
{ "nom_n", "acc_n" }, { "gen_mn", "acc_m_an" }, { "nom_m", "acc_m_in" }, { "gen_p", "acc_mp_pers" },
{ "nom_p_not_mp_pers", "acc_p_not_mp_pers" }, { "nom_mp_npers", "acc_mp_npers" }, { "nom_fp", "acc_fp" },
{ "nom_np", "acc_np" },
}
-- The last letter of an adjective stem that drops before an ending starting with the given letter (e.g. ''moj-'' +
-- ''-ich'' → ''moich'').
data.adjective_dropped = { j = "i" }
-- The archaic dative added by `archdat` (''polsku''): its ending, added to the adjective's stem, and its footnote (a
-- key of `notes`).
data.archaic_dative = { "u", note = "archaic" }
--[==[
The irregular adjectives of `<irreg>`, tried on the lemma in order.
`pattern` captures the stem (or `stem` gives it), and each of the `sets` adds forms to the stem (plus `add`), with an
optional footnote.
A set's `endings` give the slots in which a regular adjective has its own forms; the other slots are shared as for
every adjective (the dative, instrumental and locative feminine singular are the genitive, accusative and genitive; the
locative masculine singular is the instrumental; and the locative plural is the genitive). `-` as an ending means the
lemma itself. A set's `own` endings fill a slot without that sharing. `table` names a table with slots of its own
(`dwa` for the plural of ''dwa'' and ''oba'', and `plonly` for the plural only).
]==]
local function normal(nom_f, nom_n, nom_mp_pers, nom_p_not_mp_pers, gen_mn, gen_f, gen_p, dat_mn, dat_p, acc_f, ins_mn,
ins_p)
return {
nom_f = nom_f, nom_n = nom_n, nom_mp_pers = nom_mp_pers, nom_p_not_mp_pers = nom_p_not_mp_pers,
gen_mn = gen_mn, gen_f = gen_f, gen_p = gen_p, dat_mn = dat_mn, dat_p = dat_p, acc_f = acc_f, ins_mn = ins_mn,
ins_p = ins_p,
}
end
local DWA = {
table = "dwa",
sets = { {
own = {
nom_mp_pers = "aj", nom_mp_npers = "a", nom_fp = "ie", nom_np = "a", gen_p = { "u", "óch" },
dat_p = { "u", "om", "óm" }, ins_mnp = { "oma", "u" }, ins_fp = { "iema", "oma", "u" }, loc_p = { "u", "óch" },
},
} },
}
data.irregular_adjectives = {
{ pattern = "^(dw)a$", table = DWA.table, sets = DWA.sets },
{ pattern = "^(ob)a$", table = DWA.table, sets = DWA.sets },
{ pattern = "^(.*[st]w)ój$", sets = {
{ add = "oj", endings = normal("a", "e", "i", "e", "ego", "ej", "ich", "emu", "im", "ą", "im", "imi") },
{ endings = normal("a", "e", nil, "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi"),
note = "literary or archaic" },
} },
{ pattern = "^(.*m)ój$", sets = {
{ add = "oj", endings = normal("a", "e", "i", "e", "ego", "ej", "ich", "emu", "im", "ą", "im", "imi") },
{ endings = normal("a", "e", nil, "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi"),
note = "literary or archaic" },
} },
{ pattern = "^(.*)ten$", sets = {
{ endings = normal("ta", "to", "ci", "te", "tego", "tej", "tych", "temu", "tym", nil, "tym", "tymi") },
{ own = { acc_f = "tę" } },
{ own = { acc_f = "tą" }, note = "proscribed but much more common" },
{ own = { ins_f = "tą" } },
} },
-- ''tenże'' declines like ''ten'', with ''-ż'' after a vowel and ''-że'' after a consonant.
{ pattern = "^(.*)tenże$", sets = {
{ endings = normal("taż", "toż", "ciż", "też", "tegoż", "tejże", "tychże", "temuż", "tymże", nil, "tymże", "tymiż") },
{ own = { acc_f = { "tęż", "tęże", "tąż", "tąże" }, ins_f = { "tąż", "tąże" } } },
} },
{ pattern = "^(.*czyj)$", sets = {
{ endings = normal("a", "e", "i", "e", "ego", "ej", "ich", "emu", "im", "ą", "im", "imi") },
} },
{ pattern = "^(.*sam)$", sets = {
{ endings = normal("a", "o", "i", "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi") },
} },
{ pattern = "^(.*jed)en$", sets = {
{ add = "n", endings = normal("a", "o", "i", "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi") },
} },
{ pattern = "^(on)$", sets = {
{ endings = normal("a", "o", "i", "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi") },
} },
{ pattern = "^ów$", stem = "ow", sets = {
{ endings = normal("a", "o", "i", "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi") },
} },
{ pattern = "^owy$", stem = "ow", sets = {
{ endings = normal("a", "o", "i", "e", "ego", "ej", "ych", "emu", "ym", "ą", "ym", "ymi") },
} },
{ pattern = "^(.*il)e$", table = "plonly", sets = {
{ endings = normal(nil, nil, "u", "e", nil, nil, "u", nil, "u", nil, nil, "u") },
{ own = { ins_p = "oma" }, note = "rare" },
} },
{ pattern = "^(.*wszys)tek$", sets = {
{ add = "tk", endings = normal("a", "o", nil, "ie", "iego", "iej", "ich", "iemu", "im", "ą", "im", "imi"),
archaic_dative = "u" },
{ add = "c", own = { nom_mp_pers = "y" } },
} },
}
--[==[
The adjective groups, keyed `adj common sg NOMINATIVE` (the lemma's ending, `y` or `i`) like the noun groups.
]==]
data.adjective_groups = {
["adj common sg "] = {
copies = { acc_m_an = "gen_mn", acc_m_in = "nom_m", acc_mp_pers = "gen_p", acc_n = "nom_n", acc_p_not_mp_pers = "nom_p_not_mp_pers", dat_f = "gen_f", dat_p = "ins_mn", loc_f = "gen_f", loc_mn = "ins_mn", loc_p = "gen_p" },
rules = {
[""] = { acc_f = "ą", dat_mn = "emu", gen_f = "ej", gen_mn = "ego", gen_p = "ych", ins_f = "ą", ins_mn = "ym", ins_p = "ymi", nom_f = "a", nom_mp_pers = "", nom_n = "e", nom_p_not_mp_pers = "e" },
["."] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["a"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["ad"] = { acc_f = {}, dat_mn = {}, gen_f = {}, gen_mn = {}, gen_p = {}, ins_f = {}, ins_mn = {}, ins_p = {}, nom_mp_pers = { "", stem = "palatal" } },
["asz"] = { nom_mp_pers = { "i", stem = "virile" } },
["e"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["en"] = { acc_f = { "ą", stem = "reduced" }, dat_mn = { "emu", stem = "reduced" }, gen_f = { "ej", stem = "reduced" }, gen_mn = { "ego", stem = "reduced" }, gen_p = { "ych", stem = "reduced" }, ins_f = { "ą", stem = "reduced" }, ins_mn = { "ym", stem = "reduced" }, ins_p = { "ymi", stem = "reduced" }, nom_f = { "a", stem = "reduced" }, nom_mp_pers = { "", stem = "reduced+palatal" }, nom_n = { "e", stem = "reduced" }, nom_p_not_mp_pers = { "e", stem = "reduced" } },
["ent"] = { acc_f = {}, dat_mn = {}, gen_f = {}, gen_mn = {}, gen_p = {}, ins_f = {}, ins_mn = {}, ins_p = {} },
["l"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["n"] = { nom_mp_pers = { "", stem = "palatal" } },
["nd"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["o"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["om"] = { nom_mp_pers = { "", stem = "palatal" } },
["on"] = { nom_mp_pers = { "", stem = "fronted+palatal" } },
["r"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["ron"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_mp_pers = "", nom_n = "", nom_p_not_mp_pers = "" },
["s"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
["t"] = { nom_mp_pers = { "", stem = "palatal" } },
["w"] = { nom_mp_pers = { "", stem = "palatal" } },
["é"] = { acc_f = "", dat_mn = "", gen_f = "", gen_mn = "", gen_p = "", ins_f = "", ins_mn = "", ins_p = "", nom_f = "", nom_n = "", nom_p_not_mp_pers = "" },
},
},
["adj common sg i"] = {
copies = { acc_m_an = "gen_mn", acc_m_in = "nom_m", acc_mp_pers = "gen_p", acc_n = "nom_n", acc_p_not_mp_pers = "nom_p_not_mp_pers", dat_f = "gen_f", dat_p = "ins_mn", ins_f = "acc_f", loc_f = "gen_f", loc_mn = "ins_mn", loc_p = "gen_p" },
rules = {
[""] = { acc_f = "ą", dat_mn = "iemu", gen_f = "iej", gen_mn = "iego", gen_p = "ich", ins_mn = "im", ins_p = "imi", nom_f = "a", nom_mp_pers = { "y", stem = "palatal" }, nom_n = "ie", nom_p_not_mp_pers = "ie" },
["b"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["c"] = { acc_f = "ią", nom_f = "ia", nom_mp_pers = "i" },
["f"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["i"] = { acc_f = "ją", dat_mn = "jemu", gen_f = "jej", gen_mn = "jego", nom_f = "ja", nom_mp_pers = "i", nom_n = "je", nom_p_not_mp_pers = "je" },
["ks"] = { acc_f = { "", stem = "palatal" }, dat_mn = { "", stem = "palatal" }, gen_f = { "", stem = "palatal" }, gen_mn = { "", stem = "palatal" }, gen_p = { "", stem = "palatal" }, ins_mn = { "", stem = "palatal" }, ins_p = { "", stem = "palatal" }, nom_f = { "", stem = "palatal" }, nom_n = { "", stem = "palatal" }, nom_p_not_mp_pers = { "", stem = "palatal" } },
["l"] = { dat_mn = "emu", gen_f = "ej", gen_mn = "ego", nom_mp_pers = "i", nom_n = "e", nom_p_not_mp_pers = "e" },
["m"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["n"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["p"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["s"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["u"] = { acc_f = "ją", dat_mn = "jemu", gen_f = "jej", gen_mn = "jego", nom_f = "ja", nom_mp_pers = "i", nom_n = "je", nom_p_not_mp_pers = "je" },
["w"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
["y"] = { acc_f = "ją", dat_mn = "jemu", gen_f = "jej", gen_mn = "jego", nom_f = "ja", nom_mp_pers = "i", nom_n = "je", nom_p_not_mp_pers = "je" },
["z"] = { acc_f = { "ą", stem = "palatal" }, dat_mn = { "emu", stem = "palatal" }, gen_f = { "ej", stem = "palatal" }, gen_mn = { "ego", stem = "palatal" }, gen_p = { "ch", stem = "palatal" }, ins_mn = { "m", stem = "palatal" }, ins_p = { "mi", stem = "palatal" }, nom_f = { "a", stem = "palatal" }, nom_mp_pers = { "", stem = "palatal" }, nom_n = { "e", stem = "palatal" }, nom_p_not_mp_pers = { "e", stem = "palatal" } },
},
},
["adj common sg y"] = {
copies = { acc_m_an = "gen_mn", acc_m_in = "nom_m", acc_mp_pers = "gen_p", acc_n = "nom_n", acc_p_not_mp_pers = "nom_p_not_mp_pers", dat_f = "gen_f", dat_p = "ins_mn", ins_f = "acc_f", loc_f = "gen_f", loc_mn = "ins_mn", loc_p = "gen_p" },
rules = {
[""] = { acc_f = "ą", dat_mn = "emu", gen_f = "ej", gen_mn = "ego", gen_p = "ych", ins_mn = "ym", ins_p = "ymi", nom_f = "a", nom_mp_pers = { "", stem = "palatal" }, nom_n = "e", nom_p_not_mp_pers = "e" },
["c"] = { nom_mp_pers = "y" },
["dzn"] = { nom_mp_pers = "i" },
["h"] = { nom_mp_pers = { "i", stem = "virile" } },
["on"] = { nom_mp_pers = { "", stem = "fronted+palatal" } },
["r"] = { nom_mp_pers = { "y", stem = "palatal" } },
["ron"] = { nom_mp_pers = { "", stem = "palatal" } },
["soł"] = { nom_mp_pers = { "i", stem = "fronted+palatal" } },
["sz"] = { nom_mp_pers = { "i", stem = "virile" } },
["won"] = { nom_mp_pers = { "", stem = "palatal" } },
["z"] = { nom_mp_pers = "y" },
["ł"] = { nom_mp_pers = { "i", stem = "palatal" } },
["łon"] = { nom_mp_pers = { "", stem = "palatal" } },
["łzł"] = { nom_mp_pers = { { "i", stem = "virile" }, { "i", stem = "palatal" } } },
["ż"] = { nom_mp_pers = "y" },
},
},
}
return data
h6wem0xkkfdl6803nlsscfhfpkoiwxa
ð
0
421165
2573004
2026-10-23T13:39:25Z
Lcsnes
40261
Trang mới: “{{also|Ð|Đ}} {{minitoc}} {{-Latn-}} {{character info}} ==={{ĐM|desction}}=== {{mul-letter}} #[[chữ cái|Chữ cái]] '''[[eth]] viết thường'''. ==={{ĐM|see}}=== {{Latn-script}} =={{langname|mul}}== {{wikipedia|lang=vi|eth}} ==={{ĐM|pron}}=== *{{audio|mul|Voiced_dental_fricative.ogg|IPA=[ðɑː ɑˈðɑː]}} ==={{ĐM|symbol}}=== {{mul-symbol}} #{{lb|mul|IPA}} [[phụ âm|Phụ âm]] [[tắc]] [[quặt]] [[lưỡi]] [[hữu]] [[thanh]] #{{label|mul|viết trê…”
2573004
wikitext
text/x-wiki
{{also|Ð|Đ}}
{{minitoc}}
{{-Latn-}}
{{character info}}
==={{ĐM|desction}}===
{{mul-letter}}
#[[chữ cái|Chữ cái]] '''[[eth]] viết thường'''.
==={{ĐM|see}}===
{{Latn-script}}
=={{langname|mul}}==
{{wikipedia|lang=vi|eth}}
==={{ĐM|pron}}===
*{{audio|mul|Voiced_dental_fricative.ogg|IPA=[ðɑː ɑˈðɑː]}}
==={{ĐM|symbol}}===
{{mul-symbol}}
#{{lb|mul|IPA}} [[phụ âm|Phụ âm]] [[tắc]] [[quặt]] [[lưỡi]] [[hữu]] [[thanh]]
#{{label|mul|viết trên ⟨ᶞ⟩|IPA}} {{IPAfont|[ð]}}-âm xát của phụ âm tắc (ví dụ {{IPAfont|[dᶞ]}}); [dᶞ]{{IPAfont|[ð]}} thêm âm sắc hoặc nhẹ, thoáng qua hay vang.
#{{lb|mul|UPA}} Âm vỗ lợi (IPA {{IPAfont|[[ɾ]]}}).
===={{ĐM|der}}====
*⟨[[ð̞]]⟩ (cụ thể như âm tiếp cận)
=={{langname|awg}}==
==={{ĐM|pron}}===
*{{IPA|awg|/ð/}}
==={{ĐM|letter}}===
{{letter|awg}}
#Chữ cái IPA biểu thị phụ âm '''{{IPAchar|/ð/}}''' trong tiếng Anguthimri
#:{{ux|awg|'''ð'''u|[[khâu]]|inline=1}}
=={{langname|en}}==
==={{ĐM|pron}}===
* {{enPR|''th''}}
* {{IPA|en|/ð/|a=RP,GenAm,CanE,AuE,NZE,ScE}}
* {{IPA|en|/d̪/|a=Nam Á}}
==={{ĐM|letter}}===
{{letter|en}}
#{{ng|Thay thế ''th'' trong một số kiểu viết cổ.}}
=={{langname|ang}}==
==={{ĐM|pron}}===
*{{ang-IPA|ð}}
==={{ĐM|letter}}===
{{letter|ang}}
#Chữ [[eth]] viết thường trong bảng chữ cái Anh cổ biểu thị phụ âm {{IPAchar|/θ/}}, thường được phát âm {{IPAchar|[θ]}} hay {{IPAchar|[ð]}}
#:{{ux|ang|{{l|ang|for'''ð'''an}}|[[vì]]|inline=1}}
===={{ĐM|syn}}====
*{{l|ang|Þ}}, {{l|ang|þ}}
=={{langname|enm}}==
==={{ĐM|pron}}===
*{{IPA|enm|/θ/|/ð/}}
==={{ĐM|letter}}===
{{letter|enm}}
#Chữ cái thứ 6 viết thường trong bảng chữ cái Latinh tiếng Anh trung đại; dần được thay thế bằng "th".
==={{ĐM|see}}===
*{{letters|lang=enm|sc=Latn|qual=Bảng chữ cái Latinh tiếng Anh trung đại|Aa|Ææ|Bb|Cc|Dd|Ðð|Ee|Ff|Gg|Ȝȝ|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Qq|Rr|Ss|Tt|Þþ|Uu|Vv|Ww|Xx|Yy|Zz}}
=={{langname|non}}==
==={{ĐM|pron}}===
*{{IPA|non|/θ/|/ð/}}
==={{ĐM|letter}}===
{{letter|non}}
#Chữ cái thứ 6 viết thường trong bảng chữ cái Latinh tiếng Bắc Âu cổ.
#:{{ux|non|{{l|non|hǫf'''ð'''ager'''ð'''}}|[[tấm]] [[ván]] [[đầu]] [[giường]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=non|sc=Latn|qual=Bảng chữ cái Latinh tiếng Bắc Âu cổ|Aa|Áá|Bb|Cc|Dd|Ðð|Ee|Éé|Ff|Gg|(Gj/gj)|Hh|(Hl/hl)|(Hn/hn)|(Hr/hr)|(Hv/hv)|Ii|Íí|Jj|Kk|(Kj/kj)|Ll|Mm|Nn|(Ng/ng)|Oo|Óó|Pp|Qq|Rr|Ss|Tt|Uu|Úú|Vv|Ww|Xx|Yy|Ýý|Þþ|Ææ|Ǽǽ|Œœ|Øø|Ǫǫ}}
=={{langname|fo}}==
{{wp|lang=fo}}
==={{ĐM|pron}}===
*{{IPA|fo|/ð/}}
==={{ĐM|letter}}===
{{letter|fo}}
#Chữ cái thứ 5 viết thường trong bảng chữ cái Latinh tiếng Faroe.
#:{{ux|fo|{{l|fo|forbjó'''ð'''a}}|[[cấm]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=fo|sc=Latn|qual=Bảng chữ cái tiếng Faroe}}
=={{langname|is}}==
{{wp|lang=is}}
==={{ĐM|pron}}===
*{{is-IPA|ˈeð}} (''tên chữ cái'')
==={{ĐM|letter}}===
{{letter|is}}
#Chữ cái thứ 5 viết thường trong bảng chữ cái Latinh tiếng Iceland.
#:{{ux|is|{{l|is|au'''ð'''mýkja}}|[[sỉ nhục]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=is|sc=Latn|qual=Bảng chữ cái tiếng Iceland}}
=={{langname|myb}}==
==={{ĐM|pron}}===
*{{IPA|myb|/ð/}}
==={{ĐM|letter}}===
{{letter|myb}}
#Chữ cái Latinh viết thường trong bảng chữ cái tiếng Mbay năm 1980.
#:{{quote|myb|Kun kï'''ð'''en kï døningt, yel kï'''ð'''en kïdõ, nya kï'''ð'''en kï a ød ron, în kò kumkajir i kamat, m'ad a mu kï mbuj kï'''ð'''en nyasat. Na nya'n non '''ð'''a nya titbe.|Còn các loài thú ngoài đồng, các loài chim trên trời, và các động-vật khác trên mặt đất, phàm giống nào có sự sống thì ta ban cho mọi thứ cỏ xanh đặng dùng làm đồ-ăn; thì có như vậy. ([[s:Sáng thế Ký/1#1:30|Sáng thế Ký 1:30]])}}
==={{ĐM|ref}}===
*{{Chú thích web|myb|work=BIBLE MBAÏ|author=Alliance Biblique du Tchad|year=1980|entryurl=https://www.bible.com/bible/444/GEN.1.MB80|entry=Yaþ 1}}
=={{langname|osa}}==
==={{ĐM|pron}}===
*{{IPA4|osa|/ð/}}
==={{ĐM|letter}}===
{{letter|osa}}
#Chữ cái thứ 10 viết thường trong bảng chữ cái Latinh tiếng Osage.
#:{{ux|osa|'''ð'''óxe|[[bò]] [[rừng]] [[bison]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=osa|sc=Latn|qual=Bảng chữ cái Latinh tiếng Osage|Aa|Ąą|Bb|Cc|Ch/ch|Hc/hc|C’/c’|Čč|Hč/hč|Ðð|Ee|Ɣɣ|(Gh/gh)|Hh|Ii|Įį|Kk|Kh/kh|Hk/hk|K’/k’|Mm|Nn|Oo|Ǫǫ|Pp|Ph/ph|Hp/hp|P’/p’|Rr|Ss|Šš|Tt|Th/th|Ht/ht|T’/t’|Uu|Ww|Xx|Zz|Žž|ʔ}}
=={{langname|ovd}}==
==={{ĐM|pron}}===
*{{IPA|ovd|[ð]}}
==={{ĐM|letter}}===
{{letter|ovd}}
#Chữ cái thứ 5 viết thường trong bảng chữ cái Latinh tiếng Övdal.
#:{{ux|ovd|e'''ð'''|[[nó]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=ovd|sc=Latn|qual=Bảng chữ cái Latinh tiếng Övdal|Aa|Ąą|Bb|Dd|Ðð|Ee|Ęę|Ff|Gg|Hh|Ii|Įį|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Rr|Ss|Tt|Uu|Ųų|Vv|Ww|Yy|Y̨/y̨|Åå|Ą̊/ą̊|Ää|Öö}}
==={{ĐM|ref}}===
*{{Chú thích sách|sv|publisher=Alvdalen|title=[https://web.archive.org/web/20170113233252/http://alvdalen.se/upload/Dokument/kultur_fritid/%c3%84lvdalskan/alvdalsk_ortografi.pdf Förslag till en enhetlig stavning för älvdalska]|date=2005-03-16}}
=={{langname|osx}}==
==={{ĐM|alt}}===
*{{l|osx|th}}
==={{ĐM|pron}}===
*{{IPA|osx|[ð]}}
==={{ĐM|letter}}===
{{letter|osx}}
#Chữ cái thứ 25 (cuối cùng) viết thường trong bảng chữ cái Latinh tiếng Saxon cổ.
#:{{ux|osx|'''ð'''werh|tr='''th'''werh|[[trái ngược]]|inline=1}}
==={{ĐM|see}}===
*{{letters|lang=osx|sc=Latn|qual=Bảng chữ cái Latinh tiếng Saxon cổ|Aa|Bb|Cc|Dd|Ee|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Qq|Rr|Ss|Tt|Uu|Vv|Ww|Ƀƀ|Ðð}}
[[Thể loại:Khối ký tự Latin-1 Supplement|F0]]
qhq46ylpbfajrlz7o7hqsmwafy6prh6
boŋo
0
421166
2573005
2026-10-23T13:39:52Z
TheHighFighter2
42988
/* */
2573005
wikitext
text/x-wiki
=={{langname|dgi}}==
==={{ĐM|pron}}===
* {{IPA|dgi|/bòŋó/}}
==={{ĐM|noun}}===
{{head|dgi|noun|số nhiều|bonni}}
# Con [[lừa]].
==={{ĐM|ref}}===
* Ali, Gri & Bodomo: A dictionary and grammatical sketch of Dagaare (2021). [https://refubium.fu-berlin.de/bitstream/handle/fub188/30413/A_dictionary_and_grammatical_sketch_of_Dagaare.pdf?sequence=1&isAllowed=y]
4ewkvsix127ix8fdtz9ds1kyzcbcpzf
2573007
2573005
2026-10-23T14:49:47Z
TheHighFighter2
42988
/* Tiếng Acholi */
2573007
wikitext
text/x-wiki
=={{langname|ach}}==
==={{ĐM|noun}}===
{{head|ach|noun}}
# [[vải|Vải]], [[vải vóc]].
# [[quần áo|Quần áo]], [[trang phục]].
===References===
* {{R:ach:Blackings|17}}
=={{langname|dgi}}==
==={{ĐM|pron}}===
* {{IPA|dgi|/bòŋó/}}
==={{ĐM|noun}}===
{{head|dgi|noun|số nhiều|bonni}}
# Con [[lừa]].
==={{ĐM|ref}}===
* Ali, Gri & Bodomo: A dictionary and grammatical sketch of Dagaare (2021). [https://refubium.fu-berlin.de/bitstream/handle/fub188/30413/A_dictionary_and_grammatical_sketch_of_Dagaare.pdf?sequence=1&isAllowed=y]
i97srkajp09fov9huogiz3cd9sb9i30
2573008
2573007
2026-10-23T14:50:15Z
TheHighFighter2
42988
2573008
wikitext
text/x-wiki
=={{langname|ach}}==
==={{ĐM|noun}}===
{{head|ach|noun}}
# [[vải|Vải]], [[vải vóc]].
# [[quần áo|Quần áo]], [[trang phục]].
==={{ĐM|ref}}===
* {{R:ach:Blackings|17}}
=={{langname|dgi}}==
==={{ĐM|pron}}===
* {{IPA|dgi|/bòŋó/}}
==={{ĐM|noun}}===
{{head|dgi|noun|số nhiều|bonni}}
# Con [[lừa]].
==={{ĐM|ref}}===
* Ali, Gri & Bodomo: A dictionary and grammatical sketch of Dagaare (2021). [https://refubium.fu-berlin.de/bitstream/handle/fub188/30413/A_dictionary_and_grammatical_sketch_of_Dagaare.pdf?sequence=1&isAllowed=y]
5q3fg7iv7cvxc9pk16050lmit3t5uh6
2573011
2573008
2026-10-23T14:53:36Z
TheHighFighter2
42988
2573011
wikitext
text/x-wiki
{{also|Phụ lục:Biến thể của "bono"}}
=={{langname|ach}}==
==={{ĐM|noun}}===
{{head|ach|noun}}
# [[vải|Vải]], [[vải vóc]].
# [[quần áo|Quần áo]], [[trang phục]].
==={{ĐM|ref}}===
* {{R:ach:Blackings|17}}
=={{langname|dgi}}==
==={{ĐM|pron}}===
* {{IPA|dgi|/bòŋó/}}
==={{ĐM|noun}}===
{{head|dgi|noun|số nhiều|bonni}}
# Con [[lừa]].
==={{ĐM|ref}}===
* Ali, Gri & Bodomo: A dictionary and grammatical sketch of Dagaare (2021). [https://refubium.fu-berlin.de/bitstream/handle/fub188/30413/A_dictionary_and_grammatical_sketch_of_Dagaare.pdf?sequence=1&isAllowed=y]
tb2c8nrcd482wy8t9dw3oz6e2zmz9q3
Thể loại:Mục từ tiếng Dagara Bắc
14
421167
2573006
2026-10-23T13:40:30Z
TheHighFighter2
42988
Trang mới: “{{auto cat}}”
2573006
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Bản mẫu:R:ach:Blackings
10
421168
2573009
2026-10-23T14:51:48Z
TheHighFighter2
42988
Trang mới: “{{#invoke:quote|call_template |template=cite-book |last=Blackings|first= Mairi John|title=Acholi English – English Acholi Dictionary|publisher=LINCOM GmbH|location=Munich|year=2009|pageparam= 1|url=https://archive.org/details/acholienglisheng00mair|isbn=9783929075694}}<noinclude>{{reference template cat}}</noinclude>”
2573009
wikitext
text/x-wiki
{{#invoke:quote|call_template
|template=cite-book
|last=Blackings|first= Mairi John|title=Acholi English – English Acholi Dictionary|publisher=LINCOM GmbH|location=Munich|year=2009|pageparam= 1|url=https://archive.org/details/acholienglisheng00mair|isbn=9783929075694}}<noinclude>{{reference template cat}}</noinclude>
g4qii6julsy68gs7aebk2nxfgki6xm5
спинной мозг
0
421169
2573012
2026-10-23T14:55:58Z
Kelly zhrm
58416
Trang mới: “=={{langname|ru}}== {{wp|ru:}} ==={{ĐM|pron}}=== * {{ru-IPA|спинно́й мо́зг}} * {{audio|ru|Ru-спинной мозг.ogg}} ==={{ĐM|n}}=== {{ru-noun+|[[спинно́й]]|+|_|c|[[мозг]]}} # {{lb|ru|anatomy}} [[tủy sống|Tủy sống]]. ===={{ĐM|decl}}==== {{ru-noun-table|[[спинно́й]]|+|_|c|[[мозг]]}}”
2573012
wikitext
text/x-wiki
=={{langname|ru}}==
{{wp|ru:}}
==={{ĐM|pron}}===
* {{ru-IPA|спинно́й мо́зг}}
* {{audio|ru|Ru-спинной мозг.ogg}}
==={{ĐM|n}}===
{{ru-noun+|[[спинно́й]]|+|_|c|[[мозг]]}}
# {{lb|ru|anatomy}} [[tủy sống|Tủy sống]].
===={{ĐM|decl}}====
{{ru-noun-table|[[спинно́й]]|+|_|c|[[мозг]]}}
1w8dxfa5aawgr5szhg480sp99zw9i7d
Thể loại:ru:Giải phẫu học
14
421170
2573013
2026-10-23T14:56:44Z
Kelly zhrm
58416
Trang mới: “{{auto cat}}”
2573013
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
boɔ
0
421171
2573014
2026-10-23T15:02:40Z
TheHighFighter2
42988
Trang mới: “{{also|Phụ lục:Biến thể của "boo"}} =={{langname|ak}}== ==={{ĐM|alt}}=== * {{alt|ak|ɛboɔ}} ==={{ĐM|etym}} 1=== ===={{ĐM|noun}}==== {{ak-head|noun|pl=aboɔ}} # [[đá|Đá]]. #: {{syn|ak|ɔbotan}} ==={{ĐM|etym}} 2=== ===={{ĐM|noun}}==== {{ak-head|noun}} # [[giá|Giá]], [[giá cả]]. ==={{ĐM|ref}}=== * {{R:ak:LearnAkan|ɛboɔ}} =={{langname|dgi}}== ==={{ĐM|pron}}=== * {{IPA|dgi|/bʊ́ɔ́/}} ==={{ĐM|noun}}=== {{head|dgi|noun|số nhiều|bó…”
2573014
wikitext
text/x-wiki
{{also|Phụ lục:Biến thể của "boo"}}
=={{langname|ak}}==
==={{ĐM|alt}}===
* {{alt|ak|ɛboɔ}}
==={{ĐM|etym}} 1===
===={{ĐM|noun}}====
{{ak-head|noun|pl=aboɔ}}
# [[đá|Đá]].
#: {{syn|ak|ɔbotan}}
==={{ĐM|etym}} 2===
===={{ĐM|noun}}====
{{ak-head|noun}}
# [[giá|Giá]], [[giá cả]].
==={{ĐM|ref}}===
* {{R:ak:LearnAkan|ɛboɔ}}
=={{langname|dgi}}==
==={{ĐM|pron}}===
* {{IPA|dgi|/bʊ́ɔ́/}}
==={{ĐM|noun}}===
{{head|dgi|noun|số nhiều|bóóré}}
# [[dê|Dê]].
==={{ĐM|ref}}===
* Ali, Gri & Bodomo: A dictionary and grammatical sketch of Dagaare (2021). [https://refubium.fu-berlin.de/bitstream/handle/fub188/30413/A_dictionary_and_grammatical_sketch_of_Dagaare.pdf?sequence=1&isAllowed=y]
k8jbtncoxs1d0xf9x75wh7c62kma0lr
jentas
0
421172
2573021
2026-10-23T15:35:04Z
Hiyuune
50834
+ la
2573021
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntās}}
# {{inflection of|la|jēntō||indc|pres|actv|ở|2|s}}
ht26xs3qp043m9eh69xmepdvl0a4sat
jentat
0
421173
2573022
2026-10-23T15:35:46Z
Hiyuune
50834
+ la
2573022
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntat}}
# {{inflection of|la|jēntō||indc|pres|actv|ở|3|s}}
t7mblmrnasbl9sv3h3q830430s5h3th
jentamus
0
421174
2573023
2026-10-23T15:36:33Z
Hiyuune
50834
+ la
2573023
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntāmus}}
# {{inflection of|la|jēntō||indc|pres|actv|ở|1|p}}
69lvdtyx6fek7i6jpngyjpgup1dil79
Mô đun:ak-headword
828
421175
2573024
2026-10-23T15:38:36Z
TheHighFighter2
42988
Trang mới: “local export = {} local pos_functions = {} local M = require("Module:module loader").init { require = { headword_utilities = "Module:headword utilities", labels = "Module:labels", }, lazy = { lang = function() return require("Module:languages").getByCode("ak") end, }, } local force_cat = false local lect_data = { {"Twi", aliases = {"t"}}, {"Akuapem", parent = "Twi", aliases = {"ak"}}, {"Asante", parent = "Twi", aliases = {"as"}}, {"Fante", aliases = {"f"}…”
2573024
Scribunto
text/plain
local export = {}
local pos_functions = {}
local M = require("Module:module loader").init {
require = {
headword_utilities = "Module:headword utilities",
labels = "Module:labels",
},
lazy = {
lang = function() return require("Module:languages").getByCode("ak") end,
},
}
local force_cat = false
local lect_data = {
{"Twi", aliases = {"t"}},
{"Akuapem", parent = "Twi", aliases = {"ak"}},
{"Asante", parent = "Twi", aliases = {"as"}},
{"Fante", aliases = {"f"}},
}
local lect_names = {}
for _, lect in ipairs(lect_data) do
lect_names[lect[1]] = lect[1]
for _, alias in ipairs(lect.aliases) do
lect_names[alias] = lect[1]
end
end
local function get_lects(value)
if not value or not value:find("%S") then
return {}
end
local list = mw.text.split(value, "%s*,%s*")
for i, lect in ipairs(list) do
list[i] = lect_names[lect]
if not list[i] then
local valid = {}
for _, data in ipairs(lect_data) do
table.insert(valid, ("%s (%s)"):format(data[1], data.aliases[1]))
end
error(("Unrecognized lect '%s'; use %s"):format(lect, mw.text.listToText(valid, ", ", " or ")))
end
end
return list
end
function export.show(frame)
local headword = M.headword_utilities.process_headword {
lang = M.lang,
frame = frame,
pos_functions = pos_functions,
force_cat = force_cat,
augment_params = function(data, params)
params.lect = true
end,
}
local args = frame:getParent().args
local list = get_lects(args.lect)
if not list[1] or args.json then
return headword
end
return headword .. " " .. M.labels.show_labels {labels = list, lang = M.lang, mode = "term-label"}
end
pos_functions["head.nouns"] = {
infls = {
{"pl", label = "plural"},
},
}
pos_functions["head.adjectives"] = {
infls = {
{"pl", label = "plural"},
{"redup", label = "reduplication"},
{"triplication", label = "triplication"},
},
}
pos_functions["head.adverbs"] = {
infls = {
{"triplication", label = "triplication"},
},
}
local function verb_form(param, label, form)
return {param,
label = label,
accel_form = form,
}
end
pos_functions["head.verbs"] = {
infls = {
verb_form("tpast", "transitive past", "tr|past"),
verb_form("ipast", "intransitive past", "intr|past"),
verb_form("neg", "negative", "neg"),
verb_form("fut", "future", "fut"),
verb_form("prog", "progressive", "prog"),
verb_form("pros", "prospective", "pros"),
verb_form("perf", "perfect", "perf"),
verb_form("imp", "imperative", "imp"),
verb_form("redup", "reduplication"),
},
}
return export
30v1ugeaukiqbcyp42k9ayffnnoq1yt
2573057
2573024
2026-10-23T16:04:59Z
TheHighFighter2
42988
2573057
Scribunto
text/plain
local export = {}
local pos_functions = {}
local M = require("Module:module loader").init {
require = {
headword_utilities = "Module:headword utilities",
labels = "Module:labels",
},
lazy = {
lang = function() return require("Module:languages").getByCode("ak") end,
},
}
local force_cat = false
local lect_data = {
{"Twi", aliases = {"t"}},
{"Akuapem", parent = "Twi", aliases = {"ak"}},
{"Asante", parent = "Twi", aliases = {"as"}},
{"Fante", aliases = {"f"}},
}
local lect_names = {}
for _, lect in ipairs(lect_data) do
lect_names[lect[1]] = lect[1]
for _, alias in ipairs(lect.aliases) do
lect_names[alias] = lect[1]
end
end
local function get_lects(value)
if not value or not value:find("%S") then
return {}
end
local list = mw.text.split(value, "%s*,%s*")
for i, lect in ipairs(list) do
list[i] = lect_names[lect]
if not list[i] then
local valid = {}
for _, data in ipairs(lect_data) do
table.insert(valid, ("%s (%s)"):format(data[1], data.aliases[1]))
end
error(("Unrecognized lect '%s'; use %s"):format(lect, mw.text.listToText(valid, ", ", " or ")))
end
end
return list
end
function export.show(frame)
local headword = M.headword_utilities.process_headword {
lang = M.lang,
frame = frame,
pos_functions = pos_functions,
force_cat = force_cat,
augment_params = function(data, params)
params.lect = true
end,
}
local args = frame:getParent().args
local list = get_lects(args.lect)
if not list[1] or args.json then
return headword
end
return headword .. " " .. M.labels.show_labels {labels = list, lang = M.lang, mode = "term-label"}
end
pos_functions["head.Danh từ"] = {
infls = {
{"pl", label = "plural"},
},
}
pos_functions["head.Tính từ"] = {
infls = {
{"pl", label = "plural"},
{"redup", label = "reduplication"},
{"triplication", label = "triplication"},
},
}
pos_functions["head.Phó từ"] = {
infls = {
{"triplication", label = "triplication"},
},
}
local function verb_form(param, label, form)
return {param,
label = label,
accel_form = form,
}
end
pos_functions["head.Động từ"] = {
infls = {
verb_form("tpast", "transitive past", "tr|past"),
verb_form("ipast", "intransitive past", "intr|past"),
verb_form("neg", "negative", "neg"),
verb_form("fut", "future", "fut"),
verb_form("prog", "progressive", "prog"),
verb_form("pros", "prospective", "pros"),
verb_form("perf", "perfect", "perf"),
verb_form("imp", "imperative", "imp"),
verb_form("redup", "reduplication"),
},
}
return export
05khzy6yfnsgvovc4h8q0efgfp2c3mc
2573063
2573057
2026-10-23T16:11:09Z
TheHighFighter2
42988
2573063
Scribunto
text/plain
local export = {}
local pos_functions = {}
local M = require("Module:module loader").init {
require = {
headword_utilities = "Module:headword utilities",
labels = "Module:labels",
},
lazy = {
lang = function() return require("Module:languages").getByCode("ak") end,
},
}
local force_cat = false
local lect_data = {
{"Twi", aliases = {"t"}},
{"Akuapem", parent = "Twi", aliases = {"ak"}},
{"Asante", parent = "Twi", aliases = {"as"}},
{"Fante", aliases = {"f"}},
}
local lect_names = {}
for _, lect in ipairs(lect_data) do
lect_names[lect[1]] = lect[1]
for _, alias in ipairs(lect.aliases) do
lect_names[alias] = lect[1]
end
end
local function get_lects(value)
if not value or not value:find("%S") then
return {}
end
local list = mw.text.split(value, "%s*,%s*")
for i, lect in ipairs(list) do
list[i] = lect_names[lect]
if not list[i] then
local valid = {}
for _, data in ipairs(lect_data) do
table.insert(valid, ("%s (%s)"):format(data[1], data.aliases[1]))
end
error(("Unrecognized lect '%s'; use %s"):format(lect, mw.text.listToText(valid, ", ", " or ")))
end
end
return list
end
function export.show(frame)
local headword = M.headword_utilities.process_headword {
lang = M.lang,
frame = frame,
pos_functions = pos_functions,
force_cat = force_cat,
augment_params = function(data, params)
params.lect = true
end,
}
local args = frame:getParent().args
local list = get_lects(args.lect)
if not list[1] or args.json then
return headword
end
return headword .. " " .. M.labels.show_labels {labels = list, lang = M.lang, mode = "term-label"}
end
pos_functions["head.Danh từ"] = {
infls = {
{"pl", label = "số nhiều"},
},
}
pos_functions["head.Tính từ"] = {
infls = {
{"pl", label = "plural"},
{"redup", label = "reduplication"},
{"triplication", label = "triplication"},
},
}
pos_functions["head.Phó từ"] = {
infls = {
{"triplication", label = "triplication"},
},
}
local function verb_form(param, label, form)
return {param,
label = label,
accel_form = form,
}
end
pos_functions["head.Động từ"] = {
infls = {
verb_form("tpast", "transitive past", "tr|past"),
verb_form("ipast", "intransitive past", "intr|past"),
verb_form("neg", "negative", "neg"),
verb_form("fut", "future", "fut"),
verb_form("prog", "progressive", "prog"),
verb_form("pros", "prospective", "pros"),
verb_form("perf", "perfect", "perf"),
verb_form("imp", "imperative", "imp"),
verb_form("redup", "reduplication"),
},
}
return export
tat0wdky9abarodzt92h5cra3x4wcke
jentatis
0
421176
2573025
2026-10-23T15:38:45Z
Hiyuune
50834
+ la
2573025
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntātis}}
# {{inflection of|la|jēntō||indc|pres|actv|ở|2|p}}
g5ireqrhozers7mboew4jt856x0bal6
jentant
0
421177
2573026
2026-10-23T15:40:15Z
Hiyuune
50834
+ la
2573026
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jentant}}
# {{inflection of|la|jentō||indc|pres|actv|ở|3|p}}
633erngmq47yw69c7noh7qk6db9w5qz
jentabam
0
421178
2573028
2026-10-23T15:41:44Z
Hiyuune
50834
+ la
2573028
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābam}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|1|s}}
nmd6nky91m6fr7m31jfsf6l7upuu1iw
jentabas
0
421179
2573030
2026-10-23T15:42:49Z
Hiyuune
50834
+ la
2573030
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābās}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|2|s}}
r8srdfsv2j3l2s47p0vuv2lvxkkekl5
jentabat
0
421180
2573032
2026-10-23T15:43:19Z
Hiyuune
50834
+ la
2573032
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābās}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|3|s}}
7kmrwf2k3pg2hemueahfx3mpn3hrx8b
2573037
2573032
2026-10-23T15:46:28Z
Hiyuune
50834
/* Động từ */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2573037
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jentābat}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|3|s}}
oj0nw6a76jw1o66zquq28mb7ryd2njg
jentabamus
0
421181
2573033
2026-10-23T15:43:34Z
Hiyuune
50834
+ la
2573033
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābās}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|1|p}}
0jatwclfiqbdmf8vjg5vk67w3nfnpk8
2573038
2573033
2026-10-23T15:46:39Z
Hiyuune
50834
2573038
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jentābāmus}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|1|p}}
3dk2p5i7f9d62uiof8xnwhhof7g9a45
jentabatis
0
421182
2573034
2026-10-23T15:43:47Z
Hiyuune
50834
+ la
2573034
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābās}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|2|p}}
h1m7fhtilal0tr7vicwmn9nc5baeq2x
2573039
2573034
2026-10-23T15:46:52Z
Hiyuune
50834
2573039
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jentābātis}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|2|p}}
8mthso5wzqhw0orc89vmafh98yh9r5q
jentabant
0
421183
2573035
2026-10-23T15:44:00Z
Hiyuune
50834
+ la
2573035
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābās}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|3|p}}
p9dymnpligbt33617noyyllq9g75yis
2573040
2573035
2026-10-23T15:47:04Z
Hiyuune
50834
2573040
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jentābant}}
# {{inflection of|la|jēntō||indc|impf|actv|ở|3|p}}
qd3vwr0tu3rwn2opy7k9cc760pt29oz
jentabo
0
421184
2573036
2026-10-23T15:46:09Z
Hiyuune
50834
Trang mới: “=={{langname|la}}== ==={{section|v}}=== {{head|la|Biến thể hình thái động từ|head=jēntābō}} # {{inflection of|la|jēntō||indc|futr|actv|ở|1|s}}”
2573036
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābō}}
# {{inflection of|la|jēntō||indc|futr|actv|ở|1|s}}
6rylbakhjnl16envd9gvz2n3oxsr9pt
jentabis
0
421185
2573041
2026-10-23T15:49:35Z
Hiyuune
50834
+ la
2573041
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābis}}
# {{inflection of|la|jēntō||indc|futr|actv|ở|2|s}}
o3cdccnz9wywfcjd3f3dpzev9wt2q0q
jentabit
0
421186
2573042
2026-10-23T15:50:18Z
Hiyuune
50834
+ la
2573042
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābit}}
# {{inflection of|la|jēntō||indc|futr|actv|ở|3|s}}
lsnqi071zfkox55b0934lndfu8n494g
jentabimus
0
421187
2573043
2026-10-23T15:51:57Z
Hiyuune
50834
+ la
2573043
wikitext
text/x-wiki
=={{langname|la}}==
==={{section|v}}===
{{head|la|Biến thể hình thái động từ|head=jēntābimus}}
# {{inflection of|la|jēntō||indc|futr|ở|1|p}}
emurbk2ch3vf70ai8dpqgl0v1p8hh97
mơngế kâ
0
421188
2573044
2026-10-23T15:52:13Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[miệng]]. #:{{ux|sed|môi ngế pêi cheăng păn pŭn '''mơngế kâ'''|một mình làm nuôi bốn '''miệng '''ăn}} ==={{section|ref}}=== * {{R:VOV}}”
2573044
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[miệng]].
#:{{ux|sed|môi ngế pêi cheăng păn pŭn '''mơngế kâ'''|một mình làm nuôi bốn '''miệng '''ăn}}
==={{section|ref}}===
* {{R:VOV}}
65t8ei8qmkzg52q10v1oj4y1nijnvxm
Thể loại:Danh từ tiếng Saramacca
14
421189
2573049
2026-10-23T15:54:41Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573049
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Mục từ tiếng Saramacca
14
421190
2573050
2026-10-23T15:56:03Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573050
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Tiếng Saramacca
14
421191
2573051
2026-10-23T15:56:48Z
Hiyuune
50834
Trang mới: “{{auto cat|Suriname|Guyane thuộc Pháp}}”
2573051
wikitext
text/x-wiki
{{auto cat|Suriname|Guyane thuộc Pháp}}
pg8yz8nt0tp5w3qbwilrm93nny7r5qm
makáku
0
421192
2573052
2026-10-23T15:58:23Z
Hiyuune
50834
Trang mới: “{{also|makaku}} =={{langname|srm}}== ==={{section|etym}}=== {{ety|srm|:bor|pt:macaco|text=+|tree=1}} ==={{section|n}}=== {{head|srm|Danh từ}} # [[khỉ]]. ==={{section|ref}}=== * {{R:srm:SIL}} {{C|srm|Khỉ}}”
2573052
wikitext
text/x-wiki
{{also|makaku}}
=={{langname|srm}}==
==={{section|etym}}===
{{ety|srm|:bor|pt:macaco|text=+|tree=1}}
==={{section|n}}===
{{head|srm|Danh từ}}
# [[khỉ]].
==={{section|ref}}===
* {{R:srm:SIL}}
{{C|srm|Khỉ}}
bt00t0frwxqshukp3y1ltfp6xl936nb
وانٛدُر
0
421193
2573053
2026-10-23T15:59:54Z
Hiyuune
50834
Trang mới: “=={{langname|ks}}== ==={{section|etym}}=== Từ {{inh|ks|sa|वानर}}. ==={{section|pron}}=== * {{IPA|ks|[wãːdur]}} ==={{section|n}}=== {{ks-noun|g=m|dv=वाँदुर}} # [[khỉ]]. {{C|ks|Khỉ}}”
2573053
wikitext
text/x-wiki
=={{langname|ks}}==
==={{section|etym}}===
Từ {{inh|ks|sa|वानर}}.
==={{section|pron}}===
* {{IPA|ks|[wãːdur]}}
==={{section|n}}===
{{ks-noun|g=m|dv=वाँदुर}}
# [[khỉ]].
{{C|ks|Khỉ}}
06yrbgsub1wd3gwhio81pe1euah9vhy
वाँदुर
0
421194
2573054
2026-10-23T16:01:50Z
Hiyuune
50834
Trang mới: “=={{langname|ks}}== ==={{section|etym}}=== Từ {{inh|ks|sa|वानर|t=khỉ}}. ==={{section|pron}}=== * {{IPA|ks|[wãːdur]}} ==={{section|n}}=== {{ks-noun|g=m|pa=وانٛدُر}} # [[khỉ]]. {{C|ks|Khỉ}}”
2573054
wikitext
text/x-wiki
=={{langname|ks}}==
==={{section|etym}}===
Từ {{inh|ks|sa|वानर|t=khỉ}}.
==={{section|pron}}===
* {{IPA|ks|[wãːdur]}}
==={{section|n}}===
{{ks-noun|g=m|pa=وانٛدُر}}
# [[khỉ]].
{{C|ks|Khỉ}}
kz8mfkip002syfb9t0d1ld0u0404nry
majom
0
421195
2573056
2026-10-23T16:04:22Z
Hiyuune
50834
+ hu
2573056
wikitext
text/x-wiki
=={{langname|hu}}==
==={{section|etym}}===
Từ {{der|hu|ar|مَيْمُون}}.<ref>{{R:Zaicz 2006}}</ref>
==={{section|pron}}===
* {{hu-IPA}}
* {{audio|hu|LL-Q9067 (hun)-Procrastineur49-majom.wav}}
* {{rhymes|hu|om|s=2}}
* {{hyphenation|hu|ma|jom}}
==={{section|n}}===
{{hu-noun|pl=majmok}}
# [[vượn]], [[khỉ]].
===={{section|decl}}====
{{hu-infl-nom|majmo|o|stem2=majom|spe_sg_stem=majm}}{{hu-pos-otok|majm||ai}}
===={{section|drv}}====
{{col4|hu
|majmol
|majomkodik
}}
{{col4|hu|title=Từ ghép
|majomhimlő
|majomkenyérfa
|majomszeretet
|makimajom
}}
{{col2|hu|title=Mở rộng
|most ugrik a majom a vízbe
|tengeri majom
}}
===={{section|desc}}====
* {{desc|ro|moimă|bor=1}}
==={{section|ref}}===
{{reflist}}
==={{section|further}}===
* {{R:ErtSz}}
{{C|hu|Khỉ}}
ayafqjfwdyi6rx72qmflvibn6261imp
маймалак
0
421196
2573058
2026-10-23T16:07:40Z
Hiyuune
50834
Trang mới: “=={{langname|av}}== ==={{section|etym}}=== Từ {{der|av|ar|مَيْمُون}}. ==={{section|n}}=== {{av-noun}} # [[khỉ]]. {{c|av|Bộ Linh trưởng}}”
2573058
wikitext
text/x-wiki
=={{langname|av}}==
==={{section|etym}}===
Từ {{der|av|ar|مَيْمُون}}.
==={{section|n}}===
{{av-noun}}
# [[khỉ]].
{{c|av|Bộ Linh trưởng}}
2k2oxewdggiv0qhz48h0jyn6o0rhef1
Thể loại:av:Bộ Linh trưởng
14
421197
2573059
2026-10-23T16:07:51Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573059
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Bộ Linh trưởng
14
421198
2573060
2026-10-23T16:08:29Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573060
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
meymun
0
421199
2573061
2026-10-23T16:09:52Z
Hiyuune
50834
+ az
2573061
wikitext
text/x-wiki
=={{langname|az}}==
{{wp|az:}}
{{az-variant|мејмун|مئیمۇن}}
==={{section|etym}}===
{{ety|az|:bor|ar:مَيْمُون|text=+|tree=1}}
==={{section|pron}}===
* {{audio|az|LL-Q9292 (aze)-Azerbaijani audiorecordings-meymun.wav|a=Baku}}
* {{hyph|az|mey|mun}}
==={{section|n}}===
{{az-noun}}
# [[khỉ]].
===={{section|decl}}====
{{az-decl-noun|u|c}}
==={{section|ref}}===
* {{R:az:ADIL}}
{{C|az|Bộ Linh trưởng}}
c133q8f5hm6wken3xa16ts6h3j3zqqx
маймыл
0
421200
2573064
2026-10-23T16:15:17Z
Hiyuune
50834
+ ba, kk, ky
2573064
wikitext
text/x-wiki
=={{langname|ba}}==
[[Image:Berberaffe,_Barbary_Macaque_(Macaca_sylvanus)_-_Tierpark_Gera_06.jpg|thumb|Маймыл (nghĩa 1)]]
==={{section|etym}}===
Từ {{bor|ba|ar|مَيْمُون||khỉ}}.
Cùng gốc với {{cog|krc|маймул|tr=maymul}}, {{cog|kk|-}}, {{cog|ky|-}}, {{cog|tt|маймыл||khỉ}}.
==={{section|pron}}===
* {{IPA|ba|[mɑjˈmɯ̞ɫ]}}
* {{hyphenation|ba|май|мыл}}
==={{section|n}}===
{{ba-noun}}
# [[khỉ]].
# [[vượn]].
===={{section|decl}}====
{{ba-ndecl-c|ы|л}}
{{C|ba|Bộ Linh trưởng}}
=={{langname|kk}}==
{{kk-regional|маймыл|مايمىل}}
==={{section|etym}}===
Từ {{der|kk|ar|مَيْمُون}}.
==={{section|pron}}===
* {{IPA|kk|[mɑjˈmɯɫ]}}
==={{section|n}}===
{{kk-noun}}
# [[khỉ]].
===={{section|decl}}====
{{kk-noun-c|ы|л}}
{{C|kk|Bộ Linh trưởng}}
=={{langname|ky}}==
==={{section|etym}}===
Từ {{der|ky|ar|مَيْمُون}}.
==={{section|pron}}===
* {{ky-IPA|майˈмыл}}
* {{audio|ky|LL-Q9255 (kir)-Almanbet Janışev-маймыл.wav}}
==={{section|n}}===
{{ky-noun}}
# [[khỉ]].
===={{section|decl}}====
{{ky-decl-noun}}
{{C|ky|Bộ Linh trưởng}}
o1ue7wv1bgyzxhfrvy9962y1cdj2t8i
Bản mẫu:R:bg:Gerov:digital
10
421201
2573065
2026-10-23T16:25:10Z
Hiyuune
50834
Trang mới: ““[https://gerov-rechnik.net/{{{1|}}} {{{2|{{{1|}}}}}}]”, in [[w:bg:Речник на българския език (Найден Геров)|Рѣчникъ на Блъгарскꙑй язꙑкъ]] [Từ điển tiếng Bulgaria] (trong tiếng Bulgaria), [https://gerov-rechnik.net/ gerov-rechnik.net], ấn bản {{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}} ({{#switch:{{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}}|1=1895|2=1897|3=1899|4=1901|5=1904|6=1908|#defaul…”
2573065
wikitext
text/x-wiki
“[https://gerov-rechnik.net/{{{1|}}} {{{2|{{{1|}}}}}}]”, in [[w:bg:Речник на българския език (Найден Геров)|Рѣчникъ на Блъгарскꙑй язꙑкъ]] [Từ điển tiếng Bulgaria] (trong tiếng Bulgaria), [https://gerov-rechnik.net/ gerov-rechnik.net], ấn bản {{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}} ({{#switch:{{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}}|1=1895|2=1897|3=1899|4=1901|5=1904|6=1908|#default=1895–1908}}).<noinclude>{{tcat}}</noinclude>
ozy1ogrvz3azz7x6s4ad3qtsdwd3q72
2573067
2573065
2026-10-23T16:25:42Z
Hiyuune
50834
2573067
wikitext
text/x-wiki
“[https://gerov-rechnik.net/{{{1|}}} {{{2|{{{1|}}}}}}]”, trong [[w:bg:Речник на българския език (Найден Геров)|Рѣчникъ на Блъгарскꙑй язꙑкъ]] [Từ điển tiếng Bulgaria] (trong tiếng Bulgaria), [https://gerov-rechnik.net/ gerov-rechnik.net], ấn bản {{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}} ({{#switch:{{#invoke:string/templates|sub|{{{1|b1/}}}|2|2}}|1=1895|2=1897|3=1899|4=1901|5=1904|6=1908|#default=1895–1908}}).<noinclude>{{tcat}}</noinclude>
omgz5yvptz2tnrbhg9avg1tzsbnfvqc
маймуна
0
421202
2573066
2026-10-23T16:25:23Z
Hiyuune
50834
+ bg
2573066
wikitext
text/x-wiki
=={{langname|bg}}==
{{wp|bg:}}
==={{section|pron}}===
{{bg-pr|майму́на|a=[KK]}}
==={{section|n}}===
{{bg-noun|майму́на|f|dim=майму́нка|dim2=майму́нче|adj=майму́нски}}
# [[khỉ|Khỉ]].
# [[vượn|Vượn]].
# {{lb|bg|colloquial|Internet}} Ký hiệu (@).
#: {{syn|bg|кльо́мба|майму́нка|майму́нско а́|ухо́}}
===={{section|decl}}====
{{bg-ndecl|майму́на<(v)>}}
==={{section|further}}===
* {{R:bg:Gerov:digital|b3/01341|Майму́на}}
{{C|bg|Bộ Linh trưởng}}
hnkgj3bb3yrche4wis08fkf3wj69afi
маймуни
0
421203
2573068
2026-10-23T16:29:34Z
Hiyuune
50834
+ bg
2573068
wikitext
text/x-wiki
{{also|мајмуни}}
=={{langname|bg}}==
==={{section|n}}===
{{head|bg|Biến thể hình thái danh từ|head=майму́ни}}
# {{inflection of|bg|майму́на||indef|p}}
i2gqrurew68uvz1yzbtpittgbt8it4p
2573069
2573068
2026-10-23T16:30:43Z
Hiyuune
50834
/* Tiếng Bulgari */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]])
2573069
wikitext
text/x-wiki
{{also|мајмуни}}
=={{langname|bg}}==
==={{section|n}}===
{{head|bg|Biến thể hình thái danh từ|head=майму́ни}}
# {{inflection of|bg|майму́на||indef|p|;|voc|p}}
q67ydysns41inkx40a7hy5hix3kksen
маймуната
0
421204
2573070
2026-10-23T16:31:25Z
Hiyuune
50834
+ bg
2573070
wikitext
text/x-wiki
=={{langname|bg}}==
==={{section|n}}===
{{head|bg|Biến thể hình thái danh từ|head=майму́ната}}
# {{inflection of|bg|майму́на||def|s}}
p58kty7r9vhfdxxzr1w7tcelwy1j9fq
isneach
0
421205
2573071
2026-10-24T01:33:40Z
Hiyuune
50834
/* */ + gd (import to enwikt, author: User:Altronic)
2573071
wikitext
text/x-wiki
=={{langname|gd}}==
==={{section|n}}===
{{gd-noun|f|-ich|-ichean}}
# [[súng trường]].
#: {{synonyms|gd|raidhfil}}
===={{section|decl}}====
{{gd-decl-noun-f2a|i|sneach|snich|an|poly=1|s=1}}
==={{section|mut}}===
{{gd-mut}}
==={{section|further}}===
* {{R:Dwelly}}
jujp2whzn980en8rgayo4da4gykvozg
ainm-àite
0
421206
2573072
2026-10-24T01:36:19Z
Hiyuune
50834
/* */
2573072
wikitext
text/x-wiki
=={{langname|gd}}==
==={{sect|n}}===
{{gd-noun|m|~|ainmean-àite}}
# [[địa danh]].
==={{sect|mut}}===
{{gd-mut}}
==={{sect|further}}===
* {{R:Dwelly}}
psivpvilgp6ux2qm0iiiwxvh8wabvin
ngâ
0
421207
2573074
2026-10-24T04:05:12Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[miệng]]. #:{{ux|sed|'''ngâ '''vó|'''miệng '''ché}} ==={{section|ref}}=== * {{R:VOV}}”
2573074
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[miệng]].
#:{{ux|sed|'''ngâ '''vó|'''miệng '''ché}}
==={{section|ref}}===
* {{R:VOV}}
jfkq6kt8atbbh01ran93islygjky94a
pơlôu
0
421208
2573075
2026-10-24T04:05:58Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[miệng]]. #:{{syn|sed|trŭm}} ==={{section|ref}}=== * {{R:VOV}}”
2573075
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[miệng]].
#:{{syn|sed|trŭm}}
==={{section|ref}}===
* {{R:VOV}}
n5a49zofotze9etj13b8mqv9a1vts41
trŭm
0
421209
2573076
2026-10-24T04:06:48Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[miệng]]. #:{{ux|sed|'''trŭm '''kiâp hmốu|'''miệng '''hang}} #:{{syn|sed|pơlôu}} ==={{section|ref}}=== * {{R:VOV}}”
2573076
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[miệng]].
#:{{ux|sed|'''trŭm '''kiâp hmốu|'''miệng '''hang}}
#:{{syn|sed|pơlôu}}
==={{section|ref}}===
* {{R:VOV}}
su06ce18wixna47jegqoeot887s4cd9
trâm tơpui a mâ
0
421210
2573077
2026-10-24T04:07:30Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|part}}=== {{head|sed|Trợ từ}} # [[miệng]]. #:{{ux|sed|tiâ '''trâm tơpui a mâ'''|trả lời '''miệng'''}} ==={{section|ref}}=== * {{R:VOV}}”
2573077
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|part}}===
{{head|sed|Trợ từ}}
# [[miệng]].
#:{{ux|sed|tiâ '''trâm tơpui a mâ'''|trả lời '''miệng'''}}
==={{section|ref}}===
* {{R:VOV}}
h57v4kikezde118988eu7wgx110tpsa
Thể loại:ren:Răng
14
421211
2573080
2026-10-24T04:12:59Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573080
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:tdr:Răng
14
421212
2573081
2026-10-24T04:13:01Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573081
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Răng
14
421213
2573082
2026-10-24T04:13:03Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573082
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:ren:Miệng
14
421214
2573083
2026-10-24T04:13:10Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573083
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:tdr:Miệng
14
421215
2573084
2026-10-24T04:13:16Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573084
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:ren:Khuôn mặt
14
421216
2573085
2026-10-24T04:13:24Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573085
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Miệng
14
421217
2573086
2026-10-24T04:13:32Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573086
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:tdr:Khuôn mặt
14
421218
2573087
2026-10-24T04:13:36Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573087
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:ren:Đầu và cổ
14
421219
2573088
2026-10-24T04:13:38Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573088
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:ren:Bộ phận cơ thể
14
421220
2573089
2026-10-24T04:13:45Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573089
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:tdr:Đầu và cổ
14
421221
2573090
2026-10-24T04:13:51Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573090
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Khuôn mặt
14
421222
2573091
2026-10-24T04:13:57Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573091
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:ren:Cơ thể
14
421223
2573092
2026-10-24T04:14:04Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573092
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Đầu và cổ
14
421224
2573093
2026-10-24T04:14:10Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573093
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Bộ phận cơ thể
14
421225
2573094
2026-10-24T04:14:18Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573094
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
hơněng hlôu
0
421226
2573095
2026-10-24T04:16:18Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng cửa]]. #:{{ux|sed|châi '''hơněng hlôu'''|Đau '''răng cửa'''}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573095
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng cửa]].
#:{{ux|sed|châi '''hơněng hlôu'''|Đau '''răng cửa'''}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
svb171pk2bzvrfuxze6wknxmhcyzn5v
pơ-eăm
0
421227
2573096
2026-10-24T04:17:34Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng hàm]]. #:{{ux|sed|'''pơ-eăm''' dế châi|'''Răng hàm''' bị đau}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573096
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng hàm]].
#:{{ux|sed|'''pơ-eăm''' dế châi|'''Răng hàm''' bị đau}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
kvqkgibgt2phmzgb1grck8v4p82a7sg
hơněng eăm
0
421228
2573097
2026-10-24T04:18:01Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng hàm]]. #:{{ux|sed|'''hơněng eăm''' dế châi|'''Răng hàm''' bị đau}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573097
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng hàm]].
#:{{ux|sed|'''hơněng eăm''' dế châi|'''Răng hàm''' bị đau}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
qq8dxypgfx2oj1n9cfywpuswzaekrvo
hơněng tơ-eăm tui
0
421229
2573098
2026-10-24T04:19:33Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng khôn]]. #:{{ux|sed|'''hơněng tơ-eăm tui''' ối kŭn|'''Răng khôn''' còn nhỏ}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573098
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng khôn]].
#:{{ux|sed|'''hơněng tơ-eăm tui''' ối kŭn|'''Răng khôn''' còn nhỏ}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
g97wlekkzh3r7clasipjrpa1tje8dwa
hơněng chó
0
421230
2573099
2026-10-24T04:24:34Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng nanh]]. #:{{ux|sed|huăn '''hơněng chó'''|Mọc '''răng nanh'''}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573099
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng nanh]].
#:{{ux|sed|huăn '''hơněng chó'''|Mọc '''răng nanh'''}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
hevogknua9pwum6ib20lo307kcivrdr
civil right
0
421231
2573100
2026-10-24T04:25:27Z
Hiyuune
50834
Trang mới: “=={{langname|en}}== ==={{section|v}}=== {{en-noun}} # {{singular of|en|civil rights}}”
2573100
wikitext
text/x-wiki
=={{langname|en}}==
==={{section|v}}===
{{en-noun}}
# {{singular of|en|civil rights}}
5rn8rbmn227k1mtvwx222cgd5bwyqmq
civil rights
0
421232
2573101
2026-10-24T04:26:39Z
Hiyuune
50834
+ en
2573101
wikitext
text/x-wiki
=={{langname|en}}==
{{wp|en:Civil and political rights}}
==={{section|pron}}===
* {{audio|en|LL-Q1860 (eng)-Vealhurl-civil rights.wav|a=Southern England}}
==={{section|n}}===
{{en-noun|p|sg=civil right}}
# [[quyền]] [[dân sự]].
===={{section|drv}}====
{{col|en|civil rightist|civil rights movement|snivel rights}}
===={{section|rel}}====
{{col3|en|absolute right|civil liberties|fundamental right|human right|natural right|neuroright}}
8cm9ykqjou1hzl45u5z55m2yjmn5hum
ngrěk ngrěk
0
421233
2573102
2026-10-24T04:26:56Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|adj}}=== {{head|sed|Tính từ}} # [[răng rắc]]. #:{{ux|sed|'''ngrěk ngrěk'''|Cành cây khô gãy '''răng rắc'''}} ==={{section|ref}}=== * {{R:VOV}}”
2573102
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|adj}}===
{{head|sed|Tính từ}}
# [[răng rắc]].
#:{{ux|sed|'''ngrěk ngrěk'''|Cành cây khô gãy '''răng rắc'''}}
==={{section|ref}}===
* {{R:VOV}}
is252ao99s8nw207jwfh0bkrcwy3byz
hơněng têa tôu
0
421234
2573103
2026-10-24T04:27:36Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[răng sữa]]. #:{{ux|sed|'''hơněng têa tôu''' tro kơdrun kâ|ăn kẹo nhiều quá, '''răng sữa''' con bé sún hết}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Răng}}”
2573103
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[răng sữa]].
#:{{ux|sed|'''hơněng têa tôu''' tro kơdrun kâ|ăn kẹo nhiều quá, '''răng sữa''' con bé sún hết}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Răng}}
qgytlr48a71b7ij76b5nup8lv7u3ak7
民権
0
421235
2573104
2026-10-24T04:27:46Z
Hiyuune
50834
+ ja
2573104
wikitext
text/x-wiki
{{also|民權|民权}}
=={{langname|ja}}==
{{ja-kanjitab|みん|けん|yomi=o}}
==={{section|pron}}===
{{ja-pron|みんけん|acc=0}}
==={{section|n}}===
{{ja-noun|みんけん}}
# [[quyền]] [[dân sự]].
==={{section|ref}}===
* {{R:Kanjipedia Kotoba|0006630700}}
3nj9dfjgaefq0t56s2o69z37b5c9glt
みんけん
0
421236
2573105
2026-10-24T04:28:04Z
Hiyuune
50834
Trang mới: “=={{langname|ja}}== {{ja-see|民権}}”
2573105
wikitext
text/x-wiki
=={{langname|ja}}==
{{ja-see|民権}}
4o8vmjyvt2qkb52m4qfqecc4g3e65w8
minken
0
421237
2573106
2026-10-24T04:30:06Z
Hiyuune
50834
Trang mới: “=={{langname|nn}}== ==={{section|n}}=== {{head|nn|Biến thể hình thái danh từ|g=m}} # {{inflection of|nn|mink||def|s}} =={{langname|ja}}== ==={{section|rom}}=== {{ja-rom}} # {{ja-rom of|みんけん}} =={{langname|sv}}== ==={{section|n}}=== {{head|sv|Biến thể hình thái danh từ}} # {{noun form of|sv|mink||def|s}}”
2573106
wikitext
text/x-wiki
=={{langname|nn}}==
==={{section|n}}===
{{head|nn|Biến thể hình thái danh từ|g=m}}
# {{inflection of|nn|mink||def|s}}
=={{langname|ja}}==
==={{section|rom}}===
{{ja-rom}}
# {{ja-rom of|みんけん}}
=={{langname|sv}}==
==={{section|n}}===
{{head|sv|Biến thể hình thái danh từ}}
# {{noun form of|sv|mink||def|s}}
itkm2kkvhs9sgfsegt0fwscm2738co1
Thể loại:Biến thể hình thái danh từ tiếng Na Uy (Nynorsk)
14
421238
2573107
2026-10-24T04:30:25Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573107
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:Mục từ biến thể hình thái tiếng Na Uy (Nynorsk)
14
421239
2573108
2026-10-24T04:30:52Z
Hiyuune
50834
Trang mới: “{{auto cat}}”
2573108
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
rơpê
0
421240
2573109
2026-10-24T04:31:54Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]]. #:{{ux|sed|lế '''rơpê'''|Lè '''lưỡi'''}} ==={{section|ref}}=== * {{R:VOV}}”
2573109
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]].
#:{{ux|sed|lế '''rơpê'''|Lè '''lưỡi'''}}
==={{section|ref}}===
* {{R:VOV}}
f2wwqn5r2yb9566zamphum5qe9zo10u
kuăn
0
421241
2573112
2026-10-24T04:33:03Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi câu]]. ==={{section|ref}}=== * {{R:VOV}}”
2573112
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi câu]].
==={{section|ref}}===
* {{R:VOV}}
q1r5xcg853bmy4pe3aw0lkg2g8ublum
kruăn
0
421242
2573113
2026-10-24T04:33:16Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi câu]]. ==={{section|ref}}=== * {{R:VOV}}”
2573113
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi câu]].
==={{section|ref}}===
* {{R:VOV}}
q1r5xcg853bmy4pe3aw0lkg2g8ublum
ḥnkyt
0
421243
2573114
2026-10-24T04:34:24Z
Hiyuune
50834
Trang mới: “=={{langname|egy}}== ==={{section|pron}}=== {{egy-pr}} ==={{section|n}}=== {{egy-noun|f|head=H-Hn:n-k:i*i-t:D41-S28-Z1}} # [[giường]]. ===={{section|infl}}==== {{egy-decl-noun|g=f|f=ḥnky}} ===={{section|syn}}==== * {{l|egy|ꜣṯt}} ==={{section|ref}}=== * {{R:egy:Hoch|116}} {{C|egy|Vật dụng nội thất}}”
2573114
wikitext
text/x-wiki
=={{langname|egy}}==
==={{section|pron}}===
{{egy-pr}}
==={{section|n}}===
{{egy-noun|f|head=H-Hn:n-k:i*i-t:D41-S28-Z1}}
# [[giường]].
===={{section|infl}}====
{{egy-decl-noun|g=f|f=ḥnky}}
===={{section|syn}}====
* {{l|egy|ꜣṯt}}
==={{section|ref}}===
* {{R:egy:Hoch|116}}
{{C|egy|Vật dụng nội thất}}
8ihmogu6voonsju5up5kk3ho3b960b4
nêk pơchoh
0
421244
2573115
2026-10-24T04:36:45Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi cày]]. #:{{ux|sed|rôe ''''nêk pơchoh''' vâ pêi chiâk|Mua '''lưỡi cày''' để làm rẫy}} ==={{section|ref}}=== * {{R:VOV}} {{c|sed|Dụng cụ nông nghiệp}}”
2573115
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi cày]].
#:{{ux|sed|rôe ''''nêk pơchoh''' vâ pêi chiâk|Mua '''lưỡi cày''' để làm rẫy}}
==={{section|ref}}===
* {{R:VOV}}
{{c|sed|Dụng cụ nông nghiệp}}
3f3xu0asejcn0f4sbzfeuyyu89li5l3
Thể loại:sed:Dụng cụ nông nghiệp
14
421245
2573116
2026-10-24T04:36:54Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573116
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
plá chăng
0
421246
2573117
2026-10-24T04:37:25Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]] [[dao]]. ==={{section|ref}}=== * {{R:VOV}}”
2573117
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao]].
==={{section|ref}}===
* {{R:VOV}}
31r7k5wur12fl0en5gl9bhxxauy9fan
plá hơkê
0
421247
2573118
2026-10-24T04:38:20Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]] [[dao]]. #:{{ux|sed|'''plá hơkê''' chi hlá mơ-éa|'''Lưỡi dao''' rọc giấy}} ==={{section|ref}}=== * {{R:VOV}}”
2573118
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao]].
#:{{ux|sed|'''plá hơkê''' chi hlá mơ-éa|'''Lưỡi dao''' rọc giấy}}
==={{section|ref}}===
* {{R:VOV}}
6uo4j3l8ce0qip6i9x7gswg5abq00hz
plá hơlong
0
421248
2573119
2026-10-24T04:38:22Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]] [[dao]]. ==={{section|ref}}=== * {{R:VOV}}”
2573119
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao]].
==={{section|ref}}===
* {{R:VOV}}
31r7k5wur12fl0en5gl9bhxxauy9fan
plá drê
0
421249
2573120
2026-10-24T04:38:40Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]] [[dao]]. ==={{section|ref}}=== * {{R:VOV}}”
2573120
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao]].
==={{section|ref}}===
* {{R:VOV}}
31r7k5wur12fl0en5gl9bhxxauy9fan
plá vok
0
421250
2573121
2026-10-24T04:38:42Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi]] [[dao]]. ==={{section|ref}}=== * {{R:VOV}}”
2573121
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi]] [[dao]].
==={{section|ref}}===
* {{R:VOV}}
31r7k5wur12fl0en5gl9bhxxauy9fan
Thể loại:sed:Ai Cập
14
421251
2573122
2026-10-24T04:39:37Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573122
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Quốc gia của châu Phi
14
421252
2573123
2026-10-24T04:39:46Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573123
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:sed:Châu Phi
14
421253
2573124
2026-10-24T04:40:06Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573124
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
鶡雞
0
421254
2573125
2026-10-24T04:42:47Z
Hiyuune
50834
Trang mới: “=={{langname|zh}}== {{zh-forms|s=鹖鸡}} {{wp|zh:}} ==={{section|pron}}=== {{zh-pron |m=héjī |cat=n }} ==={{section|n}}=== {{head|zh|Danh từ}} # {{w|Trĩ nâu}} ({{taxfmt|Crossoptilon mantchuricum|loài}}). ===={{section|syn}}==== * {{zh-l|褐馬雞}}”
2573125
wikitext
text/x-wiki
=={{langname|zh}}==
{{zh-forms|s=鹖鸡}}
{{wp|zh:}}
==={{section|pron}}===
{{zh-pron
|m=héjī
|cat=n
}}
==={{section|n}}===
{{head|zh|Danh từ}}
# {{w|Trĩ nâu}} ({{taxfmt|Crossoptilon mantchuricum|loài}}).
===={{section|syn}}====
* {{zh-l|褐馬雞}}
ffcinz5do0fw25mtdict6pulm0ez9pi
鶡鷄
0
421255
2573126
2026-10-24T04:43:15Z
Hiyuune
50834
Trang mới: “=={{langname|zh}}== {{zh-see|鶡雞}}”
2573126
wikitext
text/x-wiki
=={{langname|zh}}==
{{zh-see|鶡雞}}
np8iu68pnbbswzy54evixt6prkri943
鹖鸡
0
421256
2573128
2026-10-24T04:43:35Z
Hiyuune
50834
Trang mới: “=={{langname|zh}}== {{zh-see|鶡雞}}”
2573128
wikitext
text/x-wiki
=={{langname|zh}}==
{{zh-see|鶡雞}}
np8iu68pnbbswzy54evixt6prkri943
rơpê rơvŏng hlŭm
0
421257
2573129
2026-10-24T04:46:24Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi gà]]. #:{{ux|sed|pôa A Hun dế pro '''rơpê rơvŏng hlŭm'''|ông A Hun đang làm '''lưỡi gà''' cho cây sáo}} ==={{section|ref}}=== * {{R:VOV}}”
2573129
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi gà]].
#:{{ux|sed|pôa A Hun dế pro '''rơpê rơvŏng hlŭm'''|ông A Hun đang làm '''lưỡi gà''' cho cây sáo}}
==={{section|ref}}===
* {{R:VOV}}
i0cuwvrakvyrvu7z8i3wspc2w6e4tiw
hnêa pháu
0
421258
2573130
2026-10-24T04:48:57Z
WhoAlone
40420
Trang mới: “=={{langname|sed}}== ==={{section|noun}}=== {{head|sed|Danh từ}} # [[lưỡi lê]]. #:{{ux|sed|pháu tâ răng ƀă krâ '''hnêa pháu'''|Súng nạp đạn và cắm '''lưỡi lê'''}} ==={{section|ref}}=== * {{R:VOV}}”
2573130
wikitext
text/x-wiki
=={{langname|sed}}==
==={{section|noun}}===
{{head|sed|Danh từ}}
# [[lưỡi lê]].
#:{{ux|sed|pháu tâ răng ƀă krâ '''hnêa pháu'''|Súng nạp đạn và cắm '''lưỡi lê'''}}
==={{section|ref}}===
* {{R:VOV}}
fy26m1xfnyfkatudi960ivbyecmw4c8
Thể loại:uum:Răng
14
421259
2573132
2026-10-24T04:50:45Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573132
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:uum:Miệng
14
421260
2573133
2026-10-24T04:51:00Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573133
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:uum:Khuôn mặt
14
421261
2573134
2026-10-24T04:51:14Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573134
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:uum:Đầu và cổ
14
421262
2573135
2026-10-24T04:51:45Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573135
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:uum:Bộ phận cơ thể
14
421263
2573136
2026-10-24T04:52:34Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573136
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:uum:Cơ thể
14
421264
2573137
2026-10-24T04:52:42Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573137
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:qxq:Răng
14
421265
2573140
2026-10-24T04:53:48Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573140
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Răng
14
421266
2573141
2026-10-24T04:53:51Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573141
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Miệng
14
421267
2573142
2026-10-24T04:54:00Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573142
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:qxq:Miệng
14
421268
2573143
2026-10-24T04:54:33Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573143
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Khuôn mặt
14
421269
2573144
2026-10-24T04:54:35Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573144
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:qxq:Khuôn mặt
14
421270
2573145
2026-10-24T04:55:24Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573145
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Đầu và cổ
14
421271
2573146
2026-10-24T04:55:27Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573146
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Bộ phận cơ thể
14
421272
2573147
2026-10-24T04:55:35Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573147
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:qxq:Đầu và cổ
14
421273
2573148
2026-10-24T04:55:37Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573148
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Từ tái tạo:Tiếng Ấn-Âu nguyên thủy/-h₂
0
421274
2573149
2026-10-24T04:55:46Z
Hiyuune
50834
Trang mới: “{{reconstructed}} =={{langname|ine-pro}}== {{etymon|ine-pro|id=danh từ tập hợp|pos=suffix}} ==={{section|suffix}}=== {{head|ine-pro|Hậu tố|head=*(é)-(o)-h₂|g=n}} # {{non-gloss|Tạo danh từ tập hợp, thường mang nghĩa đề cập đến nhóm hoặc tập hợp.}} ===={{section|infl}}==== {{ine-decl-noun-n|ac=amphikinetic|n=s|(é)-(o)-h₂|(∅)-(∅)-|loc_sg=(∅)-(é)-}} ===={{section|drv}}==== {{suffixsee|ine-pro}} * {{desc|ine-pro|*-éh₂|d…”
2573149
wikitext
text/x-wiki
{{reconstructed}}
=={{langname|ine-pro}}==
{{etymon|ine-pro|id=danh từ tập hợp|pos=suffix}}
==={{section|suffix}}===
{{head|ine-pro|Hậu tố|head=*(é)-(o)-h₂|g=n}}
# {{non-gloss|Tạo danh từ tập hợp, thường mang nghĩa đề cập đến nhóm hoặc tập hợp.}}
===={{section|infl}}====
{{ine-decl-noun-n|ac=amphikinetic|n=s|(é)-(o)-h₂|(∅)-(∅)-|loc_sg=(∅)-(é)-}}
===={{section|drv}}====
{{suffixsee|ine-pro}}
* {{desc|ine-pro|*-éh₂|der=1}}
* {{desc|ine-pro|*-ih₂|der=1}}
Hậu tố này được xem là một hậu tố mang tính biến tố của danh từ giống trung theo dạng "số tập hợp", và được thể hiện trong bảng biến tố trên Wiktionary.
[[en:Reconstruction:Proto-Indo-European/-h₂]]
p4lek18489zeh4m70sbbttrzfv733g2
2573154
2573149
2026-10-24T05:02:58Z
Hiyuune
50834
2573154
wikitext
text/x-wiki
{{reconstructed}}
=={{langname|ine-pro}}==
{{etymon|ine-pro|id=danh từ tập hợp|pos=suffix}}
==={{section|suffix}}===
{{head|ine-pro|Hậu tố|head=*(é)-(o)-h₂|g=n}}
# {{non-gloss|Tạo danh từ tập hợp, thường mang nghĩa đề cập đến nhóm hoặc tập hợp.}}
===={{section|infl}}====
{{ine-decl-noun-n|ac=amphikinetic|n=s|(é)-(o)-h₂|(∅)-(∅)-|loc_sg=(∅)-(é)-}}
===={{section|drv}}====
{{suffixsee|ine-pro}}
* {{desc|ine-pro|*-éh₂|der=1}}
* {{desc|ine-pro|*-ih₂|der=1}}
Hậu tố này được xem là một hậu tố mang tính biến tố của danh từ giống trung theo dạng "số tập hợp", và được thể hiện trong bảng biến tố Wiktionary.
[[en:Reconstruction:Proto-Indo-European/-h₂]]
3b5uwrqtd9oqk8m67ahemva90jkrid7
Thể loại:qxq:Bộ phận cơ thể
14
421275
2573150
2026-10-24T04:55:47Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573150
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Cơ thể
14
421276
2573151
2026-10-24T04:55:48Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573151
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:gag:Danh sách chủ đề thuộc nhóm tập hợp
14
421277
2573152
2026-10-24T04:55:51Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573152
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
Thể loại:qxq:Cơ thể
14
421278
2573153
2026-10-24T04:55:57Z
WhoAlone
40420
Trang mới: “{{auto cat}}”
2573153
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
ёрзающий
0
421279
2573160
2026-10-24T08:04:30Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{ĐM|pron}}=== * {{ru-IPA}} ==={{ĐM|ptcp}}=== {{head|ru|Phân từ hiện tại chủ động}} # {{participle of|ru|ёрзать||impfv|pres|act}} ===={{ĐM|decl}}==== {{ru-decl-adj|ёрзающий|-}}”
2573160
wikitext
text/x-wiki
=={{langname|ru}}==
==={{ĐM|pron}}===
* {{ru-IPA}}
==={{ĐM|ptcp}}===
{{head|ru|Phân từ hiện tại chủ động}}
# {{participle of|ru|ёрзать||impfv|pres|act}}
===={{ĐM|decl}}====
{{ru-decl-adj|ёрзающий|-}}
alkdtb7qw1jexufk6pus816im4wdnc6
ёрзавший
0
421280
2573161
2026-10-24T08:05:28Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{ĐM|pron}}=== * {{ru-IPA}} ==={{ĐM|ptcp}}=== {{head|ru|Phân từ quá khứ chủ động}} # {{participle of|ru|ёрзать||impfv|past|act}} ===={{ĐM|decl}}==== {{ru-decl-adj|ёрзавший|-}}”
2573161
wikitext
text/x-wiki
=={{langname|ru}}==
==={{ĐM|pron}}===
* {{ru-IPA}}
==={{ĐM|ptcp}}===
{{head|ru|Phân từ quá khứ chủ động}}
# {{participle of|ru|ёрзать||impfv|past|act}}
===={{ĐM|decl}}====
{{ru-decl-adj|ёрзавший|-}}
aynb092e3gskrtc8ww0s3zq1xort45f
ёрзаю
0
421281
2573163
2026-10-24T08:08:02Z
Hiyuune
50834
+ ru
2573163
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|1|s}}
k5f12nucila44jryewqchj7pkbluk0v
ёрзаешь
0
421282
2573164
2026-10-24T08:10:15Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{section|pron}}=== * {{ru-IPA}} ==={{section|v}}=== {{head|ru|Biến thể hình thái động từ}} # {{inflection of|ru|ёрзать||ind|impfv|pres|ở|2|s}}”
2573164
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|2|s}}
ovjhqppyr7nka67pmgp7z58smlyfv84
ёрзает
0
421283
2573165
2026-10-24T08:11:18Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{section|pron}}=== * {{ru-IPA}} ==={{section|v}}=== {{head|ru|Biến thể hình thái động từ}} # {{inflection of|ru|ёрзать||ind|impfv|pres|ở|3|s}}”
2573165
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|3|s}}
oilw6lzi0h0z5v3dpq8sgnikxutd21n
ёрзаем
0
421284
2573166
2026-10-24T08:14:16Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{section|v}}=== * {{ru-IPA}} ==={{section|v}}=== {{head|ru|Biến thể hình thái động từ}} # {{inflection of|ru|ёрзать||ind|impfv|pres|ở|1|p}}”
2573166
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|v}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|1|p}}
3ede0wkv5x04qhnld8b02d60n6wmssx
ёрзаете
0
421285
2573167
2026-10-24T08:14:44Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{section|v}}=== * {{ru-IPA}} ==={{section|v}}=== {{head|ru|Biến thể hình thái động từ}} # {{inflection of|ru|ёрзать||ind|impfv|pres|ở|2|p}}”
2573167
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|v}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|2|p}}
r4q7a9494u7hz57bj07suteb58id7o5
ёрзают
0
421286
2573168
2026-10-24T08:14:51Z
Hiyuune
50834
Trang mới: “=={{langname|ru}}== ==={{section|v}}=== * {{ru-IPA}} ==={{section|v}}=== {{head|ru|Biến thể hình thái động từ}} # {{inflection of|ru|ёрзать||ind|impfv|pres|ở|3|p}}”
2573168
wikitext
text/x-wiki
=={{langname|ru}}==
==={{section|v}}===
* {{ru-IPA}}
==={{section|v}}===
{{head|ru|Biến thể hình thái động từ}}
# {{inflection of|ru|ёрзать||ind|impfv|pres|ở|3|p}}
7dk8l1y2icas9l5z46gs954vm86qdq7
Bản mẫu:R:ru:Dal
10
421287
2573171
2026-10-24T08:21:01Z
Hiyuune
50834
Trang mới: “{{#invoke:checkparams|error}}<!-- Validate template parameters -->{{cite-book<!-- -->|ru<!-- -->|last=Dal<!-- -->|first=Vladimir<!-- -->|authorlink=Vladimir Dal<!-- -->|title=w:en:Explanatory Dictionary of the Living Great Russian Language|<!-- -->{{#switch:{{{e|2}}}|<!-- -->|1=Толковый Словарь Живаго Великорускаго Языка<!-- -->|2=Толковый Словарь живаго великорускаго языка<!-- -->…”
2573171
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{cite-book<!--
-->|ru<!--
-->|last=Dal<!--
-->|first=Vladimir<!--
-->|authorlink=Vladimir Dal<!--
-->|title=[[w:en:Explanatory Dictionary of the Living Great Russian Language|<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=Толковый Словарь Живаго Великорускаго Языка<!--
-->|2=Толковый Словарь живаго великорускаго языка<!--
-->|3=Толковый Словарь живого великорусскаго языка<!--
-->|#default=Толковый словарь живого великорусского языка<!--
-->}}]]<!--
-->|edition={{#switch:{{{e|2}}}|1=1|2=2|3=3}}<!--
-->|year=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1={{#switch:{{{3|{{{vol|}}}}}}|1=1863|2=1865|3=1865|4=1866|#default=1863–1866}}<!--
-->|2={{#switch:{{{3|{{{vol|}}}}}}|1=1880|2=1881|3=1882|4=1882|#default=1880–1882}}<!--
-->|3={{#switch:{{{3|{{{vol|}}}}}}|1=1903|2=1905|3=1907|4=1909|#default=1903–1909}}<!--
-->}}<!--
-->|location=<!--Saint Petersburg, Moscow--><!--
-->|publisher=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=<!-- типографія: 1 а. семена, 23 лазаревскаго института восточныхъ языковъ (а. мамонтовъ), 4 т. рисъ
-->|2=Publication of the bookseller-typographer [[w:ru:Вольф, Маврикий Осипович|Wolf, M. O.]]<!--{{xlit|ru|Издание книгопродавца-типографа М.О. Вольфа}}--><!--
-->|3=[[w:ru:Вольф (издательство)|товарищество М. О. Вольфъ]]<!--
-->}}<!--
-->|volume={{{3|}}}<!--
-->|page={{{2|{{{page|}}}}}}<!--
-->|pageurl=https://books.google.com/books?id=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1={{#switch:{{{3|{{{vol|1}}}}}}|1=R91bAAAAcAAJ|2=kt1bAAAAcAAJ|3=ctxbAAAAcAAJ|4=ed1bAAAAcAAJ}}<!--
-->|2={{#switch:{{{3|{{{vol|1}}}}}}|1=JO8GAAAAQAAJ|2=8TlJDuNqbB8C|3=pO8GAAAAQAAJ|4=2O8GAAAAQAAJ}}<!--
-->|3={{#switch:{{{3|{{{vol|1}}}}}}|1=YAM4AQAAMAAJ|2=C2E5AQAAMAAJ|3=bOlOAQAAIAAJ|4=reFOAQAAIAAJ}}<!--
-->}}&pg=PA{{{2|{{{page|}}}}}}&dq={{urlencode:{{{1|}}} {{{passage|}}}|QUERY}}<!--
-->|entry={{lang|ru|{{#if: {{{e|}}}|{{{1|{{pagename}}}}}|[[s:ru:ТСД2/{{ucfirst:{{{1|{{pagename}}}}}}}|{{{1|{{pagename}}}}}]]}}}}<!--
-->|entryurl=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=<!--
-->|2=<!--
-->|3=https://viewer.rusneb.ru/ru/rsl0100397223{{#switch:{{{3|{{{vol|1}}}}}}|1=5|2=4|3=3|4=2}}?page={{#expr:ceil({{{2|{{{page|1}}}}}}/2)+{{#switch:{{{3|{{{vol|1}}}}}}|1={{#ifexpr:{{{2|{{{page|1}}}}}}<740|17|16}}|2=3|3=3|4=4}}}}<!-- missing p739+740 in vol1
-->}}<!--
-->|passage={{{passage|}}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
8xzjgqj13uh207ucs0libuink6g6ezh
2573191
2573171
2026-10-24T09:26:49Z
TheHighFighter2
42988
/* */
2573191
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{cite-book<!--
-->|ru<!--
-->|last=Dal<!--
-->|first=Vladimir<!--
-->|authorlink=Vladimir Dal<!--
-->|title=[[w:en:Explanatory Dictionary of the Living Great Russian Language|<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=Толковый Словарь Живаго Великорускаго Языка<!--
-->|2=Толковый Словарь живаго великорускаго языка<!--
-->|3=Толковый Словарь живого великорусскаго языка<!--
-->|#default=Толковый словарь живого великорусского языка<!--
-->}}]]<!--
-->|edition={{#switch:{{{e|2}}}|1=1|2=2|3=3}}<!--
-->|year=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1={{#switch:{{{3|{{{vol|}}}}}}|1=1863|2=1865|3=1865|4=1866|#default=1863–1866}}<!--
-->|2={{#switch:{{{3|{{{vol|}}}}}}|1=1880|2=1881|3=1882|4=1882|#default=1880–1882}}<!--
-->|3={{#switch:{{{3|{{{vol|}}}}}}|1=1903|2=1905|3=1907|4=1909|#default=1903–1909}}<!--
-->}}<!--
-->|location=<!--Saint Petersburg, Moscow--><!--
-->|publisher=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=<!-- типографія: 1 а. семена, 23 лазаревскаго института восточныхъ языковъ (а. мамонтовъ), 4 т. рисъ
-->|2=Ấn phẩm của nhà sách kiêm thợ sắp chữ [[w:ru:Вольф, Маврикий Осипович|Wolf, M. O.]]<!--{{xlit|ru|Издание книгопродавца-типографа М.О. Вольфа}}--><!--
-->|3=[[w:ru:Вольф (издательство)|товарищество М. О. Вольфъ]]<!--
-->}}<!--
-->|volume={{{3|}}}<!--
-->|page={{{2|{{{page|}}}}}}<!--
-->|pageurl=https://books.google.com/books?id=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1={{#switch:{{{3|{{{vol|1}}}}}}|1=R91bAAAAcAAJ|2=kt1bAAAAcAAJ|3=ctxbAAAAcAAJ|4=ed1bAAAAcAAJ}}<!--
-->|2={{#switch:{{{3|{{{vol|1}}}}}}|1=JO8GAAAAQAAJ|2=8TlJDuNqbB8C|3=pO8GAAAAQAAJ|4=2O8GAAAAQAAJ}}<!--
-->|3={{#switch:{{{3|{{{vol|1}}}}}}|1=YAM4AQAAMAAJ|2=C2E5AQAAMAAJ|3=bOlOAQAAIAAJ|4=reFOAQAAIAAJ}}<!--
-->}}&pg=PA{{{2|{{{page|}}}}}}&dq={{urlencode:{{{1|}}} {{{passage|}}}|QUERY}}<!--
-->|entry={{lang|ru|{{#if: {{{e|}}}|{{{1|{{pagename}}}}}|[[s:ru:ТСД2/{{ucfirst:{{{1|{{pagename}}}}}}}|{{{1|{{pagename}}}}}]]}}}}<!--
-->|entryurl=<!--
-->{{#switch:{{{e|2}}}|<!--
-->|1=<!--
-->|2=<!--
-->|3=https://viewer.rusneb.ru/ru/rsl0100397223{{#switch:{{{3|{{{vol|1}}}}}}|1=5|2=4|3=3|4=2}}?page={{#expr:ceil({{{2|{{{page|1}}}}}}/2)+{{#switch:{{{3|{{{vol|1}}}}}}|1={{#ifexpr:{{{2|{{{page|1}}}}}}<740|17|16}}|2=3|3=3|4=4}}}}<!-- missing p739+740 in vol1
-->}}<!--
-->|passage={{{passage|}}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
ctq797jrowus4sbrs0x1acui6xbzn6j
Bản mẫu:R:ru:Dal/doc
10
421288
2573172
2026-10-24T08:24:13Z
Hiyuune
50834
Trang mới: “{{documentation subpage}} ==Tham số== * {{para|1}} Mục từ (ví dụ: лава) * {{para|2}} Số trang (ví dụ: 1, 10, 100) * {{para|3}} Ấn bản (1, 2, 3, 4) * {{para|e}} Phiên bản (1, 2, 3) ==Ví dụ== * <code><nowiki>{{R:ru:Dahl|веверица}}</nowiki></code> : {{R:ru:Dahl|веверица}} * <code><nowiki>{{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёрка}}</nowiki></code> : {{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёр…”
2573172
wikitext
text/x-wiki
{{documentation subpage}}
==Tham số==
* {{para|1}} Mục từ (ví dụ: лава)
* {{para|2}} Số trang (ví dụ: 1, 10, 100)
* {{para|3}} Ấn bản (1, 2, 3, 4)
* {{para|e}} Phiên bản (1, 2, 3)
==Ví dụ==
* <code><nowiki>{{R:ru:Dahl|веверица}}</nowiki></code>
: {{R:ru:Dahl|веверица}}
* <code><nowiki>{{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёрка}}</nowiki></code>
: {{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёрка}}
* <code><nowiki>{{R:ru:Dahl|мѣсить|965|2|e=3|passage=мѣсила}}</nowiki></code>
: {{R:ru:Dahl|мѣсить|965|2|e=3|passage=мѣсила}}
<includeonly>{{refcat}}
[[Thể loại:Bản mẫu tham khảo từ điển tiếng Nga]]
</includeonly>
ss3o2xhkuey1va386wr0amrc12vlcms
2573174
2573172
2026-10-24T08:25:04Z
Hiyuune
50834
2573174
wikitext
text/x-wiki
{{documentation subpage}}
==Tham số==
* {{para|1}} Mục từ (ví dụ: лава)
* {{para|2}} Số trang (ví dụ: 1, 10, 100)
* {{para|3}} Số tập (1, 2, 3, 4)
* {{para|e}} Phiên bản (1, 2, 3)
==Ví dụ==
* <code><nowiki>{{R:ru:Dahl|веверица}}</nowiki></code>
: {{R:ru:Dahl|веверица}}
* <code><nowiki>{{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёрка}}</nowiki></code>
: {{R:ru:Dahl|ве́верица|428|1|e=3|passage=вевёрка}}
* <code><nowiki>{{R:ru:Dahl|мѣсить|965|2|e=3|passage=мѣсила}}</nowiki></code>
: {{R:ru:Dahl|мѣсить|965|2|e=3|passage=мѣсила}}
<includeonly>{{refcat}}
[[Thể loại:Bản mẫu tham khảo từ điển tiếng Nga]]
</includeonly>
q4yhb4jaiyhyqjj48yadmv1w077fzzc
Bản mẫu:R:ru:Dahl
10
421289
2573173
2026-10-24T08:24:42Z
Hiyuune
50834
Đổi hướng đến [[Bản mẫu:R:ru:Dal]]
2573173
wikitext
text/x-wiki
#redirect [[Bản mẫu:R:ru:Dal]]
cvdtr45mm6g30bz068q8d9weidoq5au
поёжиться
0
421290
2573179
2026-10-24T08:36:24Z
Hiyuune
50834
Trang mới: “{{also|поежиться}} =={{langname|ru}}== ==={{section|etym}}=== {{af|ru|по-|ёжиться}} ==={{section|pron}}=== * {{ru-IPA}} ==={{section|v}}=== {{ru-verb|поёжиться|pf|impf=поёживаться}} # [[run|Run]], [[rùng mình]]. ===={{section|forms}}==== {{ru-conj|pf|4a|поёжиться}} ===={{section|rel}}==== * {{l|ru|ёжиться|g=impf}}, {{l|ru|съёжиться|g=pf}}”
2573179
wikitext
text/x-wiki
{{also|поежиться}}
=={{langname|ru}}==
==={{section|etym}}===
{{af|ru|по-|ёжиться}}
==={{section|pron}}===
* {{ru-IPA}}
==={{section|v}}===
{{ru-verb|поёжиться|pf|impf=поёживаться}}
# [[run|Run]], [[rùng mình]].
===={{section|forms}}====
{{ru-conj|pf|4a|поёжиться}}
===={{section|rel}}====
* {{l|ru|ёжиться|g=impf}}, {{l|ru|съёжиться|g=pf}}
8zju3344c5y7aargsh2oxq6r72ssb5d
बन्दर
0
421291
2573180
2026-10-24T08:40:10Z
Hiyuune
50834
Trang mới: “=={{langname|hi}}== ==={{section|n}}=== {{hi-noun|m}} # {{alt sp|hi|बंदर}} ===={{section|decl}}==== {{hi-ndecl|<M>}}”
2573180
wikitext
text/x-wiki
=={{langname|hi}}==
==={{section|n}}===
{{hi-noun|m}}
# {{alt sp|hi|बंदर}}
===={{section|decl}}====
{{hi-ndecl|<M>}}
tgqnfdaay6pb55kmfpzn9g3kn2r4uvs
pagsisipam-
0
421292
2573182
2026-10-24T08:58:56Z
Hiyuune
50834
+ tl
2573182
wikitext
text/x-wiki
=={{langname|tl}}==
==={{section|etym}}===
{{ety|tl|pagsisipang-|:af<surf>|pagsisi-|pam-|text=+|tree=1}}
==={{section|pron}}===
{{tl-pr|pagsísipám-}}
==={{section|prefix}}===
{{tl-head|Biến thể hình thái tiền tố|pagsísipám-|b=+}}
# {{alt form|tl|pagsisipang-}}
===={{section|drv}}====
{{prefixsee|tl}}
9g0rcsjhkb1bw90q1ogv3iiaozbvkwp
ຄນະ
0
421293
2573183
2026-10-24T08:59:54Z
Hiyuune
50834
Trang mới: “=={{langname|lo}}== ==={{section|pron}}=== {{lo-pron|ຄະ-ນະ}} ==={{section|n}}=== {{lo-noun}} # {{obsolete spelling of|lo|ຄະນະ}}”
2573183
wikitext
text/x-wiki
=={{langname|lo}}==
==={{section|pron}}===
{{lo-pron|ຄະ-ນະ}}
==={{section|n}}===
{{lo-noun}}
# {{obsolete spelling of|lo|ຄະນະ}}
6ybjwec68uetg3273kqxlq30cnj8xl3
Mô đun:bibliography/data/scn
828
421294
2573184
2026-10-24T09:00:40Z
Hiyuune
50834
+ scn
2573184
Scribunto
text/plain
local data = {}
data.sources = {
["Rohlfs:1977"] = {
year = "1977",
author = "|Rohlfs, Gerhard",
title = "Nuovo dizionario dialettale della Calabria (con repertorio italo-calabro). Nuova edizione interamente rielaborata, ampliata ed aggiornata",
location = "Ravenna",
publisher = "A. Longo",
}
}
return data
736jtoy1q0sabyeq7bmspod3m6i367i
gunna-froise
0
421295
2573185
2026-10-24T09:01:56Z
Hiyuune
50834
+ gd
2573185
wikitext
text/x-wiki
=={{langname|gd}}==
==={{section|etym}}===
Từ {{af|gd|gunna|froise}}, {{calque|gd|en|shotgun|nocap=1}}.
==={{section|n}}===
{{gd-noun|m|~|gunnaichean-froise}}
# [[súng ngắn|Súng ngắn]], [[súng săn]].
==={{section|mut}}===
{{gd-mut}}
==={{section|further}}===
* {{R:Dwelly}}
6pajfj1d71h2lgz3dh08jwx5yyf255g