विक्षनरी hiwiktionary https://hi.wiktionary.org/wiki/%E0%A4%AE%E0%A5%81%E0%A4%96%E0%A4%AA%E0%A5%83%E0%A4%B7%E0%A5%8D%E0%A4%A0 MediaWiki 1.47.0-wmf.20 case-sensitive मीडिया विशेष वार्ता सदस्य सदस्य वार्ता विक्षनरी विक्षनरी वार्ता चित्र चित्र वार्ता मीडियाविकि मीडियाविकि वार्ता साँचा साँचा वार्ता सहायता सहायता वार्ता श्रेणी श्रेणी वार्ता TimedText TimedText talk मॉड्यूल मॉड्यूल वार्ता Event Event talk असमिया 0 978 489338 487733 2026-09-22T18:11:01Z SM7 6218 शब्दसागर की एंट्री इस शीर्षक से नहीं है [[आसामी]] पर ले जाया गया 489338 wikitext text/x-wiki ==हिंदी== {{-noun-}} स्त्री. # [[भारत]] की [[भाषा]] हैं । # [[व्यक्ति]] {{-trans-}} * {{as}} : [[অসমিয়া]] * {{de}} : [[Assami]] * {{en}} : [[Assamese]] [[:en:Assamese]] * {{fr}} : [[assamais]] पु. [[:fr:assamais]] (१), [[Assamais]] पु. [[:fr:Assamais]] (२) * {{gu}} : [[આસામી]] स्त्री. [[:gu:આસામી]] * {{nl}} : [[Assamitisch]] न. [[:nl:Assamitisch]] * {{zh}} : [[阿萨密语]] {{-adj-}} # {{-trans-}} * {{en}} : [[Assamese]] * {{fr}} : [[assamais]] पु., [[assamaise]] स्त्री. [[:fr:assamaise]] * {{gu}} : [[આસામી]] [[श्रेणी:भाषाएँ]] jr0q0l56oj6aoktyr9tnqaz0r0ety08 जर्मनी 0 1142 489346 480683 2026-09-22T18:35:38Z SM7 6218 सुधार 489346 wikitext text/x-wiki {{also|जर्मन|जरमन}} == हिन्दी == {{विकिपीडिया}} [[चित्र:States of Germany.svg |thumb|right|220px|जर्मनी देश का मानचित्र]] === उच्चारण === {{audio|hi|LL-Q1571 (mar)-Manjusha Gore-जर्मनी.wav}} === नामवाचक संज्ञा === # [[मध्य यूरोप]] में स्थित एक देश; [[द्वितीय विश्व युद्ध]] के पश्चात [[पूर्वी जर्मनी]] और [[पश्चिमी जर्मनी]] में विभाजित और १९९० में एकीकृत। आधिकारिक नाम: जर्मन संघीय गणराज्य (''[[:de:Bundesrepublik Deutschland|Bundesrepublik Deutschland]]'') ===अनुवाद=== * {{de}} : [[Deutschland]] [[:de:Deutschland]] * {{en}} : [[Germany]] [[:en:Germany]] * {{fr}} : [[Allemagne]] [[:fr:Allemagne]] * {{gu}} : [[જર્મની]] [[:gu:જર્મની]] <!--* {{lb}} : [[Däitschland]] साँचा:lb लेबल पर --> <!--* {{nds}} : [[Düütschland]] [[:nds:Düütschland]]--> * {{nl}} : [[Duitsland]] [[:nl:Duitsland]] ==भोजपुरी== {{wikipedia|lang=bh}} === नामवाचक संज्ञा === {{bho-proper noun}} # {{place|bho|देश|r/मध्य यूरोप|t=जर्मनी}} ==मराठी== {{विकिपीडिया|mr:}} ===नामवाचक संज्ञा=== # [[#हिन्दी|जर्मनी]] g1c8lpzkjga5x7fpiyk8d0jqgy8utrq 489347 489346 2026-09-22T18:37:24Z SM7 6218 सुधार 489347 wikitext text/x-wiki {{also|जर्मन|जरमन}} == हिन्दी == {{विकिपीडिया}} [[चित्र:States of Germany.svg |thumb|right|220px|जर्मनी देश का मानचित्र]] === उच्चारण === {{audio|hi|LL-Q1571 (mar)-Manjusha Gore-जर्मनी.wav}} === नामवाचक संज्ञा === # [[मध्य यूरोप]] में स्थित एक देश; [[द्वितीय विश्व युद्ध]] के पश्चात [[पूर्वी जर्मनी]] और [[पश्चिमी जर्मनी]] में विभाजित और १९९० में एकीकृत। आधिकारिक नाम: जर्मन संघीय गणराज्य (''[[:de:Bundesrepublik Deutschland|Bundesrepublik Deutschland]]'') ===अनुवाद=== * {{de}} : [[Deutschland]] [[:de:Deutschland]] * {{en}} : [[Germany]] [[:en:Germany]] * {{fr}} : [[Allemagne]] [[:fr:Allemagne]] * {{gu}} : [[જર્મની]] [[:gu:જર્મની]] <!--* {{lb}} : [[Däitschland]] साँचा:lb लेबल पर --> <!--* {{nds}} : [[Düütschland]] [[:nds:Düütschland]]--> * {{nl}} : [[Duitsland]] [[:nl:Duitsland]] ==भोजपुरी== {{wikipedia|lang=bh}} === नामवाचक संज्ञा === {{bho-proper noun|g=m}} # {{place|bho|देश|r/मध्य यूरोप|t=जर्मनी}} ==मराठी== {{विकिपीडिया|mr:}} ===नामवाचक संज्ञा=== # [[#हिन्दी|जर्मनी]] ntqlxtusdkn0p163v2fakn46ewlnmq5 मॉड्यूल:place 828 304308 489342 477895 2026-09-22T18:28:01Z SM7 6218 updating... 489342 Scribunto text/plain local export = {} local force_cat = false -- set to true for testing local m_placetypes = require("Module:place/placetypes") local m_links = require("Module:links") local memoize = require("Module:memoize") local m_strutils = require("Module:string utilities") local m_table = require("Module:table") local debug_track_module = "Module:debug/track" local en_utilities_module = "Module:en-utilities" local form_of_module = "Module:form of" local languages_module = "Module:languages" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local parameter_utilities_module = "Module:parameter utilities" local utilities_module = "Module:utilities" local enlang = require(languages_module).getByCode("en") local rmatch = m_strutils.match local rfind = m_strutils.find local split = m_strutils.split local dump = mw.dumpObject local insert = table.insert local concat = table.concat local pluralize = require(en_utilities_module).pluralize local extend = m_table.extend local unpack = unpack or table.unpack -- Lua 5.2 compatibility local internal_error = m_placetypes.internal_error local placetype_data = m_placetypes.placetype_data --[==[ intro: ===Introduction=== This module implements {{tl|place}}, which is a template for standardizing the description and categorization of toponyms (terms that refer to locations such as cities, countries, rivers, etc.). The following modules support this template: * [[Module:place]]: The main module. * [[Module:place/placetypes]]: A module containing data on placetypes, as well as utilities for working with placetypes; category generation handlers for adding categories based on placetypes; and display handlers for displaying holonyms (i.e. containing locations) of a specific type. FIXME: Maybe split out the code from the data. * [[Module:place/locations]]: A module containing data on known locations, as well as utilities for working with such locations. FIXME: Maybe split out the code from the data. * [[Module:category tree/topic/Places]]: A category tree module for generating the descriptions of all categories generated by {{tl|place}}. * [[Module:place doc]]: A module that generates documentation tables describing known placetypes and locations. ===Basic terminology=== The basic terminology used in this and associated {{tl|place}} modules is: * A ''location'' (or equivalently, a ''place'') is any geographic feature (either natural or geopolitical), either on the surface of the Earth or elsewhere. Examples of types of natural places are rivers, mountains, seas and moons; examples of types of geopolitical places are cities, countries, neighborhoods and roads. A ''known location'' is specifically a location whose properties are specified in the {{tl|place}} modules; more on them below. * Specific places are identified by names, referred to as ''toponyms'' or ''placenames''. A given place will often have multiple names, and a given toponym may be ambiguous, referring to multiple possible locations. Specifically: ** There may be names including different amounts of disambiguating information (`Tucson` vs. `Tucson, Arizona` vs. `Tucson, Arizona, USA` or `New York` vs. `New York City` vs. `New York, New York`); abbreviations (`NYC` for `New York City`, `USA` for `United States of America`); ''official'' vs. ''short'' names (e.g. `Union of Soviet Socialist Republics` vs. `Soviet Union`); spelling variations (`Cracow` vs. `Krakow` vs. `Kraków`); current vs. former names (`Saint Petersburg` vs. `Leningrad` vs. `Petrograd`); [[exonym]]s vs. [[endonym]]s (e.g. `Tavastia Proper` vs. `Kanta-Häme`, both referring to the same administrative region in Finland); alternative names not due to any of the above reasons (`Bashkiria` vs. `Bashkortostan`); etc. In addition, each language that has an opportunity to refer to the place will have its own name, with the same sorts of variations as exist in English. ** Examples of ambiguous toponyms are `New York` (either a city or a state); `Georgia` (either a state of the US or an independent country in the Caucasus Mountains); `Paris` (either the capital of France or various small cities and towns in the US); `Mexico` (either a country, a state of that country, or the capital city of that country); and `San Antonio` (besides being a major city in Texas, it is the name of dozens of settlements of all sorts throughout the US and Latin America, and a least 181 distinct [[barangay]]s in the Philippines). * A ''placetype'' is the (or a) type that a location belongs to (e.g. `city`, `state`, `river`, `administrative region`, `[[regional county municipality]]`, etc.). ** It is common for locations to be described using multiple placetypes, and even sometimes known locations have multiple placetypes that they may be identified by (e.g. American Samoa can be identified either as an `unincorporated territory`, an `overseas territory` or just a `territory`). Both the {{tl|place}} template and the known location data allow a given location to be identified by multiple placetypes. When in doubt as to the correct placetype or placetypes for a given location, generally follow how Wikipedia describes the place. ** Some placetypes themselves are ambiguous; e.g. an ''area'' can variously refer to a top-level administrative division (specifically of Kuwait); a geographic region, generally without unambiguously defined borders; or a section of a city, similar to a neighborhood. The term ''district'' is similarly ambiguous. A ''[[prefecture]]'' in the context of Japan is similar to a province, but a prefecture in France is the capital of a ''[[department]]'' (which is similar to a county). Some of this ambiguity is currently handled automatically; e.g. the ambiguity of areas and districts is handled by looking at the ''holonyms'', or containing locations, specified for a given place. But sometimes it is necessary to use a qualifier before the placetype to disambiguate; for example to refer to a French prefecture, use the placetype `French prefecture` instead of just `prefecture`. (FIXME: Handle this automatically.) * A ''holonym'', in the context of a description of a place, is a placename that refers to a larger-sized entity that contains the location being described. For example, `Arizona` and `United States` are holonyms of `Tucson`, and `United States` is a holonym of `Arizona`. * A ''place invocation'' consists of the invocation of {{tl|place}}, including all its parameters. Place invocations may contain one or more ''place descriptions'', each of which provides a description of the location, including its placetype or types, any holonyms, and any additional raw text needed to properly explain the place in context. Place invocations may also contain named parameters specifying zero or more English ''glosses'' or translations (for foreign-language toponyms) and any attached ''extra information'' such as the capital, largest city, official name, modern name or full name. Multiple place descriptions in a single invocation are separated by a numbered parameter starting with a semicolon, and are used when it is necessary to provide two or more definitions of a single location for proper categorization. For example, [[Vatican City]] is defined both as a city-state in Southern Europe and as an enclave within the city of Rome, follows: : {{tl|place|en|city-state|r/Southern Europe|;,|an <<enclave>> within the city of [[Rome]], [[Italy]]|cat=Places in Rome|official=Vatican City State}}. Similar things need to be done for places like [[Crimea]] that are claimed by two different countries with different definitions and administrative structures. ** There are two types of place descriptions, ''new-style'' and ''old-style''. (The use of the terms "new" and "old" indicates chronological precedence in the development of {{tl|place}}, but is not meant to pass any value judgments on the two types, and does not indicate any intent to deprecate old-style descriptions. Both types of descriptions are useful; for example, old-style descriptions are generally more succinct but less flexible.) The above invocation shows both types: an old-style description followed by a new-style description. Old style descriptions use multiple numbered parameters, where the first parameter (after the language code) specifies the placetype or types, and following parameters specify either holonyms (which are always of the form ` ``placetype``/``placename`` `) or raw text (which is identifiable by not having a slash in it). New-style descriptions use a single parameter, where both placetypes and holonyms are surrounded by double angle brackets, and all remaining text is raw (displayed as-is). In both types of descriptions, holonyms include a slash in them to separate the placetype (which is mandatory and often abbreviated) from the placename. ** In the context of a place description, there are two types of placetypes. The ''entry placetypes'' are the placetypes of the place being described, while the ''holonym placetypes'' are the placetypes of the holonyms that the place being described is located within. Currently, a given place can have multiple placetypes specified (e.g. [[Normandy]] is specified using the ''compound placetype'' `administrative region/former province/and/medieval kingdom`) while a given holonym can have only one placetype associated with it. Holonym placetypes are frequently abbreviated (e.g. `r` for `region`, `s` for `state`, `co` for `county`, etc.), while stylistically it is preferred to spell out the entry placetype (except for some long placetypes with well-known abbreviations, such as `CDP` or `cdp` for `[[census-designated place]]`). ** All holonyms in place descriptions are automatically linked as if surrounded by {{tl|l|en|...}}; i.e. if double brackets do not occur in the holonym, the entire holonym will be linked to the corresponding Wiktionary article. For this reason, the holonym should generally be in the same format as the canonical Wiktionary article describing the location; see below). * A ''known location'' is a location whose properties are specifically defined in the {{tl|place}} modules. Generally each such location has an associated category, and known locations exist in a containment hierarchy, where the immediately containing known location is known as the ''container'' of the location and the chain of successive containing locations is known as the ''container trail''. Generally the location's container corresponds to the first parent of its category. Note that some known locations belong to more than one immediate container; for example, Russia belongs to both Europe and Asia. ===More about placetypes=== # The following general categories of placetypes exist: ## ''Natural features'' such as lakes, mountains, mountain ranges, islands, archipelagoes, moons, stars, asteroids, etc. ## ''Continents'', ''supercontinents'' (groupings of continents where it makes sense, such as `America` and `Eurasia`) and ''continent-level regions'' (grouping of countries in a given continent, such as `Central America` and `Polynesia`). ## ''Political entities'', which are generally classified as either ''polities'' (top-level entities such as countries), ''subpolities'' or ''political divisions'' (non-sovereign divisions, often specifically ''administrative divisions'', of a polity, where an administrative division has a governmental or statistical function and almost always has unambiguously defined boundaries), or ''settlements'' (e.g. cities; towns; villages; and divisions of a city such as neighborhoods, wards, [[barrio]]s and [[barangay]]s, which may or may not be formal administrative divisions and may or may not have unambiguous boundaries). ## ''Geographic regions'', which refer to recognized areas of the Earth (either with a natural geographic, political or cultural significance, often of a historical nature). Such regions can be of greatly varying size, may exist either within a single country or spanning multiple countries or (more often) parts of multiple countries, and may not have well-defined boundaries. They should be distinguished from ''administrative regions'', which exist within a single country and have well-defined boundaries and a political or administrative function. Geographic regions are categorized using the generic term ''geographic and cultural areas'' to emphasize that (a) they have no administrative significance; (b) they may vary greatly in size; and (c) their cohesion is due either to natural geographic boundaries, such as rivers or mountain ranges, or to sharing some cultural characteristics. ## ''Man-made structures'' below the level of a settlement or neighborhood, such as airports, roads, individual buildings, and the like. (Note that such structures, even if named, often do not meet the [[WT:CFI]] criteria; this is particularly the case for roads.) # Placetypes support aliases, and the mapping to canonical form happens early on in the processing. For example, `state` can be abbreviated as `s`; `administrative region` as `adr`; `regional county municipality` as `rcomun`; etc. Some placetype aliases handle alternative spellings rather than abbreviations. For example, `departmental capital` maps to `department capital`, and `home-rule city` maps to `home rule city`. Placetype abbreviations are particularly useful in holonym specs, because every holonym must be accompanied by its placetype, for disambiguation purposes. # A ''placetype qualifier'' is an adjective prepended to the placetype to give additional information about the place being described. For example, a given place may be described as a `small city`; logically this is still a city, but the qualifier `small` gives additional information about the place. Multiple qualifiers can be stacked, e.g. `small affluent beachfront unincorporated community`, where `unincorporated community` is a recognized placetype and `small`, `affluent` and `beachfront` are qualifiers. (As shown here, it may not always be obvious where the qualifiers end and the placetype begins.) For the most part, placetype qualifiers do not affect categorization; a `small city` is still a city and an `affluent beachfront unincorporated community` is still an unincorporated community, and both should still be categorized as such. But some qualifiers do change the categorization. In particular, a `former province` is no longer a province and should not be categorized in e.g. [[:Category:Provinces of Italy]], but instead in a different set of categories, e.g. [[:Category:Historical political subdivisions]]. There are several terms treated as equivalent for this purpose: `abandoned` `ancient`, `extinct`, `historic(al)`, `medi(a)eval` and `traditional`. Another set of qualifiers that change categorization are `fictional` and `mythological`, which cause any term using the qualifier to be categorized respectively into [[:Category:Fictional locations]] and [[:Category:Mythological locations]]. ===More about toponyms=== # Toponyms may be: ## ''simple'' (not including any containing location in its name, such as `Tucson`) or ''multipart'' (including one or more containing locations, such as `Tucson, Arizona` or `Tucson, USA` or even `Tucson, Arizona, USA`); ## ''bare'' (not including the word `the` if the location normally requires this article when following a preposition, such as `United States`, `Gambia` or 'Community of Madrid') or ''prefixed'' (including the word `the` as needed, such as `the United States`, `the Gambia` or `the Community of Madrid`); ## ''elliptical'' (just the placename without any disambiguating placetype, such as `Durham`, `New York` or `Mexico`) or ''full'' (containing a disambiguating placetype or similar identifier if one is commonly included, such as the city of `Durham` (in England) vs. its containing county `County Durham`; the US city `New York City` vs. its containing state `New York`; or the three-way distinction between `Mexico` (the country), `Mexico City` (the capital of this country) and `(the) State of Mexico` (one of the states of the country Mexico, mostly surrounding but not including Mexico City)). # The ''canonical Wiktionary article'' is the main article on Wiktionary where a location is described. Canonical articles, per the above terminology, are generally ''simple'' and ''bare'', but may be either ''full'' or ''elliptical''. The fact that a given article is canonical is often identifiable by the fact that translations are housed there an not somewhere else. For example, most counties of the US and Canada include the word `County` in their canonical article name, but most counties elsewhere do not. `Washington, D.C.` is one of the few cases where a non-simple toponym is used as the canonical article; this is based on common usage, especially by residents of the city in question (who commonly refer to it as "D.C." but rarely just as "Washington"). ===More about known locations=== # The following types of known locations are defined in this module: ## Continents, supercontinents and continent-level regions, into which countries are grouped. Specifically: ### At the top level below `Earth` are the supercontinents `America` and `Eurasia` and the continents `Africa`, `Oceania` and `Antartica`. ### `America` is further broken down into the continents `North America` (in turn containing the continental regions `Central America` and `Caribbean`, with the United States, Canada and Mexico directly under North America) and `South America`. ### `Eurasia` is further broken down into the continents `Europe` and `Asia`. ### `Oceania` is further broken down into the continental regions `Melanesia`, `Micronesia` and `Polynesia`, with Australia` directly under `Oceania. ### Under the above-specified divisions are countries. Some countries are placed in more than one continent or continent-level region, either because they actually span two continents (e.g. Russia, Turkey, Kazakhstan, Egypt) or because they are politically considered to belong to a continent different from the one they are geographically in (Cyprus, Georgia, Armenia, etc.). ## Political entities, including: ### Top-level political entities, which includes: #### Countries, with a fairly liberal definition, notably including all UN-recognized countries plus some others that are commonly considered countries, even if not all other countries recognize them as such or consider them completely independent (notably, Kosovo, Palestine, Taiwan, Western Sahara, Niue and the Cook Islands). #### Pseudo-countries, which include areas calling themselves countries that are de-facto not under the control of the country that they are internationally considered part of (e.g. Abkhazia, South Ossetia, Transnistria); dependent/external/etc. territories of countries (e.g. American Samoa [US], Bermuda [UK], Christmas Island [Australia], Easter Island [Chile]); constituent countries, autonomous territories and the like (Aruba, Curaçao and Sint Maarten of the Netherlands; Greenland and the Faroe Islands of Denmark; etc.; but notably not including England, Scotland, Northern Ireland and Wales, which are treated as regular countries); and a grab bag of other entities that have a semi-independent existence, such as Hong Kong, Macau, Guadeloupe, Martinique and the like. Currently, the actual distinction in treatment between "countries" and "country-like entities" is minimal, but in the future we might restrict the sorts of subcategories of country-like entities more than regular countries. #### Former countries, e.g. the Soviet Union, Yugoslavia, West Germany and the Roman Empire. These are much more limited in the sorts of subcategories allowed, because generally locations, especially cities, should be described from the perspective of which political entity they are currently located in (e.g. "an ancient Roman town in modern Syria") and categorized as such. ### Subpolities. Generally we only list top-level administrative divisions of countries (and only fairly major countries are usually included), but sometimes we list second-level administrative divisions, as in the case of the United Kingdom (where the top-level administrative divisions of the four constituent countries are listed) and China (where major prefecture-level cities are listed, and are considered administrative divisions rather than cities). ### Cities. Only major cities get categories, with the definition of "major" varying by country but often including those where the city population itself (sometimes the metro area) is >= 1,000,000 people. # A distinction should be made in the {{tl|place}} modules between ''keys'' and ''placenames''. Placenames are as the location appears in a holonym, and are generally in the same format as the canonical Wiktionary article describing the location so that when formatted as a link, the link goes to the right article; i.e. they are simple and bare, and may be full or elliptical according to Wiktionary conventions. The ''canonical key'' of a location is how the location's category is named, and always uniquely identifies the location from among the known locations in this module (but not necessarily among all possible locations). In particular, subpolities usually have multipart keys that include the containing location, such as `Anhui, China` (not just `Anhui`); `Arizona, USA` (not just `Arizona`, and also not `Arizona, United States`); and `Herefordshire, England` (not just `Herefordshire`, and also in this case not `Herefordshire, UK` or `Herefordshire, England, UK` or any other possible variation). Cities are normally simple, but some cities are multipart for disambiguation purposes (e.g. `Newcastle, New South Wales` for the city in Australia vs. `Newcastle upon Tyne` for the identically-named city in England). Canonical keys may have ''key aliases'', other ways of referring to the location that are not necessarily unique (e.g. `Newcastle` is a key alias for both of the above-mentioned cities), and city keys with diacritics generally have diacriticless aliases, such as canonical key `Düsseldorf` vs. key alias `Dusseldorf`, or canonical key `Łódź` vs. key alias `Lodz`. # Known locations are gathered into ''groups'' with similar properties, such as all the states of the United States; all the (ceremonial) counties of England (see below); and all the "sufficiently major" prefecture-level cities in China (where a prefecture-level city is a prefecture surrounding a major city with a unified government and is more like a prefecture, i.e. a major administrative division just underneath a province, than like a city, and where "sufficiently major" is defined according to the population of either the total prefecture or the urban area of the city). Note that there are multiple types of counties in England, with overlapping but non-identical names and boundaries; there are, in particular, ''ceremonial counties'', ''local government counties'' and ''historic counties''; ''ceremonial counties'' have only ceremonial administrative functionality but unlike local government counties (a) don't frequently change their boundaries or nature, (b) correspond more closely to historic county boundaries and names, and (c) are what Englanders usually identify themselves with, and so they are used as top-level divisions rather than local government counties. # Some known locations have ''aliases'' defined, which are of two types. ''Display aliases'' map holonyms to their canonical form near the beginning of processing (in particular before the displayed output is formatted). For example, `US`, `U.S.`, `USA`, `U.S.A.` and `United States of America` are all canonicalized to `United States` (if identified as a country), and display as `United States`. Similarly, the foreign forms `Occitanie` (as a region or administrative region) and `Noord-Brabant` (as a province) are mapped to `Occitania` and `North Brabant` for display purposes. There are also ''category aliases'', so that if e.g. `Republic of Macedonia` is encountered, it will display as such but categorize as `North Macedonia`. (This is because, among other reasons, `Republic of Macedonia` is normally preceded by `"the"` while `North Macedonia` is not, so a call {{tl|place|en|a <<city>> in the <<c/Republic of Macedonia>>}} would look wrong if `Republic of Macedonia` were converted to `North Macedonia` during display, as the result would be `a city in the North Macedonia`. There are also frequently political connotations to different category aliases, e.g. `Burma` vs. `Myanmar`.) All of these aliases are sensitive to the placetype specified. For example, `Mexico` as a state is categorized under `State of Mexico, Mexico` but `Mexico` the country is categorized as just `Mexico`. ===Categories=== There are two main types of categories: # Categories for known locations, divided into: ## Top-level polity categories (e.g. [[:Category:United States]], [[:Category:Taiwan]], [[:Category:South Ossetia]], [[:Category:Bermuda]], [[:Category:Soviet Union]], [[:Category:West Germany]]). ## Subpolity categories ([[:Category:Arizona, USA]], [[:Category:Hunan]], [[:Category:Kagoshima Prefecture]], [[:Category:Cluj County, Romania]]). For historical reasons, different formats are used for the subpolities of different polities. Increasingly, we are moving towards always including the polity name in the subpolity category, but whether the subpolity type is included and where it is included (cf. [[:Category:Cluj County, Romania]] vs. [[:Category:County Cork, Ireland]] is still inconsistent and will probably remain that way, based on how the subpolity is normally referred to. ## City categories ([[:Category:Tokyo]], [[:Category:New York City]], [[:Category:Jaipur]]). Normally these do not include the containing subpolity, but may do so in order to disambiguate. # Categories for placetypes, divided into: ## "Immediate" political and non-political division categories ([[:Category:States of the United States]], [[:Category:Municipalities of Tocantins, Brazil]], [[:Category:Ghost towns in Arizona, USA]]). These are name categories, whose purpose is to contain locations of the specified type. "Immediate" here refers to the fact that the location in the category name is the immediately-containing polity. Usually these categories use the preposition "of", but sometimes "in". (Specifically, "of" typically implies that the placetype in question has an official or semi-official status, whereas "in" implies there is no such official status, but common usage may override this.) The form of the toponym appearing in these categories is always the same as that of the corresponding toponym category except that the word "the" may appear (e.g. [[:Category:States of the United States]]), whereas it doesn't appear in the toponym category itself ([[:Category:United States]], no "the"). ## "Skip-polity" categories for second-level political and non-political divisions of a country or other top-level polity (e.g. [[:Category:Counties of the United States]], [[:Category:Municipalities of Brazil]] and [[:Category:Subprefectures of Japan]]). These have several purposes: * They group the immediate division categories mentioned previously. * They categorize "straggler" topoynms that (often improperly) fail to mention the subpolity they belong to, but only the top-level polity. * If categories do not exist for the first-level divisions of a country (and sometimes even when they do), they group all toponyms of the specified type for the specified country. For example, Lithuania is divided into first-level counties and second-level municipalities, but since we don't currently have categories for Lithuanian counties, all municipalities go under [[:Category:Municipalities of Lithuania]] rather than under a category for a specific county. In addition, even though we do have categories for Japanese prefectures (a first-level division), all subprefectures (a second-level division) go under [[:Category:Subprefectures of Japan]] because there aren't very many of them (see below). ## "Generic placetype" categories, both of the immediate and skip-polity type (immediate [[:Category:Cities in California, USA]] and [[:Category:Neighborhoods of the Bronx]]; skip-polity [[:Category:Villages in Ivory Coast]], [[:Category:Geographic and cultural areas of England]], [[:Category:Rivers in Egypt]] and [[:Category:Places in the Philippines]]). As mentioned above, "generic" placetypes occur in every polity (although the set of generic placetypes allowed for cities is a subset of those allowed for top-level polities and subpolities). Usually these categories use the preposition "in", but sometimes "of". As above, skip-polity categories group immediate categories, and in addition there are various reasons a toponym entry is categorized into a skip-polity category. (For example, as a general rule, geographic and cultural areas only categorize at the country level, not the subpolity level, both because there often aren't very many in a given country and because they often span multiple subpolities.) The parent categories of a given category depend on its type. Generally, location categories have placetype categories as their first parent, and vice-versa. Specifically: # Top-level country categories have as their parent e.g. [[:Category:Countries in Europe]], [[:Category:Countries in Central America]] or [[:Category:Countries in Polynesia]], using the most specific continental-level region the country is contained in. # Pseudo-countries are under [[:Category:Country-like entities]] as a neutral designation. There aren't enough of them to subcategorize under continent-level regions. # Former countries are under [[:Category:Former countries and country-like entities]]. # Subpolity categories are usually under a placetype category whose placetype is the canonical (first-listed) placetype of the subpolity and whose toponym is the immediately containing polity, but there are exceptions. Specifically, sometimes if a polity has multiple types of subpolities, they are combined (e.g. [[:Category:States and territories of Australia]], [[:Category:Federal subjects of Russia]]). In addition, sometimes a less specific but more identifiable placetype is used instead of the canonical one (e.g. [[:Category:Regions of France]] when the canonical placetype is "administrative region"). The same rules and exceptions generally apply when categorizing subpolities themselves; e.g. both the Australian state of Queensland and territory of Northern Territory go under [[:Category:en:States and territories of Australia]] rather than separately under [[:Category:en:States of Australia]] and [[:Category:en:Territories of Australia]]. In addition, sometimes subpolities may "skip a level" if there aren't very many. For example, there are only 26 subprefectures of Japan (14 under Hokkaido and 12 more scattered under five other prefectures). Rather than have e.g. [[:Category:en:Subprefectures of Kagoshima Prefecture]] containing at most two entries and [[:Category:en:Subprefectures of Miyazaki Prefecture]] containing at most one, they are all grouped under the so-called "skip-subpolity category" [[:Category:en:Subprefectures of Japan]]. # City categories are always under e.g. [[:Category:Cities in the United States]] (e.g. [[:Category:New York City]] is so-placed, even though [[:Category:Cities in New York, USA]] exists). However, they may have a second, more-specific parent (e.g. [[:Category:Cities in New York, USA]] in the case of New York City). The city entries themselves will go under the more specific parent if it exists. # Immediate placetype categories for second-level divisions of a country generally have, respectively, a "toponym parent" that is the toponym mentioned in the category and a "skip-polity parent" that groups all subpolity placetype categories of a specific type and containing polity. For example, [[:Category:Counties of Arizona, USA]] has toponym parent [[:Category:en:Arizona, USA]] and skip-polity parent [[:Category:en:Counties of the United States]]. Sometimes the default skip-polity parent is overridden or disabled entirely. For example, in the US, most states are divided into counties but Louisiana is divided into parishes and Alaska into boroughs. It would make no sense to put [[:Category:Parishes of Louisiana, USA]] under [[:Category:Parishes of the United States]] (which would only have one subcategory), so we include them under [[:Category:Counties of the United States]]. An alternative would be to name the skip-polity category to explicitly include parishes and boroughs; this would get awkward here but is done in some cases. Similarly, [[:Category:Regional county municipalities of Quebec]] is placed under [[:Category:Regional municipalities of Canada]] since that name is used in other provinces. Meanwhile, [[:Category:Regional districts of British Columbia]] disables its skip-polity category since no other province or territory of Canada has regional districts or comparable subpolities under a different name (an alternative would be to place them under [[:Category:Counties of Canada]], since they are sort of comparable to counties). # Placetype categories for first-level divisions of a country similarly (e.g. [[:Category:States of the United States]]) have a toponym parent (in this case [[:Category:United States]]), but in place of the skip-polity parent they have two other parents: a "bare placetype" parent (in this case [[:Category:States]]) and the "generic" parent [[:Category:Political divisions of specific countries]]. (There is also a bare [[:Category:Political divisions]] that groups "bare placetype" categories.) Skip-polity placetype categories for second-level divisions of a country (e.g. [[:Category:Counties of the United States]]) work the same. Placetype categories for countries work likewise except they are missing the generic parent. ===Place descriptions=== A given place description is defined internally in a table of the following form: ```{ placetypes = {"``placetype``", "``placetype``", ...}, holonyms = { { -- holonym object; see below placetype = "``placetype``" or nil, display_placename = "``placename``", unlinked_placename = "``placename``", langcode = "``langcode``" or nil, no_display = BOOLEAN, needs_article = BOOLEAN, force_the = BOOLEAN, affix_type = "``affix_type``" or nil, pluralize_affix = BOOLEAN, suppress_affix = BOOLEAN, continue_cat_loop = BOOLEAN, }, ... }, order = { ``order_item``, ``order_item``, ... }, -- (only for new-style place descriptions), joiner = "``joiner_string``" or nil, holonyms_by_placetype = { ``holonym_placetype`` = {"``placename``", "``placename``", ...}, ``holonym_placetype`` = {"``placename``", "``placename``", ...}, ... }, }``` Holonym objects have the following fields: * `placetype`: The canonicalized placetype if specified as e.g. `c/Australia`; nil if no slash is present (in which case the placename in `display_placename` refers to raw text). * `display_placename`: The placename or raw text, in the format to be displayed. Placename display aliases have already been resolved. It is raw text if `placetype` is nil. * `unlinked_placename`: Same as `display_placename` but with links and HTML removed. * `langcode`: The language code prefix if specified as e.g. `c/fr:Australie`; otherwise nil. * `no_display`: If true (holonym prefixed with !), don't display the holonym but use it for categorization. * `needs_article`: If true, prepend an article if the placename needs one (e.g. `United States`). * `force_the`: If true, always prepend the article `the`. Example use: holoynm 'city:pref:the/Gold Coast', which gets formatted as `(the) city of the [[Gold Coast]]`. * `affix_type`: Type of affix to prepend (values `pref` or `Pref`) or append (values `suf` or `Suf`). The actual affix added is the placetype (capitalized if values `Pref` or `Suf` are given), or its plural if `pluralize_affix` is given. Note that some placetypes (e.g. `district` and `department`) have inherent affixes displayed after (or sometimes before) them. * `pluralize_affix`: Pluralize any displayed affix. Used for holonyms like `c:pref/Canada,US`, which displays as `the countries of Canada and the United States`. * `suppress_affix`: Don't display any affix even if the placetype has an inherent affix. Used for the non-last placenames when there are multiple and a suffix is present, and for the non-first placenames when there are multiple and a prefix is present. * `continue_cat_loop`: If true (holonym used :also), continue producing categories starting with this holonym when preceding holonyms generated categories. Note that new-style place descs (those specified as a single argument using <<...>> to denote placetypes, placetype qualifiers and holonyms) have an additional `order` field to properly capture the raw text surrounding the items denoted in double angle brackets. The ``order_item`` items in the `order` field are objects of the following form: ```{ type = "``order_type``", value = "STRING" or INDEX, }``` Here, the ``order_type`` is one of `"raw"`, `"qualifier"`, `"placetype"` or `"holonym"`: * `"raw"` is used for raw text surrounding `<<...>>` specs. * `"qualifier"` is used for `<<...>>` specs without slashes in them that consist only of qualifiers (e.g. the spec `<<former>>` in `<<former>> French <<colony>>`). * `"placetype"` is used for `<<...>>` `specs without slashes that do not consist only of qualifiers. * `"holonym"` is used for holonyms, i.e. `<<...>>` specs with a slash in them. For all types but `"holonym"`, the value is a string, specifying the text in question. For `"holonym"`, the value is a numeric index into the `holonyms` field. It should be noted that placetypes and placenames occurring inside the holonyms structure are canonicalized, but placetypes inside the placetypes structure are as specified by the user. Stripping off of qualifiers and canonicalization of qualifiers and bare placetypes happens later. The information under `holonyms_by_placetype` is redundant to the information in holonyms but makes categorization easier. The holonym placenames listed here already have category aliases applied. For example, the call {{tl|place|en|city|s/Pennsylvania|c/US}} will result in the return value ```{ placetypes = {"city"}, holonyms = { { placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania" }, { placetype = "country", display_placename = "United States", unlinked_placename = "United States" }, }, holonyms_by_placetype = { state = {"Pennsylvania"}, country = {"United States"}, }, }``` Here, the placetype aliases `s` and `c` have been expanded into `state` and `country` respectively, and the placename display alias `US` has been expanded into `United States`. PLACETYPES is a list because there may be more than one. For example, the call {{tl|place|en|city/and/municipality|p/[[Kwango]] Province|c/Congo}} will result in the return value ``` { placetypes = {"city", "and", "municipality"}, holonyms = { { placetype = "province", display_placename = "[[Kwango]] Province", unlinked_placename = "Kwango Province" }, { placetype = "country", display_placename = "Congo", unlinked_placename = "Congo" }, }, holonyms_by_placetype = { country = {"Congo"}, }, }``` Here, the `unlinked_placename` field has removed links from `display_placename`. The value in the key/value pairs is likewise a list; e.g. the call {{tl|place|en|city|s/Kansas|and|s/Missouri}} will return ``` { placetypes = {"city"}, holonyms = { { placetype = "state", display_placename = "Kansas", unlinked_placename = "Kansas" }, { display_placename = "and", unlinked_placename = "and" }, { placetype = "state", display_placename = "Missouri", unlinked_placename = "Missouri" }, }, holonyms_by_placetype = { state = {"Kansas", "Missouri"}, }, } ``` Note that in `get_cats()` (which runs after the display form has been generated), further changes to the holonym structure are made to aid in categorization. For example, after `handle_category_implications()` and `augment_holonyms_with_container()` are called, the above structure will look more like ``` { placetypes = {"city"}, holonyms = { { placetype = "state", display_placename = "Kansas", unlinked_placename = "Kansas" }, { placetype = "country", unlinked_placename = "United States" }, { display_placename = "and", unlinked_placename = "and" }, { placetype = "state", display_placename = "Missouri", unlinked_placename = "Missouri" }, { placetype = "country", unlinked_placename = "United States" }, }, holonyms_by_placetype = { state = {"Kansas", "Missouri"}, country = {"United States"} }, } ``` ===Overall place specs=== The overall place spec parsed by `parse_overall_place_spec` has the following fields: * `lang`: The language object (from {{para|1}}). * `args`: The parsed arguments from the {{tl|place}} call. * `directives`: List of form-of directives (starting with `@`) parsed from the numeric args beginning with {{para|2}}. Each directive contains fields `directive` (the directive as specified by the user, e.g. `"former name of"`); `terms` (list of term objects for the terms specified by the user); `conj` (conjunction specified by the user using inline modifier `<conj:...>`, or {nil}); `spec` (the corresponding directive spec from `all_form_of_directives`); `pretext` (the text to display directly before the directive); `posttext` (the text to display directly after the directive; {nil} except for the last directive). * `descs`: List of one or more place description objects parsed from the numeric args beginning with {{para|2}}, as described above. * `extra_info`: List of extra-info objects for extra info specified using arguments such as {{para|capital}}, {{para|modern}}, etc. Objects are in the order they should be displayed, and each object contains fields `spec` (the spec for the type of extra info, taken from `export.extra_info_args`), `terms` (list of term objects for the terms specified by the user); and `conj` (conjunction specified by the user using inline modifier `<conj:...>`, or {nil}). ===Category determination=== The algorithm to find the categories to which a given place belongs works off of a place description (which specifies the entry placetype(s) and holonym(s); see above). If there are multiple place descriptions, each is processed independently to generate categories. Likewise, if there are multiple entry placetypes in a given place description, each is processed independently with all the holonyms of the description to generate categories. Furthermore, before the category-generation algorithm runs, earlier steps have modified the holonyms of the place description (inserting containing polities whenever possible; see the description above of `handle_category_implications()` and `augment_holonyms_with_container()`). Given a single entry placetype and a place description, the algorithm to generate categories processes holonyms from left to right until it finds one that "matches" in that it produces one or more categories. At that point it attempts to generate categories for all other holonyms in the place description of the same placetype. Normally, it then stops processing holonyms, but if a holonym is marked using the `:also` modifier, the category generation process starts over starting with that holonym (or the leftmost such remaining holonym, if there is more than one marked with `:also`). This makes it possible, for example, to specify the description of a river that passes through two different types of political divisions (e.g. Alberta and the Northwest Territories), or categorize a geographic region at both the continent and country level, such as this: <pre> {{place|en|historical region|r/Eastern Europe|located in southeastern|c:also/Poland|*and western|c/Ukraine}} </pre> Here, `r/Eastern Europe` has a category implication that adds `cont/Europe` as a holonym directly after it, which causes the page to be categorized into [[:Category:en:Geographic and cultural areas of Europe]]. The category generation process would normally stop at this point, but the presence of `:also` causes it to restart with `c/Poland` and generate the category [[:Category:en:Geographic and cultural areas of Poland]]. After doing this, it looks for other holonyms of the same placetype as `c/Poland` (i.e. other countries), which causes it to process `c/Ukraine` and generate the category [[:Category:en:Geographic and cultural areas of Ukraine]]. The category generation process works off of the `placetype_data` table, which specifies various properties for placetypes, such as how to display a holonym of that placetype as well as how to categorize certain pages where the {{tl|place}} call contains the specified placetype as an entry placetype. For example, the entry for `city-state` in [[Module:place/placetypes]] might look like ``` ["city-state"] = { link = true, category_link = "[[sovereign]] [[microstate]]s consisting of a single [[city]] and [[w:dependent territory|dependent territories]]", has_neighborhoods = true, class = "settlement", ["continent/*"] = {"City-states", "Cities", "Countries", "Countries in +++", "National capitals"}, default = {"City-states", "Cities", "Countries", "National capitals"}, }, ``` Here, the keys specify, respectively: # If `city-state` occurs as an entry placetype, link it to the corresponding Wiktionary entry (that is what `true` means in `link = true`). # Use the specified `category_link` text for categories such as [[:Category:City-states]]. # City-states are "city-like", i.e. they have neighborhoods; this controls the handling of entry placetypes such as `neighborhood`, `district`, `area`, etc. # City-states should be treated as settlements for determining how to handle the placetype `former city-state` and for categorizing the bare category [[:Category:City-states]] and language-specific equivalents such as [[:Category:en:City-states]]. # When the entry placetype `city-state` occurs along with a continent holonym, categorize into the specified categories under `continent/*`. Here, `+++` stands for the holonym in question. # When the entry placetype `city-state` occurs in any other context, categorize into the specified categories under `default`. It's important to realize that the only categorization keys under a given placetype entry that are specified explicitly in [[Module:place/placetypes]] are certain wildcard keys such as `continent/*` above (i.e. containing a slash followed by `*`) and under the key `default`. All the remaining categorization happens through category handlers, based on the information on known locations in [[Module:place/locations]]. For example, [[Module:place/locations]] has an "England group" specified similarly to the following: ``` export.england_group = { default_container = {key = "England", placetype = "constituent country"}, default_placetype = "county", default_divs = { "districts", {type = "local government districts", cat_as = "districts"}, { type = "local government districts with borough status", cat_as = {"districts", "boroughs"}, }, {type = "boroughs", cat_as = {"districts", "boroughs"}}, "civil parishes", }, default_british_spelling = true, data = export.england_counties, } ``` The `default_divs` key here specifies the divisions that exist for each of the counties listed under the `data` key (unless the key overrides them). Here, the entry `{type = "boroughs", cat_as = {"districts", "boroughs"}}` directs the category handler `political_division_cat_handler` in [[Module:place/placetypes]] (which is one of two category handlers that run for all entry placetypes, along with `generic_place_cat_handler`) to categorize boroughs specified under any of the counties listed under `data` as both districts and boroughs. Now, the categorization process proceeds as follows, given an entry placetype and place description, which specifies a set of holonyms (the code to do this is in `get_placetype_cats()`): # First, look up the entry placetype and any equivalent placetypes in `placetype_data`, which is defined in [[Module:place/placetypes]]. Note that the entry in `placetype_data` that specifies the placetype information that is used to determine the category or categories may not directly correspond to the entry placetype as specified in the place description. For example, if the entry placetype is `small town`, the placetype whose data is fetched will be `town` since `small` is a recognized qualifier and there is no entry in `placetype_data` for `small town`. As another example, if the entry placetype is `administrative capital`, the code will first look up `administrative capital` and then look up `capital city`, which is where the category handler is found, because `administrative capital` specifies `capital city` as its fallback. # Then, iterate over holonyms from left to right, as described above. For each holonym, we proceed as follows: ## First, call `political_division_cat_handler` to check if the entry placetype and holonym match a division in the `locations` data in [[Module:place/locations]], as in the example above. Note that when doing this, holonyms are canonicalized so that e.g. `co/Bedfordshire` gets mapped to `county/Bedfordshire` (because there is an entry in `placetype_aliases` in [[Module:place/placetypes]] that maps `co` to `county`) and `c/USA` gets mapped to `country/United States` (because there is an entry in the location data for the list of countries that maps `country/USA` to `country/United States` for both display and categorization purposes). This category handler, as with all such handlers, is passed the entry placetype and holonym being processed, but is also passed the entire place description, so it can look at other specified holonyms (particularly those that follow). It either returns {nil} or a list of category specs (which are the actual categories minus the preceding language code). ## If `political_division_cat_handler` doesn't generate any categories, check if there is a category handler defined using the `cat_handler` key for the entry placetype. If so, call it to generate the categories (if any). ## If the category handler returns {nil}, or there is no category handler, look for a ''wildcard key'' of the format e.g. `country/*`, which matches any holonym of placetype `country`. If found, the value is a list of category specs, which are processed as above. ## If we get this far without generating any categories, move to the next holonym. ## If we do generate any categories, process all other holonyms of the same placetype. For example, if the user says {{tl|place|en|city|s/Kansas|and|s/Missouri}}, when we get to the holonym `s/Kansas`, we generate the category [[:Category:en:Cities in Kansas, USA]]. This causes us to look for other holonyms of the same placetype `state`, and process them accordingly, generating a category [[:Category:en:Cities in Missouri, USA]] as well. The same thing happens in an invocation like {{tl|place|pl|river|c/Poland,Ukraine,Belarus}}. # Once we generate categories for a holonym and any other holonyms of the same placetype, we normally stop processing holonyms. But if a holonym has the `:also` modifier, we restart the left-to-right loop at that holonym. For example, in the invocation {{tl|place|en|river|flowing through|p/Alberta|p/British Columbia|and the|terr/Northwest Territories}}, we will generate a category [[:Category:en:Rivers in Alberta, Canada]] as well as [[:Category:en:Rivers in British Columbia, Canada]] (because British Columbia is of the same placetype as Alberta); but no category will be generated for the Northwest Territories, which is of a different placetype. To fix this, write {{tl|place|en|river|flowing through|p/Alberta|p/British Columbia|and the|terr:also/Northwest Territories}}. The use of `:also` will cause holonym processing to resume at `Northwest Territories` after `Alberta` is processed, leading to an additional category [[:Category:en:Rivers in the Northwest Territories, Canada]]. (The presence of `the` in this last category is because `Northwest Territories` is a known location with a spec indicating that it should be preceded by `the`; it has nothing to do with the raw text `and the` in the invocation.) # Finally, if we process all holonyms and don't end up producing any categories, we check the entry placetype's data for a `default` key. If found, it lists category specs, which are processed to generate categories. This is used, for example, in the placetype `city-state`, as described above. # It should be noted that the above process runs independently for each combination of entry placetype and place description. Thus, for example, an invocation {{tl|place|en|city/and/county|s/Kansas,Missouri|c/USA}} will generate categories for both cities and counties in both Kansas and Missouri. # Two additional sources of categories are ''bare location'' categories and ''generic place'' categories. These categories are added by appropriate calls in the outer function `get_cats`, which iterates over placetypes and place descriptions, calling `get_placetype_cats` on each combination. ## Bare location categories are categories like [[:Category:Arizona, USA]] that are related-to categories containing terms related to the specified location. The bare location code, for example, adds the term [[Arizona]], and its equivalents in other languages, to [[:Category:Arizona, USA]]. When looking for terms to consider, it checks the pagename, the glosses specified using {{para|t}}, and the terms specified using {{para|modern}}, {{para|short}} and {{para|full}}. It looks to see if any of these parameters match any known locations, but only adds them to a bare location category if (a) the specified entry placetype matches, so that for example Russian `[[Джорджия]]` goes into [[:Category:Georgia, USA]] while `[[Грузия]]` goes into [[:Category:Georgia]] (the country), even though both have a gloss `Georgia`; and (b) there are no conflicting holonyms, so that for example the Old English term [[Munucceaster]] if defined similarly to {{tl|place|ang|city|in modern|cc/England|t=Newcastle}} won't get added to [[:Category:Newcastle, New South Wales]] (even though it is also a city) because the latter city is known to be in Australia, which conflicts with the country `United Kingdom` (added internally to the Old English place description through the holonym augmentation process, based on the holonym `cc/England`). ## Generic place categories are categories like [[:Category:Places in Kansas, USA]] and [[:Category:Places in England]] that contain places of arbitrary placetype. These are added through a special category handler that operates like other category handlers but is run for all placetypes, rather than only for the specified one(s). ]==] --[=[ TODO/FIXME: 1. [DONE] Neighborhoods should categorize at the city level. Categories like [[:Category:Places in Los Angeles]] exist but not [[:Category:Neighborhoods in Los Angeles]]; we can refactor the code in generic_cat_handler() to support this use case. 2. Display handlers should be smarter. For example, 'co/Travis' as a holonym should display as 'Travis County' in the United States, but (I think) display handlers don't currently have the full context of holonyms passed in to allow this to happen. 3. Connected to this, we have various display handlers that add the name of the holonym after or (sometimes) before the placename if it's not already there. An example is the county_display_handler() in [[Module:place/placetypes]], which adds "County" before Ireland and Northern Ireland counties and after Taiwan and Romania counties. This should be integrated into the polity group for these respective polities through a setting rather than requiring a separate handler that has special casing for various polities. 4. Placetypes for toponyms should also have display handlers rather than just fixed text. This should allow us to dispense with the need for special types for "fpref" = "French prefecture" (which displays as "prefecture" but links to the appropriate Wikipedia article on Frenc prefectures, which are completely different from the more general concept of prefecture). Similarly for "Polish colony" and "Welsh community". ("Israeli settlement" should probably stay as-is because it displays as "Israeli settlement" not just "settlement".) 5. [DONE] Currently, categories for e.g. states and territories of Australia go into [[:Category:States and territories of Australia]] but terms for states and territories of Australia go into (respectively) [[:Category:States of Australia]] and [[:Category:Territories of Australia]]. We should fix this; maybe this is as easy as setting cat_as in the respective divs definitions. 6. Probably cat_as should support raw categories as well as category types; raw categories would be indicated by being prefixed with "Category:". 7. [MOSTLY DONE] Update documentation. 8. [DONE] Rename remaining political division categories to include name of country in them. 9. [DONE] Add Pakistan provinces and territories. 10. [DONE] Add a polity group for continents and continent-level regions instead of special-casing. This should make it possible e.g. to have Jerusalem as a city under "Asia". 11. [DONE] Add better handling of cities that are their own states, like Mexico City. 12. [DONE] Breadcrumb for e.g. [[Category:Aguascalientes, Mexico]] is "Aguascalientes, Mexico" instead of just "Aguascalientes". 13. [DONE] Unify aliasing system; cities have a completely different mechanism (alias_of) vs. polities/subpolities (which use`placename_cat_aliases` and `placename_display_aliases` in [[Module:place/placetypes]]). 14. [DONE] More generally, cities should be unified into the polity grouping system to the extent possible; this would allow for divs of cities (see #17 below). 15. [DONE] We have `no_containing_polity_cat` set for Lebanon, Malta and Saudi Arabia to prevent country-level implications from being added due to generically-named divisions like "North Governorate", "Central Region" and "Eastern Province" but (a) this setting seems to do multiple things and should be split, (b) it should be possible to set this at the division level instead of the country level. 16. Split out the data from the handlers so we can use loadData() on the data because it's becoming very big. 17. [DONE] Cities like Tokyo have special wards; "prefecture-level cities" like Wuhan (which aren't really cities but we treat them as such) have districts, subdistricts, etc. We need to support divs for cities and even named divisions of cities (such as we already have for boroughs of New York City). 18. [DONE] It should be allowed to set 'true' to any qualifier (which links it) and have it work correctly; qualifier lookup in [[Module:place]] needs to remove links first. 19. [DONE] Categories 'Historical polities' and 'Historical political subdivisions' should be renamed 'Former ...' since "historic(al)" is ambiguous (cf. "historic counties" in England which are not former, but still have a legal definition). 20. [PARTLY DONE; SUPPORT IS THERE BUT FORMER PROVINCES NOT YET CATEGORIZED] It should be possible to categorize former subpolities of certain polities; cf. [[:Category:ja:Provinces of Japan]], which contains former provinces. 21. [DONE] In subpolity_keydesc(), we need to generate the correct indefinite article and have a huge hack to check specifically for "union territory", which is the only placetype that shows up in this function where the default indefinite article generating function fails. To fix this properly, we need to separate out the non-category placetype data from `cat_data` in [[Module:place/placetypes]] and move it to [[Module:place/locations]], because we don't have access to the data in [[Module:place/placetypes]], and that data indicates the correct article for placetypes like "union territory". 22. [DONE] Simplify the specs in `cat_data`, eliminating the distinction between "inner" and "outer" matching. There should not be two levels, just one. For example, in "district", instead of ["country/Portugal"] = { ["itself"] = {"Districts and autonomous regions of +++"}, } we should just have ["country/Portugal"] = {"Districts and autonomous regions of +++"}, And in "dependent territory", instead of ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, we should just have ["itself"] = {true}, ["country/*"] = {true}, It appears the only remaining spec that can't be easily converted in this fashion is for "subdistrict": ["country/Indonesia"] = { ["municipality"] = {true}, }, This seems to be specifically for Jakarta and doesn't seem to work anyway, as the two entries in [[:Category:en:Subdistricts of Jakarta]] and the one entry in [[:Category:id:Subdistricts of Jakarta]] are manually categorized. 23. [DONE] Consolidate the remaining stuff in [[Module:category tree/topic cat/data/Earth]] into [[Module:category tree/topic cat/data/Places]]. 24. [DONE] The `generic_cat_handler` that categorizes into `Places in FOO` is smart enough not to categorize cities that are in different polities from the specified containing polity/polities of the city, but doesn't do the same for larger-level divisions. Likewise for the `city_type_cat_handler`. There are some sufficiently generically-named divisions that this issue can occur; for example, [[Koforidua]], the capital city of Eastern Region, Ghana, is incorrectly categorized under [[:Category:en:Cities in Eastern Region, Malta]] and [[:Category:en:Places in Eastern Region, Malta]]. Note that the function `augment_holonyms_with_container` ''DOES'' do such checks, so we should be able to refactor the code out of that function and use it elsewhere. 25. [DONE] The `generic_cat_handler` that categorizes into `Places in FOO` is smart enough not to categorize cities that are in different polities from the specified containing polity/polities of the city; but how smart is it? It will successfully avoid categorizing a neighborhood in e.g. [[Columbus]], [[Georgia]] that doesn't explicitly mention the US (only `s/Georgia`) into [[:Category:en:Places in Columbus]], which is for Columbus, Ohio, but will it do the same for a hypothetical neighborhood of Columbus in say Merseyside, England? This should be investigated. It will probably work for a hypothetical Columbus in [[Canada]] because `augment_holonyms_with_container` would auto-add Canada as an additional holonym once say `p/Ontario` is mentioned, but I think there's a setting preventing this augmentation from happening for the UK. (This relates to FIXME #15. `no_containing_polity_cat` is set on England, Scotland, etc. to prevent the toponyms from being added to [[:Category:en:Places in the United Kingdom]], but this same setting is used to prevent augmentation, which it should not be; there should be different settings.) 26. [DONE] The `generic_cat_handler` (or more specifically `find_holonym_keys_for_categorization`) checks for city holonyms by looking specifically for holonym type `city`. But some cities (particularly those in China) can be specified using different holonym types, e.g. `prefecture-level city`, `subprovincial city`, etc. We should allow these when appropriate (which means the cities in China need to have a `placetype` set that indicates their regional-level status as well as just `city`). I'm not sure if cities support specifying a custom `placetype` at the moment; this relates to FIXME #14 above concerning unifying cities and political divisions internally. 27. [DONE] The bare category handler (`get_bare_categories` in [[Module:place/placetypes]]) is not smart enough to avoid overcategorizing cities or other divisions that are of the right placetype but in the wrong containing polity. For example, Asturian [[Llión]] "León (city in Spain)" gets put in [[:Category:ast:León]] even though the latter is supposed to refer to a city in Mexico. We can borrow the check-containing-polity code from `generic_cat_handler`. 28. [DONE] Redo handling of singular and plural to respect overrides specified in placetype_data. Check more carefully for things that may not singularize correctly, e.g. 'passes' -> 'passe'? Definitely 'headquarters' and variants. 29. [DONE] Combine placetype_equivs and other placetype data into `placetype_data`. Figure out if we need the distinction between `placetype_equivs` and `fallback`. 30. `has_neighborhoods` may need to be a function that can look at the containing holonyms to determine whether the entity in question is city-like. 31. [DONE] Bare placenames as they appear in holonyms (e.g. `Riau Islands`) instead of category keys (e.g. `the Riau Islands, Indonesia`) should appear in the polity data tables. As a first pass, the word "the" should not appear but should instead be a property of the polity. 32. [DONE] `capital_city_cat_handler` should use `get_holonyms_to_check()`. 33. [PARTLY DONE] The code to generate and parse the correct preposition ("in" or "of") is very convoluted, and the actual preposition used is specified in various locations with various defaults, sometimes hardcoded. This should be simplified. It is made more difficult by the fact that the in/of distinction occurs in several places: (a) when generating the {{place}} text in old-style descriptions where the preposition isn't explicitly given, which uses the `preposition` setting in placetype_data, defaulting to "in"; (b) when generating categories based on explicit category specs in placetype_data (which are gradually being deprecated), which likewise uses the `preposition` setting in placetype_data, defaulting to "in"; (c) when generating categories based on political_division_cat_handler, originating in the `divs` placetypes for specific known locations in [[Module:place/locations]], which uses the `prep` setting embedded in the `divs` specifications, defaulting to "of"; (d) when generating categories based on category handlers specified using the `cat_handler` property of entries in placetype_data, which tend to hardcode "in" or "of" depending on the specific category handler; (e) when generating category descriptions in [[Module:category tree/topic/Places]] for `divs` categories generated in (c), which (correctly) uses the same `prep` setting embedded in the `divs` settings that is used when generating the categories themselves; (f) when generating category descriptions for categories generated in (b) and (d) above, which relies on the `generic_before_non_cities` and `generic_before_cities` settings in placetype_data, which need to match the corresponding prepositions hardcoded in the category generation handlers. Instead of the hardcoding, the category generation handler should respect the `generic_before_*` settings. 34. [[Krakow]] defined as {{place|en|A <<city>> on the [[Vistula]] River, the <<capital>> of the <<voi/Lesser Poland Voivodeship>> in southern <<c/Poland>>}} categorizes under [[:Category:Voivodeship capitals]] when it should probably instead be under [[:Category:Voivodeship capitals of Poland]]. Possibly this is because the various voivodeships haven't yet been entered as known locations, but this should happen regardless of that. 35. {{tcl}} bugs: a. [DONE] Lowercase initial letter in new-style {{place}} descriptions in {{tcl}}. Maybe we can have a setting tcl_nolc=1 to prevent this from happening. b. [DONE] tcl= and probably new-style {{place}} descriptions in general should recognize ;; to separate distinct {{place}} descriptions, and similarly ;;and as the equivalent of regular `;and`, etc. c. [DONE] The value supplied in `modern=` should be displayed in {{tcl}} descriptions regardless of the setting that normally disables this, so that e.g. the foreign-language equivalent of [[British Honduras]] doesn't just say it's a former British colony in Central America but specifically identifies it as modern Belize. If the user gives, place_modern= in {{tcl}}, that should override the modern= value and still display. d. [DONE] The page supplied to {{tcl}} should be used for generating bare categories even if t= is supplied and overrides the English term displayed. [DONE] e. [DONE] If text follows {{place}} and begins with a semicolon, the semicolon isn't copied into {{tcl}}. 36. County boroughs used as holonyms currently display 'borough county borough' because there's an affix setting for 'county borough' and a fallback display handler for 'borough'. We need to rethink this; maybe merge the affix setting and display handlers. 37. Implement known-location groups and specs in a more standardly object-oriented way using metatables. 38. Implement caching of known location lookup in the holonym. This may have to be keyed by placetype, but we can have a special field for when the lookup placetype is the same as the user-specified placetype of the holonym. Use this known location in place of looking up known locations and store the appropriate known location there in `augment_holonyms_with_container()` instead of calling `key_to_placename`. 39. Bug fixes with 'the': (a) [DONE] [[Kazaň]] defined as {{place|cs|caplc|rep:Pref/Tatarstan|c/Russia|t1=Kazan}} displays as "Republic of the Tatarstan". (b) [[Valday]] defined as {{place|en|town/administrative center|dist:Suf/Valdaysky|obl/Novgorod|c/Russia}} displays as "a town, the administrative center of the Valdaysky District". Changing to `dist:suf/Valdaysky` displays as "... of Valdaysky district". 40. [DONE] Bug fix with 'the': [[Verkhoyansk]] defined as {{place|en|town|rep/Sakha|c/Russia}} displays as "a town in the Sakha". 41. [DONE] [[Category:Cities in Asia]] has [[Category:Cities in Eurasia]] as a parent, which in turn has [[Category:Cities in the Earth]] as a parent. Continents should not have the second parent like this. 42. [DONE] When checking `british_spelling`, it should check all containers as well; otherwise it's too hard to keep this in sync across cities, administrative divisions and countries. 43. [DONE] `skip_polity_parent_type` should be renamed to container_parent_type or similar. 44. There should be a flag to allow e.g. departments of France that are currently categorized as departments of their region to also be categorized as departments of France. 45. [DONE] Aliases are causing iterate_matching_holonym_location() to fail, e.g. if [[براق]] "Prague" is specified as {{place|acw|capital city|c/Czechia|t1=Prague}}, this fails add a bare category [[Category:acw:Prague]] because the code in iterate_matching_holonym_location() isn't resolving aliases when comparing the known container 'Czech Republic'. Probably we want to build an alias table to speed up these sorts of lookups. 46. [DONE; DUE TO TYPO IN HANDLER] The district cat handler is failing to work right, e.g. in [[Saint-Gaudérique]] defined as {{place|fr|district|city/Perpignan|in|dept/Pyrénées-Orientales|r/Occitania|c/France|t=Saint-Gaudérique}}, only the 'Places in ...' categories are getting triggered. 47. Suburbs of a given city aren't generally in the city and may not even be in the same country or country division, so they should not categorize as "Places in ..." based on the city and specified country and division. Same goes for "enclave" (within somewhere) and "exclave". 48. When converting display aliases, we should automatically convert full placenames to full placenames and elliptical placenames to elliptical placenames instead of always either doing elliptical or full placenames depending on the value of `display_as_full`. 49. `@obsolete form of` and `@archaic form of` should automatically trigger nocat=1. 50. The handler that adds bare categories should pick up values in <eq:...>. ]=] --[==[ var: List specifying the allowed form-of directives, used for former names, official names, abbreviations, etc. of places. The key is the form-of directive and the value is an object with the following properties: * `text`: The actual text displayed before the terms. If the value is `+`, the key is used as the text. If the value is a function, it is passed a single argument, the overall place spec (see comment at top of file) and should return the text to be displayed. * `type_prefix`: The prefix used to generate the placetype for looking up the appropriate category or categories in the placetype data structure. Can be omitted if there are no categories associated with the directive. * `conjunction`: The conjunction used to join multiple terms, defaulting to `and`. * `cat`: Additional category or categories to add the term to, whenever this particular directive is used. Normally the value is a topic-style category minus the langcode prefix, but if prefixed with `cln:`, it is a langname-style category. For example, the value `"Abbreviations"` would correspond to a category [[:Category:en:Abbreviations]] (assuming the language of the {{tl|place}} call is English), while the value `"cln:abbreviations"` corresponds to a category [[:Category:English abbreviations]]. Use a list of such specs for multiple categories. * `default_foreign`: If specified, the default language of terms given along with this directive is the language in {{para|1}}; otherwise it is English. ]==] export.all_form_of_directives = { ["former name of"] = {text = "+", type_prefix = "FORMER_NAME_OF"}, ["fmr of"] = {alias_of = "former name of"}, ["ancient name of"] = {text = "+", type_prefix = "FORMER_NAME_OF"}, ["official name of"] = {text = "+", type_prefix = "OFFICIAL_NAME_OF"}, ["former official name of"] = {text = "+", type_prefix = "FORMER_OFFICIAL_NAME_OF"}, ["long form of"] = {text = "+", type_prefix = "LONG_FORM_OF"}, ["former long form of"] = {text = "+", type_prefix = "FORMER_LONG_FORM_OF"}, ["nickname for"] = {text = "+", type_prefix = "NICKNAME_FOR"}, ["official nickname for"] = {text = "+", type_prefix = "OFFICIAL_NICKNAME_FOR"}, ["former nickname for"] = {text = "+", type_prefix = "FORMER_NICKNAME_FOR"}, ["derogatory name for"] = {text = "[[Appendix:Glossary#derogatory|derogatory]] name for", type_prefix = "DEROGATORY_NAME_FOR"}, ["synonym of"] = {text = "+"}, ["syn of"] = {alias_of = "synonym of"}, ["abbreviation of"] = {text = "[[Appendix:Glossary#abbreviation|abbreviation]] of", type_prefix = "ABBREVIATION_OF", cat = "cln:abbreviations", default_foreign = true}, ["abbr of"] = {alias_of = "abbreviation of"}, ["abbrev of"] = {alias_of = "abbreviation of"}, ["initialism of"] = {text = "[[Appendix:Glossary#initialism|initialism]] of", type_prefix = "ABBREVIATION_OF", cat = "cln:initialisms", default_foreign = true}, ["init of"] = {alias_of = "initialism of"}, ["acronym of"] = {text = "[[Appendix:Glossary#acronym|acronym]] of", type_prefix = "ABBREVIATION_OF", cat = "cln:acronyms", default_foreign = true}, ["syllabic abbreviation of"] = {text = "[[Appendix:Glossary#syllabic abbreviation|syllabic abbreviation]] of", type_prefix = "ABBREVIATION_OF", cat = "cln:syllabic abbreviations", default_foreign = true}, ["sylabbr of"] = {alias_of = "syllabic abbreviation of"}, ["sylabbrev of"] = {alias_of = "syllabic abbreviation of"}, ["ellipsis of"] = {text = "[[Appendix:Glossary#ellipsis|ellipsis]] of", type_prefix = "ELLIPSIS_OF", cat = "cln:ellipses", default_foreign = true}, ["ellip of"] = {alias_of = "ellipsis of"}, ["clipping of"] = {text = "[[Appendix:Glossary#clipping|clipping]] of", type_prefix = "CLIPPING_OF", cat = "cln:clippings", default_foreign = true}, ["clip of"] = {alias_of = "clipping of"}, ["alternative form of"] = {text = "+", default_foreign = true}, ["alt form"] = {alias_of = "alternative form of"}, ["alternative spelling of"] = {text = "+", default_foreign = true}, ["alt spell"] = {alias_of = "alternative spelling of"}, ["alt sp"] = {alias_of = "alternative spelling of"}, ["dated form of"] = {text = "[[Appendix:Glossary#dated|dated]] form of", type_prefix = "DATED_FORM_OF", cat = "cln:dated forms", default_foreign = true}, ["dated form"] = {alias_of = "dated form of"}, ["dated spelling of"] = {text = "[[Appendix:Glossary#dated|dated]] spelling of", type_prefix = "DATED_FORM_OF", cat = "cln:dated forms", default_foreign = true}, ["dated spell"] = {alias_of = "dated spelling of"}, ["dated sp"] = {alias_of = "dated spelling of"}, ["archaic form of"] = {text = "[[Appendix:Glossary#archaic|archaic]] form of", type_prefix = "ARCHAIC_FORM_OF", cat = "cln:archaic forms", default_foreign = true}, ["arch form"] = {alias_of = "archaic form of"}, ["archaic spelling of"] = {text = "[[Appendix:Glossary#archaic|archaic]] spelling of", type_prefix = "ARCHAIC_FORM_OF", cat = "cln:archaic forms", default_foreign = true}, ["arch spell"] = {alias_of = "archaic spelling of"}, ["arch sp"] = {alias_of = "archaic spelling of"}, ["obsolete form of"] = {text = "[[Appendix:Glossary#obsolete|obsolete]] form of", type_prefix = "OBSOLETE_FORM_OF", cat = "cln:obsolete forms", default_foreign = true}, ["obs form"] = {alias_of = "obsolete form of"}, ["obsolete spelling of"] = {text = "[[Appendix:Glossary#obsolete|obsolete]] spelling of", type_prefix = "OBSOLETE_FORM_OF", cat = "cln:obsolete forms", default_foreign = true}, ["obs spell"] = {alias_of = "obsolete spelling of"}, ["obs sp"] = {alias_of = "obsolete spelling of"}, } local function get_seat_text(overall_place_spec) local placetype = overall_place_spec.descs[1].placetypes[1] if placetype == "county" or placetype == "counties" then return "county seat" elseif placetype == "parish" or placetype == "parishes" then return "parish seat" elseif placetype == "borough" or placetype == "boroughs" then return "borough seat" else return "seat" end end --[==[ var: List specifying the allowed arguments containing extra information that is sometimes added to a definition, such as the capital, largest city, modern name, official name, etc., along with associated properties; displayed in the order given. Each element is an object with the following properties: * `arg`: The argument name. * `text`: The actual text displayed before the terms. If the value is `+`, the argument name is used as the text. If the value is a function, it is passed a single argument, the overall place spec (see the comment at the top of the file) and should return the text to be displayed. * `conjunction`: The conjunction used to join multiple terms, defaulting to `and`. * `display_even_when_dropped`: Display this piece of extra info even when it would normally be dropped (e.g. in {{tl|tcl}} when the language is other than English). * `match_sentence_style`: If true, the text will be capitalized and preceded by a period when ''sentence style'' is in effect (essentially, when the language is English and there is no translation specified using {{para|t}} or similar parameter); otherwise, the text will be displayed as-is and preceded by a semicolon. If false, the semicolon style will always be used. * `auto_plural`: If true, pluralize the text when there is more than one term. * `with_colon`: If true, follow the text with a colon. (This colon cannot easily be included in the text itself because if pluralized, the pluralized text goes before the colon.) ]==] export.extra_info_args = { {arg = "modern", text = "+", conjunction = "or", display_even_when_dropped = true}, {arg = "now", text = "now,", conjunction = "or", display_even_when_dropped = true}, {arg = "full", text = "in full,", conjunction = "or", display_even_when_dropped = true}, {arg = "short", text = "short form", conjunction = "or"}, {arg = "abbr", text = "abbreviation", conjunction = "or"}, {arg = "former", text = "formerly,"}, {arg = "official", text = "official name", match_sentence_style = true, auto_plural = true, with_colon = true}, {arg = "capital", text = "+", match_sentence_style = true, auto_plural = true, with_colon = true}, {arg = "largest city", text = "+", match_sentence_style = true, auto_plural = true, with_colon = true}, {arg = "caplc", text = "capital and largest city", match_sentence_style = true, auto_plural = false, with_colon = true}, {arg = "seat", text = get_seat_text, match_sentence_style = true, auto_plural = true, with_colon = true}, {arg = "shire town", text = "+", match_sentence_style = true, auto_plural = true, with_colon = true}, {arg = "headquarters", text = "+", match_sentence_style = true, auto_plural = false, with_colon = true}, {arg = "center", text = "administrative center", match_sentence_style = true, auto_plural = false, with_colon = true}, {arg = "centre", text = "administrative centre", match_sentence_style = true, auto_plural = false, with_colon = true}, } export.extra_info_arg_map = {} for _, spec in ipairs(export.extra_info_args) do export.extra_info_arg_map[spec.arg] = spec end ----------- Wikicode utility functions -- Return a wikilink link {{l|language|text}} local function link(text, langcode, id) if not langcode then return text end return m_links.full_link( {term = text, lang = require(languages_module).getByCode(langcode, true, "allow etym"), id = id}, nil, "allow self link" ) end ---------- Basic utility functions -- Add the page to a tracking "category". To see the pages in the "category", -- go to [[Wiktionary:Tracking/place/PAGE]] and click on "What links here". local function track(page) require(debug_track_module)("place/" .. page) return true end local function ucfirst_all(text) if text:find(" ") then local parts = split(text, " ", true) for i, part in ipairs(parts) do parts[i] = m_strutils.ucfirst(part) end return concat(parts, " ") else return m_strutils.ucfirst(text) end end local function lc(text) return mw.getContentLanguage():lc(text) end ---------- Argument parsing functions and utilities -- Split an argument on comma, but not comma followed by whitespace. local function split_on_comma(val) if val:find(",") then return require(parse_interface_module).split_on_comma(val) else return {val} end end -- Split an argument on slash, but not slash occurring inside of HTML tags like </span> or <br />. local function split_on_slash(arg) if arg:find("<") then local m_parse_utilities = require(parse_utilities_module) -- We implement this by parsing balanced segment runs involving <...>, and splitting on slash in the remainder. -- The result is a list of lists, so we have to rejoin the inner lists by concatenating. local segments = m_parse_utilities.parse_balanced_segment_run(arg, "<", ">") local slash_separated_groups = m_parse_utilities.split_alternating_runs(segments, "/") for i, group in ipairs(slash_separated_groups) do slash_separated_groups[i] = concat(group) end return slash_separated_groups else return split(arg, "/", true) end end -- Implement "implications", i.e. where the presence of a given holonym causes additional holonym(s) to be added. -- Implications apply only to categorization. There used to be support for "general implications" that applied to both -- display and categorization, but there ended up not being any such implications, so we've removed the support. It is -- a bad idea in any case to have such implications; the user might purposely leave out a higher-level polity to avoid -- redundancy in several successive definitions, and we wouldn't want to override that. Note that in practice the -- mechanism implemented by this function is used specifically for non-administrative geographic regions such as -- Eastern Europe and the West Bank; there is a similar mechanism for administrative regions handled by -- `augment_holonyms_with_containing_polity` in [[Module:place/placetypes]]. -- -- `place_descriptions` is a list of place descriptions (see top of file, collectively describing the data passed to -- {{place}}). `implication_data` is the data used to implement the implications, i.e. a table indexed by holonym -- placetype, each value of which is a table indexed by holonym placename, each value of which is a list of -- "PLACETYPE/PLACENAME" holonyms to be added to the end of the list of holonyms. local function handle_category_implications(place_descriptions, implication_data) for i, desc in ipairs(place_descriptions) do if desc.holonyms then local new_holonyms = {} for _, holonym in ipairs(desc.holonyms) do insert(new_holonyms, holonym) local imp_data = m_placetypes.get_equiv_placetype_prop(holonym.placetype, function(pt) local implication = implication_data[pt] and implication_data[pt][holonym.unlinked_placename] if implication then return implication end end) if imp_data then for _, holonym_to_add in ipairs(imp_data) do local split_holonym = split_on_slash(holonym_to_add) if #split_holonym ~= 2 then internal_error("Invalid holonym in implications: %s", holonym_to_add) end local holonym_placetype, holonym_placename = unpack(split_holonym, 1, 2) local new_holonym = { -- By the time we run, the display has already been generated so we don't need to set -- display_placename. placetype = holonym_placetype, unlinked_placename = holonym_placename } insert(new_holonyms, new_holonym) m_placetypes.key_holonym_into_place_desc(desc, new_holonym) end end end desc.holonyms = new_holonyms end end end -- Split a holonym (e.g. "continent/Europe" or "country/en:Italy" or "in southern" or "r:suf/O'Higgins" or -- "c/Austria,Germany,Czech Republic") into its components. Return a list of holonym objects (see top of file). Note -- that if there isn't a slash in the holonym (e.g. "in southern"), the `placetype` field of the holonym will be nil. -- Placetype aliases (e.g. "r" for "region") and placename aliases (e.g. "US" or "USA" for "United States") will be -- expanded. local function split_holonym(raw) local no_display, combined_holonym = raw:match("^(!)(.*)$") no_display = not not no_display combined_holonym = combined_holonym or raw local suppress_comma, combined_holonym_without_comma = combined_holonym:match("^(%*)(.*)$") suppress_comma = not not suppress_comma combined_holonym = combined_holonym_without_comma or combined_holonym local holonym_parts = split_on_slash(combined_holonym) if #holonym_parts == 1 then -- `unlinked_placename` should not be used. return {{display_placename = combined_holonym, no_display = no_display, suppress_comma = suppress_comma}} end -- Rejoin further slashes in case of slash in holonym placename, e.g. Admaston/Bromley. local placetype = holonym_parts[1] local placename = concat(holonym_parts, "/", 2) -- Check for modifiers after the holonym placetype. local split_holonym_placetype = split(placetype, ":", true) placetype = split_holonym_placetype[1] local affix_type local saw_also local saw_the for i = 2, #split_holonym_placetype do local modifier = split_holonym_placetype[i] if modifier == "also" then if saw_also then error(("Modifier ':also' occurs twice in holonym '%s'"):format(combined_holonym)) end saw_also = true elseif modifier == "the" then if saw_the then error(("Modifier ':the' occurs twice in holonym '%s'"):format(combined_holonym)) end saw_the = true elseif modifier == "pref" or modifier == "Pref" or modifier == "suf" or modifier == "Suf" or modifier == "noaff" then if affix_type then error(("Affix-type modifier ':%s' occurs twice in holonym '%s'"):format(modifier, combined_holonym)) end affix_type = modifier else error(("Unrecognized holonym placetype modifier '%s', should be one of " .. "'pref', 'Pref', 'suf', 'Suf', 'noaff', 'also' or 'the'"):format(modifier)) end end placetype = m_placetypes.resolve_placetype_aliases(placetype) local holonyms = split_on_comma(placename) local pluralize_affix = #holonyms > 1 local affix_holonym_index = (affix_type == "pref" or affix_type == "Pref") and 1 or affix_type == "noaff" and 0 or #holonyms for i, placename in ipairs(holonyms) do -- Check for langcode before the holonym placename, but don't get tripped up by Wikipedia links, which begin -- "[[w:...]]" or "[[wikipedia:]]". local langcode, placename_without_langcode = rmatch(placename, "^([^%[%]]-):(.*)$") if langcode then placename = placename_without_langcode end placename = m_placetypes.resolve_placename_display_aliases(placetype, placename) holonyms[i] = { placetype = placetype, display_placename = placename, unlinked_placename = m_placetypes.remove_links_and_html(placename), langcode = langcode, affix_type = i == affix_holonym_index and affix_type or nil, pluralize_affix = i == affix_holonym_index and pluralize_affix, suppress_affix = i ~= affix_holonym_index, no_display = no_display, suppress_comma = suppress_comma, continue_cat_loop = saw_also, force_the = i == 1 and saw_the, } end return holonyms end local get_param_mods = memoize(function() local m_param_utils = require(parameter_utilities_module) return m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, {param = "eq"}, -- FIXME: Finish [[Module:format utilities]]. --{param = "conj", set = require(format_utilities_module).allowed_conjs_for_join_segments, overall = true}, {param = "conj", set = {["and"] = true, ["or"] = true, ["and/or"] = true}, overall = true}, } end) local function parse_term_with_inline_modifiers(term, paramname, default_lang) -- FIXME: Finish changes to [[Module:parameter utilities]] and [[Module:parse utilities]] that support continuations -- and new-format generate_obj(). --local function generate_obj(data) -- local m_param_utils = require(parameter_utilities_module) -- data.parse_lang_prefix = true -- data.special_continuations = m_param_utils.default_special_continuations -- data.default_lang = default_lang -- local obj = m_param_utils.generate_obj_maybe_parsing_lang_prefix(data) -- obj.show_decorations = true -- return obj --end local function generate_obj(raw_term, parse_err) local obj = require(parse_utilities_module).generate_obj_maybe_parsing_lang_prefix { term = raw_term, parse_err = parse_err, parse_lang_prefix = true, } obj.lang = obj.lang or default_lang obj.show_decorations = true return obj end return require(parse_interface_module).parse_inline_modifiers(term, { paramname = paramname, param_mods = get_param_mods(), generate_obj = generate_obj, -- FIXME: See above. --generate_obj_new_format = true, splitchar = ",", outer_container = {}, }) end local function parse_form_of_directive(arg, lang, form_of_overridden_args) local form_of_directive, raw_terms = arg:match("^@([a-z -]+):(.*)$") if not form_of_directive then error("Misformatted @-directive: " .. dump(arg)) end if not export.all_form_of_directives[form_of_directive] then local known_directives = {} for k, _ in pairs(export.all_form_of_directives) do insert(known_directives, '"' .. k .. '"') end table.sort(known_directives) error(("Unrecognized form-of directive %s in @-directive %s; recognized directives are %s"):format( dump(form_of_directive), dump(arg), concat(known_directives, ", "))) end local spec = export.all_form_of_directives[form_of_directive] local canonical_directive = form_of_directive if spec.alias_of then canonical_directive = spec.alias_of spec = export.all_form_of_directives[canonical_directive] if not spec then internal_error("Form-of directive alias %s points to %s, which is not a directive", "@" .. form_of_directive, canonical_directive) elseif spec.alias_of then internal_error("Form-of directive alias %s points to %s, which is also an alias", "@" .. form_of_directive, canonical_directive) end end local default_foreign = spec.default_foreign local directive_param = "@" .. form_of_directive if form_of_overridden_args and form_of_overridden_args[canonical_directive] then raw_terms = form_of_overridden_args[canonical_directive].new_value local new_directive = form_of_overridden_args[canonical_directive].new_directive local new_spec = export.all_form_of_directives[new_directive] if not new_spec then error(("Internal error: [[Module:transclude]] passed in unrecognized replacement directive '@%s'"): format(new_directive)) end if new_spec.alias_of then error(("Internal error: [[Module:transclude]] passed in replacement directive alias '@%s', " .. "should be canonical"):format(new_directive)) end if new_directive ~= canonical_directive then directive_param = directive_param .. (" (replaced with @%s)"):format(new_directive) canonical_directive = new_directive spec = new_spec end default_foreign = true end local terms = parse_term_with_inline_modifiers(raw_terms, directive_param, default_foreign and lang or enlang) return { directive = canonical_directive, terms = terms.terms, conj = terms.conj, spec = spec, } end -- Parse an argument containing extra information that is sometimes added to a definition, such as the capital, largest -- city, modern name, official name, etc. `args` is the value from the parsed argument structure and can be either nil, -- a string or a list (depending on whether it was declared as a single parameter or a list). `spec` is the extra info -- spec corresponding to the type of extra info. Each value in `args` can be a comma-separated list of terms with inline -- modifiers attached. [FIXME: we should switch to always using the comma-separated format and disallow list parameters -- such as |capital=, |capital2=, etc.] The return value is a structure containing fields `terms` (a list of term -- objects, each of which is in the format expected by full_link() in [[Module:links]]), `conj` (an explicit -- conjunction to join multiple terms, or nil if no explicit conjunction was given) and `spec` (the passed-in spec). local function parse_extra_info_arg(args, spec, default_lang) if not args then return nil end if type(args) ~= "table" then args = {args} end if not args[1] then return nil end local terms = nil local conj for i, arg in ipairs(args) do local this_terms = parse_term_with_inline_modifiers(arg, spec.arg .. (i == 1 and "" or i), default_lang) local thisconj = this_terms.conj if not conj then conj = thisconj elseif thisconj and conj ~= thisconj then error(("Two different conjunctions '%s' and '%s' specified for |%s=; you only need to specify the " .. "conjunction once"):format(conj, thisconj)) end if not terms then terms = this_terms.terms else m_table.extend(terms, this_terms.terms) end end return { spec = spec, terms = terms, conj = conj, } end --[==[ Parse a "new-style" place description, with placetypes and holonyms surrounded by `<<...>>` amid otherwise raw text. Return value is a place description object as documented at the top of the file. Exported for use by [[Module:demonyms]]. ]==] function export.parse_new_style_place_desc(text, lang, form_of_directives, form_of_overridden_args) local placetypes = {} local segments = split(text, "<<(.-)>>") local retval = {holonyms = {}, order = {}} local form_of_directives_already_present = form_of_directives and not not form_of_directives[1] for i, segment in ipairs(segments) do if i % 2 == 1 then insert(retval.order, {type = "raw", value = segment}) elseif segment:find("@") then if not form_of_directives then error(("Form-of directive '%s' not allowed in this context"):format(segment)) elseif form_of_directives_already_present then error(("Saw form-of directive '%s' in new-style place desc followed by direct (separate-parameter) form-of directives; not allowed"):format( segment)) elseif placetypes[1] or retval.holonyms[1] then error(("Form-of directive '%s' must come first, before placetypes and holonyms"):format(segment)) else local form_of_directive = parse_form_of_directive(segment, lang, form_of_overridden_args) if not retval.order[1] or retval.order[1].type ~= "raw" or retval.order[2] then internal_error("`retval.order` should have a single raw element: %s", retval.order) end form_of_directive.pretext = retval.order[1].value retval.order[1] = nil insert(form_of_directives, form_of_directive) end elseif segment:find("/") then local holonyms = split_holonym(segment) for j, holonym in ipairs(holonyms) do if j > 1 then if not holonym.no_display then if j == #holonyms then insert(retval.order, {type = "raw", value = " and "}) else insert(retval.order, {type = "raw", value = ", "}) end end -- All but the first in a multi-holonym need an article. For the first one, the article is -- specified in the raw text if needed. (Currently, needs_article is only used when displaying the -- holonym, so it wouldn't matter when no_display is set, but we set it anyway in case we need it -- for something else.) holonym.needs_article = true end insert(retval.holonyms, holonym) if not holonym.no_display then insert(retval.order, {type = "holonym", value = #retval.holonyms}) end m_placetypes.key_holonym_into_place_desc(retval, holonym) end else local treat_as, display = segment:match("^(..-):(.+)$") if treat_as then segment = treat_as else display = segment end -- see if the placetype segment is just qualifiers local only_qualifiers = true local split_segments = split(segment, " ", true) for _, split_segment in ipairs(split_segments) do if m_placetypes.placetype_qualifiers[split_segment] == nil then only_qualifiers = false break end end insert(placetypes, {placetype = segment, only_qualifiers = only_qualifiers}) if only_qualifiers then insert(retval.order, {type = "qualifier", value = display}) else insert(retval.order, {type = "placetype", value = display}) end end end if not form_of_directives_already_present and form_of_directives and form_of_directives[1] then form_of_directives[#form_of_directives].posttext = "" end local final_placetypes = {} for i, placetype in ipairs(placetypes) do if i > 1 and placetypes[i - 1].only_qualifiers then final_placetypes[#final_placetypes] = final_placetypes[#final_placetypes] .. " " .. placetypes[i].placetype else insert(final_placetypes, placetypes[i].placetype) end end retval.placetypes = final_placetypes return retval end --[==[ Parse one or more "new-style" place descriptions, with placetypes and holonyms surrounded by `<<...>>` amid otherwise raw text. Multiple descriptions are separated by two semicolons in a row. Return value is a list of place description objects as documented at the top of the file. ]==] local function parse_conjoined_new_style_place_desc(text, lang, form_of_directives, form_of_overridden_args) local separate_specs = split(text, ";(;[^ ]*)") local descs = {} for i = 1, #separate_specs do if i % 2 == 1 then insert(descs, export.parse_new_style_place_desc(separate_specs[i], lang, form_of_directives, form_of_overridden_args)) form_of_directives = nil else descs[#descs].separator = separate_specs[i] end end return descs end --[=[ Process numeric and "extra info" arguments into an overall place spec, as described at the top of the file. `data` is an object with the following fields: * `args`: The parsed arguments of {{tl|place}}. * `from_tcl`: True if we're being invoked from {{tl|tcl}}. * `extra_info_overridden_set`, `form_of_overridden_args`: Same as the corresponding fields in the `data` object passed to `export.format`. ]=] local function parse_overall_place_spec(data) local args, from_tcl, extra_info_overridden_set, form_of_overridden_args = data.args, data.from_tcl, data.extra_info_overridden_set, data.form_of_overridden_args local descs = {} local this_desc -- Index of separate (semicolon-separated) place descriptions within `descs`. local desc_index = 1 -- Index of separate holonyms within a place description. 0 means we've seen no holonyms and have yet to process -- the placetypes that precede the holonyms. 1 means we've seen no holonyms but have already processed the -- placetypes. local holonym_index = 0 local in_place_desc = false local form_of_directives = {} local function set_desc_joiner(desc, separator) if separator == ";" then this_desc.joiner = "; " this_desc.include_following_article = true elseif separator == ";;" then this_desc.joiner = " " else local joiner = separator:sub(2) if rfind(joiner, "^%a") then this_desc.joiner = " " .. joiner .. " " else this_desc.joiner = joiner .. " " end end end for _, arg in ipairs(args[2]) do if arg:find("^@") then if not (desc_index == 1 and holonym_index == 0) then error("@-directives cannot follow place descriptions") end local form_of_directive = parse_form_of_directive(arg, args[1], form_of_overridden_args) if form_of_directives[1] then form_of_directive.pretext = ", " else form_of_directive.pretext = "" end insert(form_of_directives, form_of_directive) elseif arg == ";" or arg:find("^;[^ ]") then if not this_desc then error("Saw semicolon joiner without preceding place description") end set_desc_joiner(this_desc, arg) desc_index = desc_index + 1 holonym_index = 0 in_place_desc = false else if arg:find("<<") then if in_place_desc then error("New-style place description must come first or following a separator (semicolon or similar), not directly following another description") end in_place_desc = true local this_descs = parse_conjoined_new_style_place_desc(arg, args[1], form_of_directives, form_of_overridden_args) for j, desc in ipairs(this_descs) do this_desc = desc if holonym_index > 0 then desc_index = desc_index + 1 holonym_index = 0 end if j < #this_descs then set_desc_joiner(this_desc, this_desc.separator) end descs[desc_index] = this_desc last_was_new_style = true holonym_index = #this_desc.holonyms + 1 end else -- Old-style arguments can directly follow a new-style argument; they become additional holonyms -- tacked onto the end of the holonym list, and are displayed old-style except that there is no -- prefix before the first one following the new-style argument. in_place_desc = true if holonym_index == 0 then local entry_placetypes = split_on_slash(arg) this_desc = {placetypes = entry_placetypes, holonyms = {}} descs[desc_index] = this_desc holonym_index = holonym_index + 1 else local holonyms = split_holonym(arg) for j, holonym in ipairs(holonyms) do if j > 1 then -- All but the first in a multi-holonym need an article. Not for the first one because e.g. -- {{place|en|city|s/Arizona|c/United States}} should not display as "a city in Arizona, the -- United States". The overall first holonym in the place description gets an article if -- needed regardless of our setting here. holonym.needs_article = true -- Insert "and" before the last holonym. if j == #holonyms then this_desc.holonyms[holonym_index] = { -- Use the no_display value from the first holonym; it should be the same for all -- holonyms. `unlinked_placename` should not be used. display_placename = "and", no_display = holonyms[1].no_display } holonym_index = holonym_index + 1 end end this_desc.holonyms[holonym_index] = holonym m_placetypes.key_holonym_into_place_desc(this_desc, this_desc.holonyms[holonym_index]) holonym_index = holonym_index + 1 end end end end end if form_of_directives[1] and not form_of_directives[#form_of_directives].posttext then form_of_directives[#form_of_directives].posttext = (args.def and args.def ~= "-" or not args.def and descs[1]) and ": " or "" end -- Tracking code. This does nothing but add tracking for seen placetypes and qualifiers. The place will be linked to -- [[Wiktionary:Tracking/place/entry-placetype/PLACETYPE]] for all entry placetypes seen; in addition, if PLACETYPE -- has qualifiers (e.g. 'small city'), there will be links for the bare placetype minus qualifiers and separately -- for the qualifiers themselves: -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/BARE_PLACETYPE]] -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/QUALIFIER]] -- Note that if there are multiple qualifiers, there will be links for each possible split. For example, for -- 'small maritime city'), there will be the following links: -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/small maritime city]] -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/maritime city]] -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-placetype/city]] -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/small]] -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/entry-qualifier/maritime]] -- Finally, there are also links for holonym placetypes, e.g. if the holonym 'c/Italy' occurs, there will be the -- following link: -- [[Special:WhatLinksHere/Wiktionary:Tracking/place/holonym-placetype/country]] for _, desc in ipairs(descs) do for _, entry_placetype in ipairs(desc.placetypes) do local splits = m_placetypes.split_qualifiers_from_placetype(entry_placetype, "no canon qualifiers") for _, split in ipairs(splits) do local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3) track("entry-placetype/" .. bare_placetype) if this_qualifier then track("entry-qualifier/" .. this_qualifier) end end end for _, holonym in ipairs(desc.holonyms) do if holonym.placetype then track("holonym-placetype/" .. holonym.placetype) end end end local extra_info = {} for _, extra_info_spec in ipairs(export.extra_info_args) do local extra_info_terms = parse_extra_info_arg(args[extra_info_spec.arg], extra_info_spec, -- If called from {{tcl}} and extra info argument was set by {{tcl}}, interpret the argument -- according to the language in 1=; otherwise interpret as English. To override this, prefix -- with the appropriate language. from_tcl and extra_info_overridden_set and extra_info_overridden_set[extra_info_spec.arg] and args[1] or enlang) if extra_info_terms then insert(extra_info, extra_info_terms) end end return { lang = args[1], args = args, directives = form_of_directives, descs = descs, extra_info = extra_info, } end -------- Definition-generating functions -- Return a string with the wikilinks to the English translations of the word. local function get_translations(transl, ids) local ret = {} for i, t in ipairs(transl) do local arg_transls = split_on_comma(t) local arg_ids = ids[i] if arg_ids then arg_ids = split_on_comma(arg_ids) if #arg_transls ~= #arg_ids then error(("Saw %s translation%s in t%s=%s but %s ID%s in tid%s=%s"):format( #arg_transls, #arg_transls > 1 and "s" or "", i == 1 and "" or i, t, #arg_ids, #arg_ids > 1 and "'s" or "", i == 1 and "" or i, ids[i])) end end for j, arg_transl in ipairs(arg_transls) do insert(ret, link(arg_transl, "en", arg_ids and arg_ids[j] or nil)) end end return concat(ret, ", ") end -- Return the article (currently always `"the"`) to be prepended to the given placename, or nil. `decorated_placename` -- is the placename as specified by the user along with any affix added to it. `placename` is the raw unlinked -- placename, defaulting to the unlinked version of `decorated_placename` if not given. `placetypes` is a placetype or -- list of placetypes for the placename. `suppress_holonym_use_the_check` suppresses checking the placetypes for -- `holonym_use_the`. local function get_placename_article(decorated_placename, placetypes, placename, suppress_holonym_use_the_check) local unlinked_decorated_placename = m_placetypes.remove_links_and_html(decorated_placename) if unlinked_decorated_placename:find("^the ") then return nil end placename = placename or unlinked_decorated_placename if type(placetypes) == "string" then placetypes = {placetypes} end for _, placetype in ipairs(placetypes) do local art = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) local art = m_placetypes.placename_article[pt] and m_placetypes.placename_article[pt][placename] if art then return art end end) if art then return art end end -- Get equivalent placetypes of the specified placetype so that e.g. -- {{place|en|@official name of:Bahamas|island country|r/Caribbean}} put 'the' before Bahamas ("Bahamas" is just -- specified as a country but "island country" falls back to "country"). local all_equiv_placetypes = {} for _, placetype in ipairs(placetypes) do local this_equiv_placetypes = m_placetypes.get_placetype_equivs(placetype) for _, this_equiv_placetype in ipairs(this_equiv_placetypes) do insert(all_equiv_placetypes, this_equiv_placetype.placetype) end end -- Look for a known location. We should be using find_matching_holonym_location() but that function doesn't -- currently work without alias resolution. Instead we check if any matching location has `the = true` set. -- In practice there aren't any cases where a given placename matches two locations, only one of which has -- `the = true` set. for group, key, spec in m_placetypes.iterate_matching_location { placetypes = all_equiv_placetypes, placename = placename, alias_resolution = "none", } do -- `iterate_holonym_location` doesn't initialize the spec if alias resolution is turned off, so check both -- the spec and group. Be careful in case `the = false` is explicitly given by the spec. if spec.the ~= nil then if spec.the then return "the" end elseif group.default_the then return "the" end end if not suppress_holonym_use_the_check then -- See if the placetype requests an article to be placed before the placename. This occurs e.g. with 'sea'. But -- if the user specifies e.g. "sea:pref/Cortez", we'll wrongly get "the sea of the Cortez", so in that case we -- need to ignore the holonym article specified along with the placetype. for _, placetype in ipairs(placetypes) do local holonym_use_the = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) return placetype_data[pt] and placetype_data[pt].holonym_use_the end) if holonym_use_the then return "the" end end end local universal_res = m_placetypes.placename_the_re["*"] for _, re in ipairs(universal_res) do if unlinked_decorated_placename:find(re) then return "the" end end for _, placetype in ipairs(placetypes) do local matched = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) local res = m_placetypes.placename_the_re[pt] if not res then return nil end for _, re in ipairs(res) do if unlinked_decorated_placename:find(re) then return true end end return nil end) if matched then return "the" end end return nil end -- Prepend the appropriate article if needed to `decorated_placename` (the user-specified placename with any affix -- added), where the underlying holonym object that generated `linked_placename` can be found at `holonym_index` in the -- holonyms in `place_desc`. local function get_holonym_article(decorated_placename, place_desc, holonym_index) local holonym = place_desc.holonyms[holonym_index] local holonym_placetype = holonym.placetype if not holonym_placetype then return nil end return get_placename_article(decorated_placename, holonym_placetype, holonym.unlinked_placename, not not holonym.affix_type) end -- Convert a holonym into display format. This adds wikilinks to holonyms and passes them through any display handlers, -- which may (e.g.) add the placetype to the holonym. If `needs_article` is true, prepend the article `"the"` if the -- holonym requires it (e.g. if the holonym is `United States`). `needs_article` is set to true we are processing the -- first specified holonym in an old-style place description (i.e. the holonym directly following the entry placetype, -- with no raw-text holonym in between). -- -- Examples: -- ({placetype = "country", display_placename = "United States", unlinked_placename = "United States"}, true) returns -- the template-expanded equivalent of "the {{l|en|United States}}". -- ({placetype = "region", display_placename = "O'Higgins", unlinked_placename = "O'Higgins", affix_type = "suf"}, false) -- returns the template-expanded equivalent of "{{l|en|O'Higgins}} region". -- ({display_placename = "in the southern"}, false) returns "in the southern" (without wikilinking because .placetype -- and .langcode are both nil). local function format_holonym(place_desc, holonym_index, needs_article) local holonym = place_desc.holonyms[holonym_index] if holonym.no_display then return "" end local orig_needs_article = needs_article needs_article = needs_article or holonym.needs_article or holonym.force_the local output = holonym.display_placename local placetype = holonym.placetype local affix_type_pt_data, affix_type, affix_is_prefix, affix, prefix, suffix, no_affix_strings local pt_equiv_for_affix_type, already_seen_affix, need_affix -- Implement display handlers. local display_handler = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) return placetype_data[pt] and placetype_data[pt].display_handler end) if display_handler then output = display_handler(placetype, output) end if not holonym.suppress_affix then -- Implement adding an affix (prefix or suffix) based on the holonym's placetype. The affix will be -- added either if the placetype's placetype_data spec says so (by setting 'affix_type'), or if the -- user explicitly called for this (e.g. by using 'r:suf/O'Higgins'). Before adding the affix, -- however, we check to see if the affix is already present (e.g. the placetype is "district" -- and the placename is "Mission District"). The placetype can override the affix to add (by setting -- `prefix`, `suffix` or `affix`) and/or override the strings used for checking if the affix is already -- present (by setting 'no_affix_strings', which defaults to the affix explicitly given through `prefix`, -- `suffix` or `affix` if any are given). `prefix` and `suffix` take precedence over `affix` if both are -- set, but only when the appropriate type of affix is requested. -- Search through equivalent placetypes for a setting of `affix_type`, `affix`, `prefix` or `suffix`. If we -- find any, use them. If `affix_type` is given, it is overridden by the user's explicitly specified affix -- type. If either an `affix_type` is found or the user explicitly specified an affix type, the affix is -- displayed according to the following: -- 1. If `prefix`, `suffix` or `affix` is given by the placetype or equivalent placetypes, use it (e.g. -- placetype `administrative region` requests suffix "region" but doesn't set affix type; if the user -- explicitly specifies `administrative region` as the placetype for a holonym and specifies a suffixal -- affix type, use "region"). In this search, we stop looking if we find an explicit `affix_type` -- setting; if this is found without an associated affix setting, the assumption is the associated -- placetype was intended as the affix, not some explicit affix setting associated with a fallback -- placetype. -- 2. Otherwise, if the user explicitly requested an affix type, use the actual placetype (principle of -- least surprise). -- 3. Finally, fall back to the placetype associated with an explicit `affix_type` setting (which will -- always exist if we get this far). affix_type_pt_data, pt_equiv_for_affix_type = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) local cdpt = placetype_data[pt] return cdpt and cdpt.affix_type and cdpt or nil end ) affix_pt_data, pt_equiv_for_affix = m_placetypes.get_equiv_placetype_prop(placetype, function(pt) local cdpt = placetype_data[pt] return cdpt and (cdpt.affix_type or cdpt.affix or cdpt.prefix or cdpt.suffix) and cdpt or nil end ) if affix_type_pt_data then affix_type = affix_type_pt_data.affix_type need_affix = true end if affix_pt_data then prefix = affix_pt_data.prefix or affix_pt_data.affix suffix = affix_pt_data.suffix or affix_pt_data.affix need_affix = true end no_affix_strings = affix_pt_data and affix_pt_data.no_affix_strings or affix_type_pt_data and affix_type_pt_data.no_affix_strings if holonym.affix_type and placetype then affix_type = holonym.affix_type prefix = prefix or placetype suffix = suffix or placetype need_affix = true end if need_affix then -- At this point the affix_type has been determined and can't change any more, so we can figure out -- whether we need the calculated prefix or suffix. affix_is_prefix = affix_type == "pref" or affix_type == "Pref" if affix_is_prefix then affix = prefix else affix = suffix end if not affix then if not pt_equiv_for_affix_type then internal_error("Something wrong, `pt_equiv_for_affix_type` not set processing holonym: %s", holonym) end affix = pt_equiv_for_affix_type.placetype if not affix then internal_error("Something wrong, no affix could be located in `pt_equiv_for_affix_type` for " .. "holonym %s: %s", holonym, pt_equiv_for_affix_type) end end no_affix_strings = no_affix_strings or lc(affix) if holonym.pluralize_affix then affix = m_placetypes.pluralize_placetype(affix) end already_seen_affix = m_placetypes.check_already_seen_string(output, no_affix_strings) end end output = link(output, holonym.langcode or placetype and "en" or nil) if need_affix and not affix_is_prefix and not already_seen_affix then output = output .. " " .. (affix_type == "Suf" and ucfirst_all(affix) or affix) end if needs_article then local article = holonym.force_the and "the" or get_holonym_article(output, place_desc, holonym_index) if article then output = article .. " " .. output end end if affix_is_prefix and not already_seen_affix then output = (affix_type == "Pref" and ucfirst_all(affix) or affix) .. " of " .. output if orig_needs_article then -- Put the article before the added affix if we're the first holonym in the place description. This is -- distinct from the article added above for the holonym itself; cf. "c:pref/United States,Canada" -> -- "the countries of the United States and Canada". We need to use the value of `needs_article` passed -- in from the function, which indicates whether we're processing the first holonym. output = "the " .. output end end return output end -- Format a holonym for display, taking into account the entry's placetype (specifically, the last placetype if there -- are more than one, excluding conjunctions and parenthetical items); the holonym's index among the holonyms in the -- template (which specifies what the previous holonym is and whether it is the first holonym); and the full place -- description (which helps resolve ambiguities in holonyms when looking up known locations). This may involve putting a -- preposition ("in" or "of") before the formatted holonym, particularly if it is the first one, and may involve -- prepending a comma. If `holonym_no_prefix` is specified, nothing except a space is put before the holonym; used -- when formatting mixed new/old-style descriptions. local function format_holonym_in_context(entry_placetype, place_desc, holonym_index, holonym_no_prefix) local desc = "" -- If holonym.placetype is nil, the holonym is just raw text, e.g. 'in southern'. if holonym_no_prefix then desc = " " else local holonym = place_desc.holonyms[holonym_index] if not holonym.no_display then -- First compute the initial delimiter. if holonym_index == 1 then if holonym.placetype then desc = desc .. " " .. m_placetypes.get_placetype_entry_preposition(entry_placetype) .. " " elseif not holonym.display_placename:find("^,") then desc = desc .. " " end else local prev_holonym = place_desc.holonyms[holonym_index - 1] if prev_holonym.placetype and not holonym.suppress_comma then local dname = holonym.display_placename if dname ~= "and" and dname ~= "in" and dname ~= "and the" and dname ~= "in the" then desc = desc .. "," end end if holonym.placetype or not holonym.display_placename:find("^,") then desc = desc .. " " end end end end return desc .. format_holonym(place_desc, holonym_index, not holonym_no_prefix and holonym_index == 1) end -- Return the linked description of a placetype. This splits off any qualifiers and displays them separately. local function get_placetype_description(placetype) local splits = m_placetypes.split_qualifiers_from_placetype(placetype) local prefix = "" for _, split in ipairs(splits) do local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3) if this_qualifier then prefix = (prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier) .. " " else prefix = "" end local display_form = m_placetypes.get_placetype_display_form(bare_placetype) if display_form then return prefix .. display_form end placetype = bare_placetype end return prefix .. placetype end -- Return the linked description of a qualifier (which may be multiple words). local function get_qualifier_description(qualifier) local splits = m_placetypes.split_qualifiers_from_placetype(qualifier .. " foo") local split = splits[#splits] local prev_qualifier, this_qualifier, bare_placetype = unpack(split, 1, 3) return prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier end -- Format a set of form-of directive terms. local function format_form_of_directive(overall_place_spec, directive_terms, ucfirst, from_tcl) local formatted_terms = {} local placetypes if not overall_place_spec.descs[2] then placetypes = overall_place_spec.descs[1].placetypes else placetypes = {} for _, desc in ipairs(overall_place_spec.descs) do m_table.extend(placetypes, desc.placetypes) end end for _, termobj in ipairs(directive_terms.terms) do local placename_article if not termobj.alt and termobj.term and not termobj.term:find("%[%[") then placename_article = get_placename_article(termobj.term, placetypes) end local linked_term = m_links.full_link(termobj, "term") linked_term = "<span class='form-of-definition-link'>" .. linked_term .. "</span>" if termobj.eq then linked_term = linked_term .. " (= " .. m_links.full_link {term = termobj.eq, lang = enlang} .. ")" end if placename_article then linked_term = placename_article .. " " .. linked_term end insert(formatted_terms, linked_term) end local spec = directive_terms.spec local text = spec.text if type(text) == "function" then text = text(overall_place_spec) end if text == "+" then text = directive_terms.directive end if ucfirst then text = m_strutils.ucfirst(text) end if not from_tcl then local tracking_prefix = "form-of/" .. directive_terms.directive track(tracking_prefix) local langcode = overall_place_spec.lang:getCode() local full_langcode = overall_place_spec.lang:getFullCode() track(tracking_prefix .. "/" .. langcode) if full_langcode ~= langcode then track(tracking_prefix .. "/" .. full_langcode) end if full_langcode ~= "en" then track(tracking_prefix .. "/non-english") end end return (require(form_of_module).format_form_of { text = text, lemmas = m_table.serialCommaJoin(formatted_terms, {conj = directive_terms.conj or spec.conjunction or "and"}), lemma_classes = false, -- text_classes = "place-text", }) end -- Format a set of extra-info terms for extra information that is sometimes added to a definition, such as the capital, -- largest city, modern name, official name, etc. `overall_place_spec` is the overall parsed {{tl|place}} spec (see -- comment at top of file); `extra_info_terms` is the terms spec for this type of extra-info (as returned by -- `parse_extra_info_arg`); and `sentence_style` indicates whether we're generating a sentence-style definition (as -- suitable for an English-language term without a translation specified using t=). local function format_extra_info(overall_place_spec, extra_info_terms, sentence_style) local formatted_terms = {} for _, termobj in ipairs(extra_info_terms.terms) do insert(formatted_terms, m_links.full_link(termobj)) end local spec = extra_info_terms.spec local text = spec.text if type(text) == "function" then text = text(overall_place_spec) end if text == "+" then text = spec.arg end if spec.auto_plural and formatted_terms[2] then text = pluralize(text) end if spec.with_colon then text = text .. ":" end if sentence_style and spec.match_sentence_style then text = ". " .. m_strutils.ucfirst(text) else text = "; " .. text end -- FIME: Use joinSegments when available. -- return text .. " " .. -- m_table.joinSegments(formatted_terms, {conj = extra_info_terms.conj or spec.conjunction or "and"}) return text .. " " .. m_table.serialCommaJoin(formatted_terms, {conj = extra_info_terms.conj or spec.conjunction or "and"}) end -- Format an old-style place description (with separate arguments for the placetype and each holonym) for display and -- return the resulting string. local function format_old_style_place_desc_for_display(args, place_desc, desc_index, with_article, ucfirst) -- The placetype used to determine whether "in" or "of" follows is the last placetype if there are -- multiple slash-separated placetypes, but ignoring "and", "or" and parenthesized notes -- such as "(one of 254)". local entry_placetype = nil local placetypes = place_desc.placetypes local function is_and_or(item) return item == "and" or item == "or" end local parts = {} local function ins(txt) insert(parts, txt) end local function ins_space() if #parts > 0 then ins(" ") end end local and_or_pos for i, placetype in ipairs(placetypes) do if is_and_or(placetype) then and_or_pos = i -- no break here; we want the last in case of more than one end end local remaining_placetype_index if and_or_pos then track("multiple-placetypes-with-and") if and_or_pos == #placetypes then error("Conjunctions 'and' and 'or' cannot occur last in a set of slash-separated placetypes: " .. concat(placetypes, "/")) end local items = {} for i = 1, and_or_pos + 1 do local pt = placetypes[i] if is_and_or(pt) then -- skip elseif i > 1 and pt:find("^%(") then -- append placetypes beginning with a paren to previous item items[#items] = items[#items] .. " " .. pt else entry_placetype = pt insert(items, get_placetype_description(pt)) end end ins(m_table.serialCommaJoin(items, {conj = placetypes[and_or_pos]})) remaining_placetype_index = and_or_pos + 2 else remaining_placetype_index = 1 end for i = remaining_placetype_index, #placetypes do local pt = placetypes[i] -- Check for and, or and placetypes beginning with a paren (so that things like -- "{{place|en|county/(one of 254)|s/Texas}}" work). if m_placetypes.placetype_is_ignorable(pt) then ins_space() ins(pt) else entry_placetype = pt -- Join multiple placetypes with comma unless placetypes are already -- joined with "and". We allow "the" to precede the second placetype -- if they're not joined with "and" (so we get "city and county seat of ..." -- but "city, the county seat of ..."). if i > 1 then ins(", ") local article = m_placetypes.get_placetype_article(pt) if article ~= "the" and i > remaining_placetype_index then -- Track cases where we are comma-separating multiple placetypes without the second one starting -- with "the", as they may be mistakes. The occurrence of "the" is usually intentional, e.g. -- {{place|zh|municipality/state capital|s/Rio de Janeiro|c/Brazil|t1=Rio de Janeiro}} -- for the city of [[Rio de Janeiro]], which displays as "a municipality, the state capital of ...". track("multiple-placetypes-without-and-or-the") end if article then ins(article) ins(" ") end end ins(get_placetype_description(pt)) end end if place_desc.holonyms then for holonym_index, _ in ipairs(place_desc.holonyms) do ins(format_holonym_in_context(entry_placetype, place_desc, holonym_index)) end end local gloss = concat(parts) if with_article then local article if desc_index == 1 then article = args.a else if not place_desc.holonyms then -- there isn't a following holonym; the place type given might be raw text as well, so don't add -- an article. with_article = false else local saw_placetype_holonym = false for _, holonym in ipairs(place_desc.holonyms) do if holonym.placetype then saw_placetype_holonym = true break end end if not saw_placetype_holonym then -- following holonym(s)s is/are just raw text; the place type given might be raw text as well, -- so don't add an article. with_article = false end end if with_article then track("second-or-higher-description-with-added-article") else track("second-or-higher-description-suppressed-article") end end if with_article then article = article or m_placetypes.get_placetype_article(place_desc.placetypes[1], ucfirst) if article then gloss = article .. " " .. gloss elseif ucfirst then gloss = m_strutils.ucfirst(gloss) end end end return gloss end --[==[ Get the full gloss (English description) of a new-style place description. New-style place descriptions are specified with a single string containing raw text interspersed with placetypes and holonyms surrounded by `<<...>>`. Exported for use by [[Module:demonyms]]. ]==] function export.format_new_style_place_desc_for_display(args, place_desc, with_article) local parts = {} local function ins(txt) insert(parts, txt) end if with_article and args.a then ins(args.a .. " ") end local max_holonym = 0 for _, order in ipairs(place_desc.order) do local segment_type, segment = order.type, order.value if segment_type == "raw" then ins(segment) elseif segment_type == "placetype" then ins(get_placetype_description(segment)) elseif segment_type == "qualifier" then ins(get_qualifier_description(segment)) elseif segment_type == "holonym" then ins(format_holonym(place_desc, segment, false)) if segment > max_holonym then max_holonym = segment end else internal_error("Unrecognized segment type %s", segment_type) end end if place_desc.holonyms and max_holonym < #place_desc.holonyms then local holonym_no_prefix = true for holonym_index = max_holonym + 1, #place_desc.holonyms do ins(format_holonym_in_context(nil, place_desc, holonym_index, holonym_no_prefix)) holonym_no_prefix = false end end return concat(parts) end -- Return a string with the gloss (the description of the place itself, as opposed to translations). If `ucfirst` is -- given, the gloss's first letter is made upper case. If `sentence_style` is given, the "extra info" (modern name, -- capital, largest city, etc.) is displayed as separated sentences; otherwise, it is displayed separated from the main -- definition by semicolons. local function get_display_form(data) local overall_place_spec, ucfirst, sentence_style, drop_extra_info, extra_info_overridden_set, from_tcl = data.overall_place_spec, data.ucfirst, data.sentence_style, data.drop_extra_info, data.extra_info_overridden_set, data.from_tcl local args = overall_place_spec.args local parts = {} local function ins(txt) table.insert(parts, txt) end if overall_place_spec.directives and overall_place_spec.directives[1] then for i, directive_terms in ipairs(overall_place_spec.directives) do ins(directive_terms.pretext) if directive_terms.pretext ~= "" then ucfirst = false end if not args.def or args.def == "-" then ins(format_form_of_directive(overall_place_spec, directive_terms, ucfirst, from_tcl)) ucfirst = false if i == #overall_place_spec.directives and directive_terms.posttext then ins(directive_terms.posttext) end end end end if args.def == "-" then return concat(parts) end if args.def then if args.def:find("<<") then local def_desc = export.parse_new_style_place_desc(args.def, args[1]) ins(export.format_new_style_place_desc_for_display({}, def_desc, false)) else ins(args.def) end else local include_article = true for n, desc in ipairs(overall_place_spec.descs) do if desc.order then ins(export.format_new_style_place_desc_for_display(args, desc, n == 1)) else ins(format_old_style_place_desc_for_display(args, desc, n, include_article, ucfirst)) end if desc.joiner then ins(desc.joiner) end include_article = desc.include_following_article ucfirst = false end end local addl = args.addl if addl then posttext = posttext or "" if addl:find("^[;:]") then ins(addl) elseif addl:find("^_") then ins(" " .. addl:sub(2)) else ins(", " .. addl) end end for _, extra_info_terms in ipairs(overall_place_spec.extra_info) do -- Include a given extra info term either when -- (1) drop_extra_info not set (it's set by {{tcl}}), or -- (2) the extra info term is marked as "display even when dropped" (e.g. modern= or full=, to help understand -- the term's sense), or -- (3) the term was overridden by a `place_*=` setting in {{tcl}}. if not drop_extra_info or extra_info_terms.spec.display_even_when_dropped or extra_info_overridden_set and extra_info_overridden_set[extra_info_terms.spec.arg] then ins(format_extra_info(overall_place_spec, extra_info_terms, sentence_style)) end end return concat(parts) end -- Return the definition line. local function get_def(data) local overall_place_spec, from_tcl, drop_extra_info, extra_info_overridden_set, translation_follows = data.overall_place_spec, data.from_tcl, data.drop_extra_info, data.extra_info_overridden_set, data.translation_follows local args = overall_place_spec.args local sentence_style = overall_place_spec.lang:getCode() == "en" local ucfirst = sentence_style and not args.nocap if #args.t > 0 then local gloss = get_display_form { overall_place_spec = overall_place_spec, ucfirst = false, sentence_style = false, drop_extra_info = drop_extra_info, extra_info_overridden_set = extra_info_overridden_set, from_tcl = from_tcl, } if from_tcl and not args.tcl_nolc then gloss = m_strutils.lcfirst(gloss) end if translation_follows then return (gloss == "" and "" or gloss .. ": ") .. get_translations(args.t, args.tid) else return get_translations(args.t, args.tid) .. (gloss == "" and "" or " (" .. gloss .. ")") end else return get_display_form { overall_place_spec = overall_place_spec, ucfirst = ucfirst, sentence_style = sentence_style, drop_extra_info = drop_extra_info, extra_info_overridden_set = extra_info_overridden_set, from_tcl = from_tcl, } end end ---------- Functions for the category wikicode -- The code in this section finds the categories to which a given place belongs. See comment at top of file. --[=[ Find the appropriate category specs for a given place description and placetype. For example, for the template invocation {{tl|place|en|city/and/county|s/Pennsylvania|c/US}}, which results in the place description ``` { placetypes = {"city", "and", "county"}, holonyms = { {placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"}, {placetype = "country", display_placename = "United States", unlinked_placename = "United States"}, }, holonyms_by_placetype = { state = {"Pennsylvania"}, country = {"United States"}, }, } ``` the call ``` find_placetype_cat_specs { entry_placetype = "city", place_desc = { placetypes = {"city", "and", "county"}, holonyms = { {placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"}, {placetype = "country", display_placename = "United States", unlinked_placename = "United States"}, }, holonyms_by_placetype = { state = {"Pennsylvania"}, country = {"United States"}, }, }, } ``` might produce the return value ``` { entry_placetype = "city", cat_specs = {"Cities in Pennsylvania, USA"}, triggering_holonym = {placetype = "state", display_placename = "Pennsylvania", unlinked_placename = "Pennsylvania"}, triggering_holonym_index = 1, } ``` See the comment at the top of the section for a description of category specs and the overall algorithm. On entry, `data` is an object with the following fields: * `entry_placetype`: the entry placetype (or equivalent) used to look up the category data in placetype_data, which must have already been resolved to a placetype with an entry in `placetype_data`; * `place_desc`: the full place description as documented at the top of the file (used only for its holonyms); * `first_holonym_index`: the index of the first holonym to consider when iterating through the holonyms (used to implement the `:also` holonym placetype modifier); * `overriding_holonym`: an optional overriding holonym to use, in place of iterating through the holonyms (used to implement categorizing other holonyms of the same type as the triggering holonym, so that e.g. {{tl|place|en|river|s/Kansas,Nebraska}}, or equivalently {{tl|place|en|river|s/Kansas|and|s/Nebraska}}, works); * `from_demonym`: we are called from {{tl|demonym-noun}} or {{tl|demonym-adj}} instead of {{tl|place}}, and should generate categories appropriate to those templates. * `form_of_directive`: A form-of directive prefix such as `FORMER_NAME_OF`. If specified, use that type prefix to generate categories appropriate to the form-of directive (in addition to the regular categories generated for the {{tl|place}} invocation, which happens in a separate call). The return value is {nil} if no category specs could be located, otherwise an object with the following fields: * `entry_placetype`: the placetype that should be used to construct categories when `true` is one of the returned category specs (normally the same as the `entry_placetype` passed in, but will be different when a "fallback" key exists and is used); * `cat_specs`: list of category specs as described above; * `triggering_holonym`: the triggering holonym (see the comment at the top of the section), or nil if there was no triggering holonym; * `triggering_holonym_index`: the index of the triggering holonym in the list of holonyms in `place_desc`, or nil if an overriding holonym was passed in or there was no triggering holonym. ]=] local function find_placetype_cat_specs(data) local entry_placetype, place_desc, first_holonym_index, overriding_holonym, from_demonym = data.entry_placetype, data.place_desc, data.first_holonym_index, data.overriding_holonym, data.from_demonym local form_of_directive = data.form_of_directive local function fetch_cat_specs(holonym_to_match, index, no_fallback) local holonym_placetype = holonym_to_match.placetype if not holonym_placetype then -- raw text in place of holonym return nil end local holonym_placename = holonym_to_match.unlinked_placename if not holonym_placename then internal_error("Missing unlinked_placename in holonym (index %s): %s", index, holonym_to_match) end local cat_specs, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype, function(equiv_entry_pt) return m_placetypes.get_equiv_placetype_prop(holonym_placetype, function(equiv_holonym_pt) return m_placetypes.political_division_cat_handler { entry_placetype = equiv_entry_pt, holonym_placetype = equiv_holonym_pt, holonym_placename = holonym_placename, holonym_index = index, place_desc = place_desc, from_demonym = from_demonym, } end) end, {no_fallback = no_fallback, form_of_directive = form_of_directive} ) if cat_specs and cat_specs[1] then return cat_specs, equiv_entry_placetype_and_qualifier.placetype end local cat_handler, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype, function(equiv_entry_pt) local entry_placetype_data = m_placetypes.placetype_data[equiv_entry_pt] if entry_placetype_data and entry_placetype_data.cat_handler then return entry_placetype_data.cat_handler end end, {no_fallback = no_fallback, form_of_directive = form_of_directive} ) if cat_handler then local cat_specs = m_placetypes.get_equiv_placetype_prop(holonym_placetype, function(equiv_holonym_pt) return cat_handler { entry_placetype = equiv_entry_placetype_and_qualifier.placetype, holonym_placetype = equiv_holonym_pt, holonym_placename = holonym_placename, holonym_index = index, place_desc = place_desc, from_demonym = from_demonym, } end) if cat_specs and cat_specs[1] then return cat_specs, equiv_entry_placetype_and_qualifier.placetype end end if not no_fallback then local cat_specs, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype, function(equiv_entry_pt) local entry_placetype_data = m_placetypes.placetype_data[equiv_entry_pt] if entry_placetype_data then return m_placetypes.get_equiv_placetype_prop(holonym_placetype, function(equiv_holonym_pt) return entry_placetype_data[equiv_holonym_pt .. "/*"] end) end end, {form_of_directive = form_of_directive} ) if cat_specs and cat_specs[1] then return cat_specs, equiv_entry_placetype_and_qualifier.placetype end end return nil end if overriding_holonym then -- FIXME, change the algorithm to eliminate overriding_holonym local cat_specs, fetched_entry_placetype = fetch_cat_specs(overriding_holonym, nil) if cat_specs and cat_specs[1] then return { entry_placetype = fetched_entry_placetype, cat_specs = cat_specs, triggering_holonym = overriding_holonym, -- no triggering_holonym_index } end else -- We loop twice over holonyms, the first time setting `no_fallback` so that we process only category specs for -- the specifically given entry placetype (possibly with preceding qualifiers). The reason for this is to -- correctly handle cases like [[Poblacion IX]]: -- {{place|en|barangay|mun/Roxas|p/Capiz|c/Philippines}}. -- "barangay" falls back to "neighborhood", and without the `no_fallback` loop, the neighborhood cat handler run -- on the mun/Roxas holonym will take precedence over the barangay-specific setting for p/Capiz because we -- check, for each holonym in turn, first for a matching spec through political_division_cat_handler, then a cat -- handler, then a wildcard spec like country/*. During the first no-fallback loop, we disable checking for -- wildcard specs because it seems a fallback matching exactly or through a cat handler on an earlier holonym -- would be better than a wildcard match for the exact entry placetype at a later holonym. (FIXME: But I don't -- know for sure; maybe we should check wildcard holonyms on the exact entry placetype first, or contrariwise -- maybe we should check only exact-match holonyms through political_division_cat_handler on the exact entry -- placetype first, not even checking other cat handlers.) for i, holonym in ipairs(place_desc.holonyms) do if first_holonym_index and i < first_holonym_index then -- continue else local cat_specs, fetched_entry_placetype = fetch_cat_specs(holonym, i, "no_fallback") if cat_specs and cat_specs[1] then return { entry_placetype = fetched_entry_placetype, cat_specs = cat_specs, triggering_holonym = holonym, triggering_holonym_index = i, } end end end for i, holonym in ipairs(place_desc.holonyms) do if first_holonym_index and i < first_holonym_index then -- continue else local cat_specs, fetched_entry_placetype = fetch_cat_specs(holonym, i) if cat_specs and cat_specs[1] then return { entry_placetype = fetched_entry_placetype, cat_specs = cat_specs, triggering_holonym = holonym, triggering_holonym_index = i, } end end end end return nil end -- Turn a list of category specs (see comment at section top) into the corresponding categories (minus the language -- code prefix). The function is given the following arguments: -- (1) the category specs retrieved using find_placetype_cat_specs(); -- (2) the entry placetype used to fetch the entry in `placetype_data` -- (3) the triggering holonym (a holonym object; see comment at top of file) used to fetch the category specs -- (see top-of-section comment); or nil if no triggering holonym. -- The return value is constructed as described in the top-of-section comment. local function cat_specs_to_categories(place_desc, cat_data) local all_cats = {} local cat_specs, entry_placetype, triggering_holonym, triggering_holonym_index = cat_data.cat_specs, cat_data.entry_placetype, cat_data.triggering_holonym, cat_data.triggering_holonym_index if triggering_holonym then for _, cat_spec in ipairs(cat_specs) do local cat if cat_spec == true then cat = m_placetypes.pluralize_placetype(entry_placetype, "ucfirst") .. " " .. m_placetypes.get_placetype_entry_preposition(entry_placetype) .. " +++" else cat = cat_spec end if cat:find("%+%+%+") then local group, key, spec, container_trail = m_placetypes.find_matching_holonym_location { holonym_placetype = triggering_holonym.placetype, holonym_placename = triggering_holonym.unlinked_placename, holonym_index = triggering_holonym_index, place_desc = place_desc, } if group then cat = cat:gsub("%+%+%+", m_strutils.replacement_escape(m_placetypes.get_prefixed_key(key, spec))) insert(all_cats, cat) else mw.log(("Unable to insert category for cat spec '%s' because holonym '%s/%s' did not match a " .. "known location"):format(cat, triggering_holonym.placetype, triggering_holonym.unlinked_placename)) track("cant-match-holonym-for-category-spec") end else insert(all_cats, cat) end end else for _, cat_spec in ipairs(cat_specs) do local cat if cat_spec == true then cat = m_placetypes.pluralize_placetype(entry_placetype, "ucfirst") else cat = cat_spec if cat:find("%+%+%+") then internal_error("Category %s contains +++ but there is no holonym to substitute", cat) end end insert(all_cats, cat) end end return all_cats end -- Return the categories (without initial lang code) that should be added to the entry, given the place description -- (which specifies the entry placetype(s) and holonym(s); see top of file) and a particular entry placetype (e.g. -- "city"). Note that only the holonyms from the place description are looked at, not the entry placetypes in the place -- description. local function get_placetype_cats(place_desc, entry_placetype, from_demonym, form_of_directive) local cats = {} local first_holonym_index = 1 while first_holonym_index <= #place_desc.holonyms do -- Find the category specs (see top-of-file comment) corresponding to the holonym(s) in the place description. local cat_data = find_placetype_cat_specs { entry_placetype = entry_placetype, place_desc = place_desc, first_holonym_index = first_holonym_index, from_demonym = from_demonym, form_of_directive = form_of_directive, } -- Check if no category spec could be found. if not cat_data then break end local triggering_holonym = cat_data.triggering_holonym if not triggering_holonym then internal_error("find_placetype_cat_specs should have returned a triggering holonym: %s", cat_data) end -- Generate categories for the category specs found. extend(cats, cat_specs_to_categories(place_desc, cat_data)) -- Also generate categories for other holonyms of the same placetype, so that e.g. -- {{place|en|city|s/Kansas|and|s/Missouri|c/USA}} generates both [[:Category:en:Cities in Kansas, USA]] and -- [[:Category:en:Cities in Missouri, USA]]. first_holonym_index = cat_data.triggering_holonym_index -- Loop over non-fallback equivalent placetypes to the triggering holonym's placetype, in case it is -- non-canonical (e.g. `cities/San Francisco`). This matches the loop over equivalent places in -- key_holonym_into_place_desc(). local equiv_triggering_placetypes = m_placetypes.get_placetype_equivs(triggering_holonym.placetype, {no_fallback = true}) for _, equiv in ipairs(equiv_triggering_placetypes) do local other_holonyms_of_same_type = place_desc.holonyms_by_placetype[equiv.placetype] if other_holonyms_of_same_type then for _, other_placename_of_same_type in ipairs(other_holonyms_of_same_type) do if other_placename_of_same_type ~= triggering_holonym.unlinked_placename then local overriding_holonym = { placetype = triggering_holonym.placetype, unlinked_placename = other_placename_of_same_type, } local other_cat_data = find_placetype_cat_specs { entry_placetype = entry_placetype, place_desc = place_desc, overriding_holonym = overriding_holonym, from_demonym = from_demonym, form_of_directive = form_of_directive, } if other_cat_data then extend(cats, cat_specs_to_categories(place_desc, other_cat_data)) end end end end end -- If there are any later-specified holonyms that had the modifier :also, try to produce categories for them -- as well. first_holonym_index = first_holonym_index + 1 while first_holonym_index <= #place_desc.holonyms do if place_desc.holonyms[first_holonym_index].continue_cat_loop then break end first_holonym_index = first_holonym_index + 1 end end if cats[1] then return cats end local entry_pt_default, equiv_entry_placetype_and_qualifier = m_placetypes.get_equiv_placetype_prop(entry_placetype, function(pt) return m_placetypes.placetype_data[pt] and m_placetypes.placetype_data[pt].default end, {form_of_directive = form_of_directive}) if entry_pt_default then return cat_specs_to_categories(place_desc, { cat_specs = entry_pt_default, entry_placetype = equiv_entry_placetype_and_qualifier.placetype, -- no triggering holonym }) end return {} end --[==[ Iterate through each type of place and return a list of the categories that need to be added to the entry. The returned categories need to be formatted using `format_cats`, as they can be either topic-style categories (by default) or langname-style categories (if prefixed with `cln:`). The function is passed the overall place spec, which contains all the parsed info on the {{tl|place}} call (see comment at top of file), the parsed arguments (needed for arguments not parsed by `parse_overall_place_spec` and used primarily to add "bare categories" corresponding to toponyms for known locations), and `from_demonym`, which is true if we're being called from {{tl|demonym-noun}} or {{tl|demonym-adj}} (in this case, we only want certain categories added, specifically bare categories corresponding to the specified holonym(s)). ]==] function export.get_cats(args, overall_place_spec, from_demonym) local cats = {} local place_descriptions = overall_place_spec.descs handle_category_implications(place_descriptions, m_placetypes.cat_implications) m_placetypes.augment_holonyms_with_container(place_descriptions) if overall_place_spec.directives then -- not necessarily when called from [[Module:demonym]] for _, directive_terms in ipairs(overall_place_spec.directives) do local spec_cats = directive_terms.spec.cat if spec_cats then if type(spec_cats) == "string" then spec_cats = {spec_cats} end for _, spec_cat in ipairs(spec_cats) do insert(cats, spec_cat) end end if directive_terms.spec.type_prefix then for _, place_desc in ipairs(place_descriptions) do for _, placetype in ipairs(place_desc.placetypes) do if not m_placetypes.placetype_is_ignorable(placetype) then extend(cats, get_placetype_cats(place_desc, placetype, from_demonym, directive_terms.spec.type_prefix)) end end end end end end if not from_demonym then local bare_categories = m_placetypes.get_bare_categories(args, overall_place_spec) extend(cats, bare_categories) end for _, place_desc in ipairs(place_descriptions) do if not from_demonym then for _, placetype in ipairs(place_desc.placetypes) do if not m_placetypes.placetype_is_ignorable(placetype) then extend(cats, get_placetype_cats(place_desc, placetype)) end end end -- Also add generic place categories for the holonyms listed (e.g. a category like -- [[Category:Places in Merseyside, England]]). This is handled through the special placetype "*". extend(cats, get_placetype_cats(place_desc, "*", from_demonym)) end if args.cat then -- not necessarily when called from [[Module:demonym]] for _, cat in ipairs(args.cat) do local split_cats = split_on_comma(cat) extend(cats, split_cats) end end return cats end -- Return the category link for a category, given the language code and the name of the category. local function format_cats(lang, cats, sort_key) local full_cats = {} local langcode = lang:getFullCode() for _, cat in ipairs(cats) do -- 'cln' corresponds to {{cln}}, which generates lang-name categories like [[:Category:English abbreviations]] -- (as opposed to topic categories like [[:Category:en:Abbreviations of states of the United States]]). local cln_cat = cat:match("^cln:(.*)$") if cln_cat then insert(full_cats, lang:getFullName() .. " " .. cln_cat) else insert(full_cats, langcode .. ":" .. cat) end end return require(utilities_module).format_categories(full_cats, lang, sort_key, nil, force_cat or m_placetypes.get_force_cat()) end ----------- Main entry point --[==[ Implementation of {{tl|place}}. Meant to be callable from another module (specifically, [[Module:transclude]]). The single argument `data` is an object with the following fields: * `template_args`: Raw arguments specified by {{tl|place}}, possibly modified by {{tl|tcl}}. * `from_tcl`: True if we're being invoked from {{tl|tcl}}. * `drop_extra_info`: True if we should drop most of the "extra info" specified using extra info arguments (capital, largest city, etc.). Usually true when invoked from {{tl|tcl}}. Note that some extra info is still displayed even when `drop_extra_info` is set in order to establish the context (e.g. {{para|full}} and {{para|modern}}), and any extra info overridden at the {{tl|tcl}} level is displayed regardless. * `extra_info_overridden_set`: Set of booleans specifying, for each extra info arg, whether it was overridden at the {{tl|tcl}} level. This means, for example, that the values are interpreted according to the language in {{para|1}} instead of always defaulting to English, as is the case when {{tl|place}} is called directly. * `form_of_overridden_args`: Set of objects of the form `{new_directive = ``directive``, new_value = ``value``}` for overriding a given form-of directive (the key) with new directive ``directive`` and new unparsed value ``value``. Both the key and the replacing directive should be canonical. ``value`` will be parsed in the same way as a regular form-of directive except that all specified terms are interpreted in the language specified in {{para|1}}, never in English. This is present so that {{tl|tcl}} can be used on abbreviations like [[GDR]] and [[FYROM]], whose equivalents in a foreign language have language-specific expansions but where the rest of the call should stay the same. * `translation_follows`: If true, any translation specified using t= should follow the definition, after a colon, rather than preceding, with the definition in parens. ]==] function export.format(data) local template_args = data.template_args local list_param = {list = true} local boolean_param = {type = "boolean"} local params = { [1] = {required = true, type = "language", default = "und"}, [2] = {required = true, list = true}, ["t"] = list_param, ["tid"] = {list = true, allow_holes = true}, ["cat"] = list_param, ["nocat"] = boolean_param, ["nocap"] = boolean_param, ["sort"] = true, ["pagename"] = true, -- for testing or documentation purposes ["a"] = true, ["addl"] = true, ["def"] = true, -- params that are only used when transcluding using {{tcl}}/{{transclude}}, to transmit information to {{tcl}}. ["tcl"] = true, ["tcl_t"] = list_param, ["tcl_tid"] = list_param, ["tcl_nolb"] = true, ["tcl_nolc"] = boolean_param, ["tcl_noextratext"] = boolean_param, } -- add "extra info" parameters for _, extra_arg_spec in ipairs(export.extra_info_args) do params[extra_arg_spec.arg] = list_param end -- FIXME, once we've flushed out any uses, delete the following clause. That will cause def= to be ignored. if template_args.def == "" then error("Cannot currently pass def= as an empty parameter; use def=- if you want to suppress the definition display") end local args = require("Module:parameters").process(template_args, params) if args.a then track("a") if args.a:find("^[Aa]n?$") or args.a:find("^[Tt]he$") then track("a/article") else error("a= can only be used to specify a definite or indefinite article (and preferably use |nocap=1 instead to get the initial letter lowercase); see especially the documentation on the [[Template:place#Mixed format|mixed format]], which can be used to add arbitrary text before the placetype") end end data.args = args local overall_place_spec = parse_overall_place_spec(data) data.overall_place_spec = overall_place_spec return get_def(data) .. ( args.nocat and "" or format_cats(args[1], export.get_cats(args, overall_place_spec), args.sort)) end --[==[ Actual entry point of {{tl|place}}. ]==] function export.show(frame) return export.format { template_args = frame:getParent().args, } end return export 4qw6749l86qzy88zjzv8ijo1amqgjnw मॉड्यूल:category tree/topic/Places 828 304676 489349 477653 2026-09-22T18:40:17Z SM7 6218 SM7 ने अनुप्रेषण छोड़े बिना पृष्ठ [[मॉड्यूल:category tree/topic cat/data/Places]] को [[मॉड्यूल:category tree/topic/Places]] पर स्थानांतरित किया 477653 Scribunto text/plain local labels = {} local handlers = {} local m_shared = require("Module:place/shared-data") local m_strutils = require("Module:string utilities") --[=[ This module contains specifications that are used to create labels that allow {{auto cat}} and {{topic cat}} to create the appropriate definitions for topic categories for places (e.g.re 'en:Waterfalls', 'de:Hokkaido', 'es:Cities in France', 'pt:Municipalities of Tocantins, Brazil', etc.). Note that this module doesn't actually create the categories; that must be done manually, with the text "{{auto cat}}" as the definition of the category. (This process should automatically happen periodically for non-empty categories, because they will appear in [[Special:WantedCategories]] and a bot will periodically examine that list and create any needed category.) There are two ways that such labels are created: (1) by manually adding an entry to the 'labels' table, keyed by the label (minus the language code) with a value consisting of a Lua table specifying the description text and the category's parents; (2) through handlers (pieces of Lua code) added to the 'handlers' list, which recognize labels of a specific type (e.g. 'Cities in France') and generate the appropriate specification for that label on-the-fly. ]=] local function lcfirst(label) return mw.getContentLanguage():lcfirst(label) end labels["places"] = { description = "{{{langname}}} names for geographical [[place]]s; [[toponym]]s.", parents = {"names", "list of sets"}, } -- Generate bare labels in 'label' for all political subdivisions. -- Do this before handling 'general_labels' so the latter can override if necessary. for subdiv, desc in pairs(m_shared.political_subdivisions) do labels[subdiv] = { description = "{{{langname}}} names of " .. desc .. ".", parents = {"political subdivisions", "list of sets"}, } end -- General labels. These are intended for places of all sorts that are not qualified -- by a holonym (e.g. it does not include 'regions in Africa'). These also do not need -- to include any political subdivisions listed in 'political_subdivisions' in -- [[Module:place-data/shared]]. Each entry is {LABEL, DESCRIPTION, PARENTS}. -- PARENTS should not include "list of sets", which is added automatically. local general_labels = { {"airports", "[[airport]]s", {"places"}}, {"ancient settlements", "former [[city|cities]], [[town]]s and [[village]]s that existed in [[antiquity]]", {"historical settlements"}}, {"atolls", "[[atoll]]s", {"islands"}}, {"bays", "[[bay]]s", {"places", "water"}}, {"beaches", "[[beach]]es", {"places", "water"}}, {"bodies of water", "[[body of water|bodies of water]]", {"landforms", "water"}}, {"boroughs", "[[borough]]s", {"polities"}}, {"capital cities", "[[capital]] [[city|cities]]: the [[seat of government|seats of government]] for a country or [[political]] [[subdivision]] of a country", {"cities"}}, {"census-designated places", "[[census-designated place]]s", {"places"}}, {"cities", "[[city|cities]]", {"polities"}}, {"city-states", "[[sovereign]] [[microstate]]s consisting of a single [[city]] and [[w:dependent territory|dependent territories]]", {"polities"}}, {"communities", "[[community|communities]] of all sizes", {"polities"}}, {"continents", "the [[continent]]s of the world", {"places"}}, {"countries", "[[country|countries]]", {"polities"}}, {"dependent territories", "[[w:dependent territory|dependent territories]]", {"polities"}}, {"deserts", "[[desert]]s", {"places"}}, {"forests", "[[forest]]s", {"places"}}, {"ghost towns", "[[ghost town]]s", {"historical settlements"}}, {"gulfs", "[[gulf]]s", {"places", "water"}}, {"headlands", "[[headland]]s", {"places"}}, {"historical and traditional regions", "regions that have no administrative significance", {"places"}}, {"historical capitals", "former [[capital]] [[city|cities]] and [[town]]s", {"historical settlements"}}, {"historical dependent territories", "[[w:dependent territory|dependent territories]] (colonies, dependencies, protectorates, etc.) that no longer exist", {"dependent territories"}}, {"historical political subdivisions", "[[political]] [[subdivision]]s (states, provinces, counties, etc.) that no longer exist", {"polities"}}, {"historical polities", "[[polity|polities]] (countries, kingdoms, empires, etc.) that no longer exist", {"polities"}}, {"historical settlements", "[[city|cities]], [[town]]s and [[village]]s that no longer exist or have been merged or reclassified", {"historical polities"}}, {"hills", "[[hill]]s", {"places"}}, {"islands", "[[island]]s", {"places"}}, {"kibbutzim", "[[kibbutz]]im", {"places"}}, {"lakes", "[[lake]]s", {"places", "bodies of water"}}, {"landforms", "[[landform]]s", {"places", "Earth"}}, {"micronations", "[[micronation]]s", {"places"}}, {"mountain passes", "[[mountain pass]]es", {"places"}}, {"mountains", "[[mountain]]s", {"places"}}, {"moors", "[[moor]]s", {"places"}}, {"neighborhoods", "[[neighborhood]]s, [[district]]s and other subportions of a [[city]]", {"places"}}, -- FIXME, is the following parent correct? {"oceans", "[[ocean]]s", {"Seas"}}, {"parks", "[[park]]s", {"places"}}, {"peninsulas", "[[peninsula]]s", {"places"}}, {"plateaus", "[[plateau]]s", {"places"}}, {"political subdivisions", "[[political]] [[subdivision]]s, such as [[province]]s, [[state]]s or [[region]]s", {"polities"}}, {"polities", "[[polity|polities]] or [[political]] [[division]]s", {"places"}}, {"rivers", "[[river]]s", {"places", "bodies of water"}}, {"seas", "[[sea]]s", {"places", "bodies of water"}}, {"straits", "[[strait]]s", {"places", "bodies of water"}}, {"subdistricts", "[[subdistrict]]s", {"polities"}}, {"suburbs", "[[suburb]]s of a [[city]]", {"places"}}, {"towns", "[[town]]s", {"polities"}}, {"townships", "[[township]]s", {"polities"}}, {"unincorporated communities", "[[unincorporated]] [[community|communities]]", {"places"}}, {"valleys", "[[valley]]s", {"places", "water"}}, {"villages", "[[village]]s", {"polities"}}, {"volcanoes", "[[volcano]]es", {"landforms"}}, {"waterfalls", "[[waterfall]]s", {"landforms", "water"}}, {"wetlands", "[[wetland]]s", {"places", "bodies of water"}}, } -- Generate bare labels in 'label' for all "general labels" (see above). for _, label_spec in ipairs(general_labels) do local label, desc, parents = unpack(label_spec) table.insert(parents, "list of sets") labels[label] = { description = "{{{langname}}} names of " .. desc .. ".", parents = parents, } end labels["city nicknames"] = { -- special-cased description description = "{{{langname}}} informal alternative names for [[city|cities]] (e.g., [[Big Apple]] for [[New York City]]).", parents = {"cities", "nicknames", "list of sets"}, } labels["exonyms"] = { -- special-cased description description = "{{{langname}}} [[exonym]]s.", parents = {"places", "list of sets"}, } -- Generate bare labels in 'label' for all polities (countries, states, etc.). for _, group in ipairs(m_shared.polities) do for key, value in pairs(group.data) do group.bare_label_setter(labels, group, key, value) end end local function city_description(group, key, value) -- The purpose of all the following code is to construct the description. It's written in -- a general way to allow any number of containing polities, each larger than the previous one, -- so that e.g. for Birmingham, the description will read "{{{langname}}} terms related to the city of -- [[Birmingham]], in the county of the [[West Midlands]], in the [[constituent country]] of [[England]], -- in the [[United Kingdom]]." local bare_key, linked_key = m_shared.construct_bare_and_linked_version(key) local descparts = {} table.insert(descparts, "the city of " .. linked_key) local city_containing_polities = m_shared.get_city_containing_polities(group, key, value) local label_parent -- parent of the label, from the immediate containing polity for n, polity in ipairs(city_containing_polities) do local bare_polity, linked_polity = m_shared.construct_bare_and_linked_version(polity[1]) if n == 1 then label_parent = bare_polity end table.insert(descparts, ", in ") if n < #city_containing_polities then local divtype = polity.divtype or group.default_divtype local pl_divtype = m_strutils.pluralize(divtype) local pl_linked_divtype = m_shared.political_subdivisions[pl_divtype] if not pl_linked_divtype then error("When creating city description for " .. key .. ", encountered divtype '" .. divtype .. "' not in m_shared.political_subdivisions") end local linked_divtype = m_strutils.singularize(pl_linked_divtype) table.insert(descparts, "the " .. linked_divtype .. " of ") end table.insert(descparts, linked_polity) end return table.concat(descparts), label_parent end -- Generate bare labels in 'label' for all cities. for _, group in ipairs(m_shared.cities) do for key, value in pairs(group.data) do if not value.alias_of then local desc, label_parent = city_description(group, key, value) desc = "{{{langname}}} terms related to " .. desc .. "." local parents = value.parents or label_parent if not parents then error("When creating city bare label for " .. key .. ", at least one containing polity must be specified or an explicit parent must be given") end if type(parents) ~= "table" then parents = {parents} end local key_parents = {} for _, parent in ipairs(parents) do local polity_group, key_parent = m_shared.city_containing_polity_to_group_and_key(parent) if key_parent then local bare_key_parent, linked_key_parent = m_shared.construct_bare_and_linked_version(key_parent) table.insert(key_parents, bare_key_parent) else error("Couldn't find entry for city '" .. key .."' parent '" .. parent .. "'") end end labels[key] = { description = desc, parents = key_parents, } end end end -- Handler for "cities in the Bahamas", "rivers in Western Australia", etc. -- Places that begin with "the" are recognized and handled specially. table.insert(handlers, function(label) label = lcfirst(label) local place_type, place = label:match("^([a-z%- ]-) in (.*)$") if place_type and m_shared.generic_place_types[place_type] then for _, group in ipairs(m_shared.polities) do local placedata = group.data[place] if placedata then placedata = group.value_transformer(group, place, placedata) local allow_cat = true if place_type == "neighborhoods" and placedata.british_spelling or place_type == "neighbourhoods" and not placedata.british_spelling then allow_cat = false end if placedata.is_former_place and place_type ~= "places" then allow_cat = false end if placedata.is_city and not m_shared.generic_place_types_for_cities[place_type] then allow_cat = false end if allow_cat then local parent if placedata.containing_polity then parent = place_type .. " in " .. placedata.containing_polity elseif place_type == "neighbourhoods" then parent = "neighborhoods" else parent = place_type end local bare_place, linked_place = m_shared.construct_bare_and_linked_version(place) local keydesc = placedata.keydesc or linked_place local parents if place_type == "places" then parents = {{name = parent, sort = bare_place}, bare_place, "list of sets"} else parents = {{name = parent, sort = bare_place}, bare_place, "list of sets", "places in " .. place} end return { description = "{{{langname}}} names of " .. m_shared.generic_place_types[place_type] .. " in " .. keydesc .. ".", parents = parents } end end end end end) -- Handler for "places in Paris", "neighbourhoods of Paris", etc. table.insert(handlers, function(label) label = lcfirst(label) local place_type, in_of, city = label:match("^(places) (in) (.*)$") if not place_type then place_type, in_of, city = label:match("^([a-z%- ]-) (of) (.*)$") end if place_type and m_shared.generic_place_types_for_cities[place_type] then for _, group in ipairs(m_shared.cities) do local city_data = group.data[city] if city_data then local spelling_matches = true if place_type == "neighborhoods" or place_type == "neighbourhoods" then local containing_polities = m_shared.get_city_containing_polities(group, city, city_data) local polity_group, polity_key = m_shared.city_containing_polity_to_group_and_key( containing_polities[1]) if not polity_key then error("Can't find polity data for city '" .. place .. "' containing polity '" .. containing_polities[1] .. "'") end local polity_value = polity_group.value_transformer(polity_group, polity_key, polity_group[polity_key]) if place_type == "neighborhoods" and polity_value.british_spelling or place_type == "neighbourhoods" and not polity_value.british_spelling then spelling_matches = false end end if spelling_matches then local parents if place_type == "places" then parents = {city, "list of sets"} else parents = {city, "list of sets", "places in " .. city} end local desc = city_description(group, city, city_data) return { description = "{{{langname}}} names of " .. m_shared.generic_place_types_for_cities[place_type] .. " " .. in_of .. " " .. desc .. ".", parents = parents } end end end end end) -- Handler for "political subdivisions of the Philippines" and other "political subdivisions of X" categories. table.insert(handlers, function(label) label = lcfirst(label) local place = label:match("^political subdivisions of (.*)$") if place then for _, group in ipairs(m_shared.polities) do local placedata = group.data[place] if placedata then placedata = group.value_transformer(group, place, placedata) local bare_place, linked_place = m_shared.construct_bare_and_linked_version(place) local keydesc = placedata.keydesc or linked_place local desc = "{{{langname}}} names of [[political]] [[subdivision]]s of " .. keydesc .. "." return { description = desc, breadcrumb = "political subdivisions", parents = {bare_place, {name = "political subdivisions", sort = bare_place}, "list of sets"}, } end end end end) -- Handler for "provinces of the Philippines", "counties of Wales", "municipalities of Tocantins, Brazil", etc. -- Places that begin with "the" are recognized and handled specially. table.insert(handlers, function(label) label = lcfirst(label) local place_type, place = label:match("^([a-z%- ]-) of (.*)$") if place then for _, group in ipairs(m_shared.polities) do local placedata = group.data[place] if placedata then placedata = group.value_transformer(group, place, placedata) local divcat = nil local poldiv_parent = nil if placedata.poldiv then for _, div in ipairs(placedata.poldiv) do if type(div) == "string" then div = {div} end if place_type == div[1] then divcat = "poldiv" poldiv_parent = div.parent break end end end if not divcat and placedata.miscdiv then for _, div in ipairs(placedata.miscdiv) do if type(div) == "string" then div = {div} end if place_type == div[1] then divcat = "miscdiv" break end end end if divcat then local linkdiv = m_shared.political_subdivisions[place_type] if not linkdiv then error("Saw unknown place type '" .. place_type .. "' in label '" .. label .. "'") end local bare_place, linked_place = m_shared.construct_bare_and_linked_version(place) local keydesc = placedata.keydesc or linked_place local desc = "{{{langname}}} names of " .. linkdiv .. " of " .. keydesc .. "." if divcat == "poldiv" then return { description = desc, breadcrumb = place_type, parents = poldiv_parent and {{name = poldiv_parent, sort = bare_place}, bare_place, "list of sets"} or {"political subdivisions of " .. place, {name = place_type, sort = bare_place}, "list of sets"}, } else return { description = desc, breadcrumb = place_type, parents = {bare_place, "list of sets"}, } end end end end end end) -- Generate bare labels in 'label' for all types of capitals. for capital_cat, placetype in pairs(m_shared.capital_cat_to_placetype) do local pl_placetype = m_strutils.pluralize(placetype) local linkdiv = m_shared.political_subdivisions[pl_placetype] if not linkdiv then error("Saw unknown place type '" .. pl_placetype .. "' in label '" .. label .. "'") end labels[capital_cat] = { description = "{{{langname}}} names of [[capital]]s of " .. linkdiv .. ".", parents = {"capital cities", "list of sets"}, } end -- Handler for "state capitals of the United States", "provincial capitals of Canada", etc. -- Places that begin with "the" are recognized and handled specially. table.insert(handlers, function(label) label = lcfirst(label) local capital_cat, place = label:match("^([a-z%- ]- capitals) of (.*)$") -- Make sure we recognize the type of capital. if place and m_shared.capital_cat_to_placetype[capital_cat] then local placetype = m_shared.capital_cat_to_placetype[capital_cat] local pl_placetype = m_strutils.pluralize(placetype) -- Locate the containing polity, fetch its known political subdivisions, and make sure -- the placetype corresponding to the type of capital is among the list. for _, group in ipairs(m_shared.polities) do local placedata = group.data[place] if placedata then placedata = group.value_transformer(group, place, placedata) if placedata.poldiv then local saw_match = false local variant_matches = {} for _, div in ipairs(placedata.poldiv) do if type(div) == "string" then div = {div} end -- HACK. Currently if we don't find a match for the placetype, we map e.g. -- 'autonomous region' -> 'regional capitals' and 'union territory' -> 'territorial capitals'. -- When encountering a political subdivision like 'autonomous region' or -- 'union territory', chop off everything up through a space to make things match. -- To make this clearer, we record all such "variant match" cases, and down below we -- insert a note into the category text indicating that such "variant matches" -- are included among the category. if pl_placetype == div[1] or pl_placetype == div[1]:gsub("^.* ", "") then saw_match = true if pl_placetype ~= div[1] then table.insert(variant_matches, div[1]) end end end if saw_match then -- Everything checks out, construct the category description. local linkdiv = m_shared.political_subdivisions[pl_placetype] if not linkdiv then error("Saw unknown place type '" .. pl_placetype .. "' in label '" .. label .. "'") end local bare_place, linked_place = m_shared.construct_bare_and_linked_version(place) local keydesc = placedata.keydesc or linked_place local variant_match_text = "" if #variant_matches > 0 then for i, variant_match in ipairs(variant_matches) do variant_matches[i] = m_shared.political_subdivisions[variant_match] if not variant_matches[i] then error("Saw unknown place type '" .. variant_match .. "' in label '" .. label .. "'") end end variant_match_text = " (including " .. require("Module:table").serialCommaJoin(variant_matches) .. ")" end local desc = "{{{langname}}} names of [[capital]]s of " .. linkdiv .. variant_match_text .. " of " .. keydesc .. "." return { description = desc, parents = {{name = capital_cat, sort = bare_place}, bare_place, "list of sets"}, } end end end end end end) -- "regions in (continent)", esp. for regions that span multiple countries labels["regions in the world"] = { -- for multinational regions which do not fit neatly within one continent description = "{{{langname}}} names of [[region]]s in the world (which do not fit neatly within one country or continent).", parents = {"places", "list of sets"}, } labels["regions in Africa"] = { description = "{{{langname}}} names of [[region]]s in Africa.", parents = {"Africa", "list of sets"}, } labels["regions in the Americas"] = { description = "{{{langname}}} names of [[region]]s in the Americas.", parents = {"America", "list of sets"}, } labels["regions in Asia"] = { description = "{{{langname}}} names of [[region]]s in Asia.", parents = {"Asia", "list of sets"}, } labels["regions in Europe"] = { description = "{{{langname}}} names of [[region]]s in Europe.", parents = {"Europe", "list of sets"}, } -- "countries in (continent)", "rivers in (continent)" for _, continent in ipairs({"Africa", "Asia", "Central America", "Europe", "North America", "Oceania", "South America"}) do labels["countries in " .. continent] = { description = "{{{langname}}} names of [[country|countries]] in [[" .. continent .. "]].", parents = {{name = "countries", sort = " "}, continent, "list of sets"}, } labels["rivers in " .. continent] = { description = "{{{langname}}} names of [[river]]s in [[" .. continent .. "]].", parents = {{name = "rivers", sort = " "}, continent, "list of sets"}, } end -- autonomous communities, oblasts, etc labels["autonomous communities of Spain"] = { -- special-cased description description = "{{{langname}}} names of the [[w:Autonomous communities of Spain|autonomous communities of Spain]].", parents = {{name = "political subdivisions", sort = "Spain"}, "Spain", "list of sets"}, } labels["autonomous cities of Spain"] = { -- special-cased description description = "{{{langname}}} names of the [[w:Autonomous communities of Spain#Autonomous_cities|autonomous cities of Spain]].", parents = {{name = "political subdivisions", sort = "Spain"}, "Spain", "list of sets"}, } -- boroughs labels["boroughs in England"] = { description = "{{{langname}}} names of boroughs, local government districts and unitary authorities in [[England]].", parents = {{name = "boroughs", sort = "England"}, "England", "list of sets"}, } labels["boroughs in Pennsylvania, USA"] = { description = "{{{langname}}} names of boroughs in [[Pennsylvania]], USA.", parents = {{name = "boroughs in the United States", sort = "Pennsylvania"}, "Pennsylvania, USA", "list of sets"}, } labels["boroughs in New Jersey, USA"] = { description = "{{{langname}}} names of boroughs in [[New Jersey]], USA.", parents = {{name = "boroughs in the United States", sort = "New Jersey"}, "New Jersey, USA", "list of sets"}, } labels["boroughs in New York City"] = { description = "{{{langname}}} names of boroughs in [[New York City]].", parents = {{name = "boroughs in the United States", sort = "New York City"}, "New York City", "list of sets"}, } labels["boroughs in the United States"] = { description = "{{{langname}}} names of [[borough]]s in the [[United States]].", -- parent is "boroughs" not "political subdivisions" and category says "in" -- not "of", because boroughs aren't really political subdivisions in the US -- (more like cities) parents = {{name = "boroughs", sort = "United States"}, "United States", "list of sets"}, } -- census-designated places labels["census-designated places in the United States"] = { description = "{{{langname}}} names of [[census-designated place]]s in the [[United States]].", -- parent is just United States; census-designated places have no political -- status and exist only in the US, so no need for a top-level -- "census-designated places" category parents = {"United States", "list of sets"}, } -- counties labels["counties of Northern Ireland"] = { description = "{{{langname}}} names of the counties of [[Northern Ireland]].", -- has two parents: "political subdivisions" and "counties of Ireland" parents = {{name = "political subdivisions", sort = "Northern Ireland"}, {name = "counties of Ireland", sort = "Northern Ireland"}, "Northern Ireland", "list of sets"}, } -- nomes labels["nomes of Ancient Egypt"] = { -- special-cased description description = "{{{langname}}} names of the nomes of [[Ancient Egypt]].", parents = {{name = "political subdivisions", sort = "Egypt"}, "Ancient Egypt", "list of sets"}, } -- regions and "regional units" labels["regions of Albania"] = { -- special-cased description description = "{{{langname}}} names of the regions (peripheries) of [[Albania]].", parents = {{name = "political subdivisions", sort = "Albania"}, "Albania", "list of sets"}, } labels["regions of Greece"] = { -- special-cased description description = "{{{langname}}} names of the regions (peripheries) of [[Greece]].", parents = {{name = "political subdivisions", sort = "Greece"}, "Greece", "list of sets"}, } labels["regions of North Macedonia"] = { -- special-cased description description = "{{{langname}}} names of the regions (peripheries) of [[North Macedonia]].", parents = {{name = "political subdivisions", sort = "North Macedonia"}, "North Macedonia", "list of sets"}, } -- subdistricts and subprefectures labels["subdistricts of Jakarta"] = { description = "default-set", -- not listed in the normal place because no categories like "cities in Jakarta" parents = {{name = "political subdivisions", sort = "Jakarta"}, "Indonesia", "list of sets"}, } labels["subprefectures of Japan"] = { -- special-cased description description = "{{{langname}}} names of subprefectures of Japanese prefectures.", parents = {{name = "political subdivisions", sort = "Japan"}, "Japan", "list of sets"}, } -- towns and townships labels["townships in Canada"] = { description = "{{{langname}}} names of townships in [[Canada]].", parents = {{name = "townships", sort = "Canada"}, "Canada", "list of sets"}, } labels["townships in Ontario"] = { description = "{{{langname}}} names of townships in [[Ontario]]. Municipalities in Ontario can be called as a city, a town, a township, or a village.", parents = {{name = "townships in Canada", sort = "Ontario"}, "Ontario", "list of sets"}, } labels["townships in Quebec"] = { description = "{{{langname}}} names of townships in [[Quebec]].", parents = {{name = "townships in Canada", sort = "Quebec"}, "Quebec", "list of sets"}, } -- temporary while users adjust to recent changes, also kept in case of desire to use for its topical purpose, see description; can be removed later if unused labels["place names"] = { description = "{{{langname}}} terms like ''hydronym'', for names for geographical [[place]]s.", parents = {"names", "list of sets"}, } return {LABELS = labels, HANDLERS = handlers} ruw5ylr14ibr2vlyeprlgmhdca57jmv 489350 489349 2026-09-22T18:40:44Z SM7 6218 updating... 489350 Scribunto text/plain local labels = {} local handlers = {} local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local string_utilities_module = "Module:string utilities" local m_locations = require("Module:place/locations") local m_placetypes = require("Module:place/placetypes") local placetype_data = m_placetypes.placetype_data local internal_error = m_locations.internal_error local dump = mw.dumpObject local insert = table.insert local concat = table.concat local is_callable = require("Module:fun").is_callable --[==[ intro: This module is part of the category tree code and contains code to generate the descriptions of place-related categories such as [[Category:de:Hokkaido Prefecture, Japan]], [[Category:es:Cities in France]], [[Category:pt:Municipalities of Tocantins, Brazil]], etc.). Note that this module doesn't actually create the categories; that must be done separately, with the text "{{tl|auto cat}}" as the definition of the category. (This process should automatically happen periodically for non-empty categories, because they will appear in [[Special:WantedCategories]] and a bot will periodically examine that list and create any needed category.) There are two ways that category descriptions are specified: (1) by manually adding an entry to the `labels` table, keyed by the label (the category minus the language code) with a value consisting of a Lua table specifying the description text and the category's parents; (2) through handlers (pieces of Lua code) added to the `handlers` list, which recognize labels of a specific type (e.g. `Cities in France`) and generate the appropriate specification for that label on-the-fly. See [[Module:place]] for an introduction to the terminology associated with places along with a list of all the relevant modules, along with for more specific information on types of toponyms and placetypes and how their categorization works. ]==] local function lcfirst(label) return mw.getContentLanguage():lcfirst(label) end local function gsub_literally(str, from, to) local m_strutils = require(string_utilities_module) return (str:gsub(m_strutils.pattern_escape(from), m_strutils.replacement_escape(to))) end local class_to_bare_category_parent = { ["polity"] = "polities", ["subpolity"] = "political divisions", ["settlement"] = "settlements", ["non-admin settlement"] = "settlements", ["capital"] = "capital cities", ["natural feature"] = "natural features", ["man-made structure"] = "man-made structures", ["geographic region"] = "geographic and cultural areas", } local class_is_political_division = { ["polity"] = true, -- strictly false but there are placetypes ambiguous between polity and subpolity ["subpolity"] = true, ["settlement"] = true, ["non-admin settlement"] = false, ["capital"] = true, ["natural feature"] = false, ["man-made structure"] = false, ["geographic region"] = false, ["generic place"] = false, } local capital_cat_to_placetype = {} for placetype, capital_cat in pairs(m_placetypes.placetype_to_capital_cat) do capital_cat_to_placetype[capital_cat] = placetype end -- Handler for bare categories for all types of capitals. This needs to precede the handler for bare placetype -- categories as some of the types of capitals exist as placetypes as well. insert(handlers, function(label) label = lcfirst(label) local capital_placetype = capital_cat_to_placetype[label] if capital_placetype then local pl_placetype = m_placetypes.pluralize_placetype(capital_placetype) local linkdesc = m_placetypes.get_placetype_display_form(pl_placetype, "top-level") if linkdesc == nil then internal_error("Unrecognized placetype %s when processing label %s", capital_placetype, label) end if linkdesc == false then mw.log(("Display form for pl_placetype %s is false, can't categorize"):format(dump(pl_placetype))) return nil end return { type = "name", topic = label, description = "{{{langname}}} names of [[capital]]s of " .. linkdesc .. ".", parents = {"capital cities"}, } end end) -- Handler for bare placetype categories. FIXME: Add wpcat= and commonscat= info. Previously we had it for various -- so-called "generic" placetypes, but sometimes the categories were wrong. insert(handlers, function(label) for _, canon_label in ipairs { lcfirst(label), label } do local ptdesc, ptdata = m_placetypes.get_placetype_display_form(canon_label, "top-level", "return full") if ptdesc then local from_category_props = { from_category = true, no_split_qualifiers = true, } local bare_category_parent = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt) local bare_category_parent = m_placetypes.get_placetype_prop(pt, "bare_category_parent") if bare_category_parent then return bare_category_parent end local class = m_placetypes.get_placetype_prop(pt, "class") if class then if class_to_bare_category_parent[class] == nil then internal_error("Saw unknown category class %s derived from placetype %s", class, canon_label) end return class_to_bare_category_parent[class] end end, from_category_props) if not bare_category_parent then internal_error("Saw placetype %s without a `class` or `bare_category_parent` setting, either " .. "directly or through a fallback", canon_label) end local addl_bare_category_parents = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt) return m_placetypes.get_placetype_prop(pt, "addl_bare_category_parents") end, from_category_props) local bare_category_breadcrumb = m_placetypes.get_equiv_placetype_prop(canon_label, function(pt) return m_placetypes.get_placetype_prop(pt, "bare_category_breadcrumb") end, from_category_props) if type(bare_category_parent) == "string" and bare_category_breadcrumb then bare_category_parent = {name = bare_category_parent, sort = bare_category_breadcrumb} end local parents = {bare_category_parent} if addl_bare_category_parents then m_table.extend(parents, addl_bare_category_parents) end return { type = "name", topic = canon_label, description = "{{{langname}}} " .. ptdesc .. ".", breadcrumb = bare_category_breadcrumb, parents = parents, } elseif ptdesc == false then mw.log(("Display form for canon_label %s is false, can't categorize"):format(dump(canon_label))) end end end) local function fetch_primary_placetype(key, spec) local placetype = spec.placetype if type(placetype) == "table" then placetype = placetype[1] end if not placetype then internal_error("No placetype specified or defaulted for key %s, spec %s", key, spec) end return placetype end --[==[ Construct an appropriately linked location based on the full or elliptical placename, preceded by `"the "`` if appropriate. Specifically: Fetch the full and elliptical_placenames. If they are the same, just link to the placename directly. Otherwise, check if the full placename exists; if so link to it. Otherwise, if the elliptical placename exists, link to it but display it as the full placename. Finally, if neither full placename nor elliptical placename exists, fall back to linking to the full placename. That way, we prefer full placenames to elliptical placenames if both or neither exist as Wiktionary entries, but if only one exists, we link to that one rather than have a red link. ]==] local function construct_linked_location(group, key, spec) local full_placename, elliptical_placename = m_locations.key_to_placename(group, key) local linked_placename if elliptical_placename ~= full_placename then local full_placename_title = mw.title.new(full_placename) if full_placename_title and full_placename_title.exists then linked_placename = m_locations.construct_linked_placename(spec, full_placename) else local elliptical_placename_title = mw.title.new(elliptical_placename) if elliptical_placename_title and elliptical_placename_title.exists then linked_placename = m_locations.construct_linked_placename(spec, elliptical_placename, full_placename) end end end return linked_placename or m_locations.construct_linked_placename(spec, full_placename) end --[==[ Construct the description of a location, including its container trail either to the end or until we encounter a `no_include_container_in_desc` setting. For example, for the city of [[Birmingham]], the description will read `"[[Birmingham]], a [[city]] in the [[West Midlands]] (which is a [[county]] of [[England]], which is a [[constituent country]] of the [[United Kingdom]], which is a [[country]] in [[Europe]])"`. FIXME: Possibly we should adopt the way city descriptions used to read, which was similar to `"the city of [[Birmingham]], in the county of the [[West Midlands]], in the [[constituent country]] of [[England]], in the [[country]] of the [[United Kingdom]], in [[Europe]]"`. ]==] local function construct_location_desc(group, key, spec) local parts = {} local function ins(txt) insert(parts, txt) end ins(construct_linked_location(group, key, spec)) local iteration = 0 local need_closing_paren = false local containers = {{group = group, key = key, spec = spec}} local container_iterator = m_locations.iterate_containers(group, key, spec) while true do iteration = iteration + 1 local include_container_in_desc = false for _, container in ipairs(containers) do if not container.spec.no_include_container_in_desc then include_container_in_desc = true break end end if not include_container_in_desc then break end local next_containers = container_iterator() if not next_containers then break end local is_former = nil for _, container in ipairs(containers) do local this_is_former = container.spec.is_former_place if is_former == nil then is_former = this_is_former elseif is_former ~= this_is_former then internal_error("When processing container trail of key %s, found a mixture of former and non-former " .. "containers: %s", key, containers) end end if #containers > 1 then local placetypes = {} local prepositions = {} for _, container in ipairs(containers) do local container_type = fetch_primary_placetype(container.key, container.spec) m_table.insertIfNot(placetypes, m_placetypes.pluralize_placetype(container_type)) m_table.insertIfNot(prepositions, m_placetypes.get_placetype_entry_preposition(container_type)) end if iteration == 1 then ins(", ") elseif iteration == 2 then ins(" (which are ") need_closing_paren = true else ins(", which are ") end if is_former then ins("former ") end ins(m_table.serialCommaJoin(placetypes)) ins(" ") ins(concat(prepositions, "/")) else if iteration == 1 then ins(", ") elseif iteration == 2 then ins(" (which is ") need_closing_paren = true else ins(", which is ") end local container_type = fetch_primary_placetype(containers[1].key, containers[1].spec) if is_former then ins("a former ") else ins(m_placetypes.get_placetype_article(container_type)) ins(" ") end ins(container_type) ins(" ") ins(m_placetypes.get_placetype_entry_preposition(container_type)) end ins(" ") first_container = false containers = next_containers local container_locations = {} for _, container in ipairs(containers) do insert(container_locations, construct_linked_location(container.group, container.key, container.spec)) end ins(m_table.serialCommaJoin(container_locations)) end if need_closing_paren then ins(")") end return concat(parts) end -- Fetch or construct the description of the location specified by `key`. If the `keydesc` property is specified, -- use it directly but substitute any occurrence of `+++` with the auto-constructed location description, which -- mentions the placename corresponding to the key, its placetype and container, and repeats the description up -- the container trail until either there are no more containers or (more usually) the `no_include_container_in_desc` -- setting is found (which is set on all continents and continent-level regions). local function fetch_or_construct_location_desc(group, key, spec) local val = spec.keydesc if is_callable(val) then val = val(group, key, spec) spec.keydesc = val end val = val or "+++" if val:find("%+%+%+") then val = gsub_literally(val, "+++", construct_location_desc(group, key, spec)) end return val end local function normalize_cat_as(cat_as, div) if type(cat_as) ~= "table" or cat_as.type then cat_as = {cat_as} end local ret_cat_as = {} for _, pt_cat_as in ipairs(cat_as) do if type(pt_cat_as) == "string" then pt_cat_as = {type = pt_cat_as} end insert(ret_cat_as, {type = pt_cat_as.type, prep = pt_cat_as.prep or div.prep or "of"}) end return ret_cat_as end -- Find the specified plural placetype among the divs for a given known location. Return a list of cat_as specs, where -- each spec is of the form {type = "PLURAL_PLACETYPE", prep = "PREP"} indicating the plural placetype to use when -- categorizing and the preposition to follow. local function find_placetype_cat_as(divs, pl_placetype) if divs then if type(divs) ~= "table" then divs = {divs} end for _, div in ipairs(divs) do if type(div) == "string" then div = {type = div} end if div.type == pl_placetype then local cat_as = div.cat_as or div.type return normalize_cat_as(cat_as, div) end end end return nil end -- Handler for bare placename categories for known locations in `locations` in [[Module:place/locations]]. insert(handlers, function(label) for _, canon_label in ipairs { label, lcfirst(label) } do local group, spec = m_locations.find_canonical_key(canon_label) if group then -- wp= defaults to true (Wikipedia article matches location's full placename) local wp = spec.wp if wp == nil then wp = true end -- wpcat= defaults to wp= (if Wikipedia article has its own name, Wikipedia category and Commons category -- generally follow) local wpcat = spec.wpcat if wpcat == nil then wpcat = wp end -- commonscat= defaults to wpcat= (if Wikipedia category has its own name, Commons category generally -- follows) local commonscat = spec.commonscat if commonscat == nil then commonscat = wpcat end local parents = {} local bare_label_parents = spec.overriding_bare_label_parents local container_iterator = m_locations.iterate_containers(group, canon_label, spec) local containers = container_iterator() if not bare_label_parents then bare_label_parents = {"+++"} end local full_location_placename, elliptical_location_placename = m_locations.key_to_placename(group, canon_label) local full_container_placename if containers then full_container_placename, _ = m_locations.key_to_placename(containers[1].group, containers[1].key) end local inserted_containers = false for _, parent in ipairs(bare_label_parents) do if parent == "+++" then parent = "PL_PLACETYPE PREP CONTAINER" end if parent:find("CONTAINER") then if not containers then internal_error("Parent category %s needs the container of %s but no containers specified: %s", parent, canon_label, spec) end local location_type = fetch_primary_placetype(canon_label, spec) local pl_location_type = m_placetypes.pluralize_placetype(location_type) for _, container in ipairs(containers) do local per_container_parent = parent local cat_as_list if per_container_parent:find("PL_PLACETYPE") then if spec.bare_category_parent_type then cat_as_list = normalize_cat_as(spec.bare_category_parent_type, spec) else cat_as_list = find_placetype_cat_as(container.spec.divs, pl_location_type) or find_placetype_cat_as(container.spec.addl_divs, pl_location_type) end end if not cat_as_list then local canon_placetype, ptdata, ptmatch = m_placetypes.get_placetype_data(location_type, "from category") if not canon_placetype or not (ptdata.generic_before_non_cities or ptdata.generic_before_cities) then internal_error("Unable to locate plural location type %s among the divs or addl_divs " .. "for container key %s spec %s, and the location type is either not in placetype_data or " .. "not identified as a generic placetype", pl_location_type, container.key, container.spec) end cat_as_list = {{type = pl_location_type, prep = m_placetypes.get_placetype_entry_preposition(location_type)}} end local prefixed_key = m_placetypes.get_prefixed_key(container.key, container.spec) per_container_parent = gsub_literally(per_container_parent, "CONTAINER", prefixed_key) for _, cat_as in ipairs(cat_as_list) do local per_container_per_placetype_parent = per_container_parent per_container_per_placetype_parent = gsub_literally(per_container_per_placetype_parent, "PL_PLACETYPE", cat_as.type) per_container_per_placetype_parent = gsub_literally(per_container_per_placetype_parent, "PREP", cat_as.prep) m_table.insertIfNot(parents, per_container_per_placetype_parent) end end inserted_containers = true else m_table.insertIfNot(parents, parent) end end if not inserted_containers and containers then -- If we didn't insert the containers above in some form, insert them now as bare categories. Note that -- this may be different categories from the container categories inserted above. for _, container in ipairs(containers) do m_table.insertIfNot(parents, container.key) end end if spec.addl_parents then for _, parent in ipairs(spec.addl_parents) do m_table.insertIfNot(parents, parent) end end local function format_boxval(val, specname) if val == true then val = "%l" end if type(val) == "string" then val = gsub_literally(val, "%l", full_location_placename) val = gsub_literally(val, "%e", elliptical_location_placename) if val:find("%%c") then if not full_container_placename then internal_error("Wikipedia/Commons spec %s = %s has %%c in it but key %s has no " .. "containers: %s", specname, val, canon_label, spec) end val = gsub_literally(val, "%c", full_container_placename) end end return val end local description = spec.fulldesc or ( "{{{langname}}} terms related to the people, culture, or territory of " .. fetch_or_construct_location_desc(group, canon_label, spec) .. ".") local full_placename, _ = m_locations.key_to_placename(group, canon_label) return { type = "topic", description = description, breadcrumb = full_placename, parents = parents, wp = format_boxval(wp, "wp"), wpcat = format_boxval(wpcat, "wpcat"), commonscat = format_boxval(commonscat, "commonscat"), } end end end) local function find_canonical_key_from_place(place, canon_label) local has_the = false local key if place:find("^the ") then key = place:gsub("^the ", "") has_the = true else key = place end local group, spec = m_locations.find_canonical_key(key) if group then local requires_the = spec.the or false if has_the ~= requires_the then if has_the then mw.log(("Mismatch in category name '%s', has 'the' in the category when it should not"):format( canon_label)) else mw.log(("Mismatch in category name '%s', should have 'the' in the category but does not"): format(canon_label)) end return nil end return group, key, spec end return nil end -- Handler for generic placetypes (those whose categories are added through category generation handlers or through -- explicit category specs in the placetype data) for known locations in [[Module:place/locations]]. All such -- placetypes have either a `generic_before_non_cities` setting (meaning they can occur before non-city locations) or -- `generic_before_cities` setting (meaning they can occur before cities), or both. Examples of such categories are -- "cities in the Bahamas" or "rivers in Western Australia, Australia", or (for city locations) -- "neighbourhoods of Hong Kong" or "places in Melbourne". insert(handlers, function(label) for _, canon_label in ipairs { lcfirst(label), label } do local placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (in) (.*)$") if not placetype then placetype, in_of, place = canon_label:match("^([A-Za-z%- ]-) (of) (.*)$") end if placetype then local normalized_placetype = placetype == "neighbourhoods" and "neighborhoods" or placetype local canon_placetype, ptdata, ptmatch = m_placetypes.get_placetype_data(normalized_placetype, "from category") if canon_placetype and (ptdata.generic_before_non_cities or ptdata.generic_before_cities) then local group, key, spec = find_canonical_key_from_place(place, canon_label) if group then -- Check whether the location uses British spelling, but also check all containers, because -- it's too hard to keep in sync the `british_spelling` setting for locations at all different -- levels (e.g. cities of various countries, first and second level administrative division, etc.), -- so we just set it at top level on the country. local uses_british_spelling = spec.british_spelling if uses_british_spelling == nil then for containers in m_locations.iterate_containers(group, key, spec) do local must_outer_break = false for _, container in ipairs(containers) do if container.spec.british_spelling ~= nil then uses_british_spelling = container.spec.british_spelling must_outer_break = true break end end if must_outer_break then break end end end local allow_cat = true if placetype == "neighborhoods" and uses_british_spelling or placetype == "neighbourhoods" and not uses_british_spelling then mw.log(("Mismatch in spelling of placetype '%s' in category '%s', should be '%s'"):format( placetype, canon_label, uses_british_spelling and "neighbourhoods" or "neighborhoods")) allow_cat = false end if spec.is_former_place and placetype ~= "places" then allow_cat = false end local expected_prep if spec.is_city then expected_prep = ptdata.generic_before_cities else expected_prep = ptdata.generic_before_non_cities end if not expected_prep then allow_cat = false end if allow_cat then if expected_prep ~= in_of then mw.log(("Mismatch in category name '%s', has '%s' when it should have '%s'"):format( canon_label, in_of, expected_prep)) return nil end local linkdesc = m_placetypes.get_placetype_display_form(placetype, spec.is_city and "city" or "noncity", "return full") if linkdesc == false then mw.log(("Display form for placetype %s is false, can't categorize"):format(dump(placetype))) return nil end if not linkdesc then internal_error("Unrecognized placetype %s when processing key %s, data %s, label %s", placetype, key, spec, canon_label) end desc = linkdesc .. " " .. in_of .. " " .. fetch_or_construct_location_desc(group, key, spec) desc = "{{{langname}}} " .. desc .. "." local parents = {} insert(parents, key) if spec.no_container_parent then -- top-level country, constituent country, continent or the like insert(parents, {name = normalized_placetype, sort = key}) if spec.placetype == "country" or m_table.contains(spec.placetype, "country") then local category_class = m_placetypes.get_equiv_placetype_prop(normalized_placetype, function(pt) return m_placetypes.get_placetype_prop(pt, "class") end, { from_category = true, no_split_qualifiers = true, }) if not category_class then internal_error("Saw placetype %s that is either unknown or has no `class` " .. "setting in `placetype_data`", normalized_placetype) end if class_is_political_division[category_class] == nil then internal_error("Saw unknown category class %s derived from placetype %s", category_class, normalized_placetype) end if class_is_political_division[category_class] then insert(parents, "political divisions of specific countries") end end else local container_iterator = m_locations.iterate_containers(group, key, spec) local next_containers = container_iterator() if next_containers then for _, container in ipairs(next_containers) do local container_prep if container.spec.is_city then container_prep = ptdata.generic_before_cities else container_prep = ptdata.generic_before_non_cities end if not container_prep then internal_error("For container key %s spec %s defines is_city = %s but " .. "there is no corresponding `generic_before_*` setting in the " .. "placedata for placetype %s", container.key, container.spec, container.spec.is_city, placetype) end insert(parents, { name = placetype .. " " .. container_prep .. " " .. m_placetypes.get_prefixed_key( container.key, container.spec), sort = key }) end else -- unrecognized countries or the like insert(parents, {name = normalized_placetype, sort = key}) end end return { type = "name", topic = canon_label, description = desc, breadcrumb = placetype, parents = parents, } end end end end end end) -- Handler for "state capitals of the United States", "provincial capitals of Canada", etc. This must precede the next -- handler for specific political and misc (non-political) divisions of polities and subpolities, such as -- "provinces of the Philippines", because "departmental capitals" is listed in cat_as for French prefectures and so -- will trigger an error if that handler runs before this one. insert(handlers, function(label) label = lcfirst(label) local capital_cat, place = label:match("^([a-z%- ]- capitals) of (.*)$") -- Make sure we recognize the type of capital. if place and capital_cat_to_placetype[capital_cat] then local placetype = capital_cat_to_placetype[capital_cat] local pl_placetype = m_placetypes.pluralize_placetype(placetype) -- Locate the container, fetch its known political divisions, and make sure the placetype corresponding to the -- type of capital is among the list. local group, key, spec = find_canonical_key_from_place(place, canon_label) if group and (spec.divs or spec.addl_divs) then local saw_match = false local variant_matches = {} local divlists = {} if spec.divs then insert(divlists, spec.divs) end if spec.addl_divs then insert(divlists, spec.addl_divs) end for _, divlist in ipairs(divlists) do if type(divlist) ~= "table" then divlist = {divlist} end for _, div in ipairs(divlist) do if type(div) == "string" then div = {type = div} end -- HACK. Currently if we don't find a match for the placetype, we map e.g. 'autonomous region' -- -> 'regional capitals' and 'union territory' -> 'territorial capitals'. When encountering a -- political division like 'autonomous region' or 'union territory', chop off everything up -- through a space to make things match. To make this clearer, we record all such -- "variant match" cases, and down below we insert a note into the category text indicating that -- such "variant matches" are included among the category. if pl_placetype == div.type or pl_placetype == div.type:gsub("^.* ", "") then saw_match = true if pl_placetype ~= div.type then insert(variant_matches, div.type) end end end end if saw_match then -- Everything checks out, construct the category description. local placetype_desc = m_placetypes.get_placetype_display_form(pl_placetype, placetype.is_city and "city" or "noncity") if placetype_desc == false then mw.log(("Display form for pl_placetype %s is false, can't categorize"):format(dump(pl_placetype))) return nil end if not placetype_desc then internal_error("Unrecognized plural placetype %s, generated as the plural of %s, which " .. "was found as the placetype of capital placetype %s in label %s", pl_placetype, placetype, capital_cat, label) end local variant_match_text = "" if variant_matches[1] then local real_variant_match_descs = {} for i, variant_match in ipairs(variant_matches) do local variant_match_desc = m_placetypes.get_placetype_display_form(variant_match, placetype.is_city and "city" or "noncity") if variant_match_desc == nil then internal_error("Unrecognized variant match plural placetype %s, coming from " .. "place key %s, data %s in label %s", variant_match, key, spec, label) end if variant_match_desc then -- skip those for which the description is `false`, like `ABBREVIATION_OF states` -- in the United States divs. insert(real_variant_match_descs, variant_match_desc) end end if real_variant_match_descs[1] then variant_match_text = " (including " .. m_table.serialCommaJoin(real_variant_match_descs) .. ")" end end local desc = "{{{langname}}} names of [[capital]]s of " .. placetype_desc .. variant_match_text .. " of " .. fetch_or_construct_location_desc(group, key, spec) .. "." local full_placename, _ = m_locations.key_to_placename(group, key) local parents = {} if spec.no_container_parent then -- top-level country, constituent country, continent or the like insert(parents, {name = capital_cat, sort = key}) else local container_iterator = m_locations.iterate_containers(group, key, spec) local next_containers = container_iterator() if next_containers then for _, container in ipairs(next_containers) do insert(parents, { name = capital_cat .. " of " .. m_placetypes.get_prefixed_key( container.key, container.spec), sort = key }) end else -- unrecognized countries or the like insert(parents, {name = capital_cat, sort = key}) end end insert(parents, key) return { type = "name", topic = label, description = desc, breadcrumb = full_placename, parents = parents, } end end end end) local overriding_category_descriptions = { ["autonomous cities of Spain"] = "the [[w:Autonomous communities of Spain#Autonomous_cities|autonomous cities of Spain]]", ["regions of Greece"] = "the regions ([[periphery|peripheries]]) of [[Greece]]", ["regions of North Macedonia"] = "the regions ([[periphery|peripheries]]) of [[North Macedonia]]", ["subprefectures of Japan"] = "[[subprefecture]]s of [[Japan]]ese [[prefecture]]s", } -- Handler for specific political and misc (non-political) divisions of locations (polities, subpolities, cities, etc.), -- such as "provinces of the Philippines", "counties of Wales", "municipalities of Tocantins, Brazil", -- "boroughs of New York City", etc. This does not handle categories for generic placetypes (cities, rivers, etc.) of -- locations, which are handled by different handlers above. insert(handlers, function(label) -- The label comes with an initial capitalization but we have to check both lowercase-initial and capital-initial -- versions of the placetype to handle e.g. [[:Category:en:Indian reserves of Canada]]. for _, canon_label in ipairs { label, lcfirst(label) } do for _, minimal_placetype in ipairs { true, false } do local match_quantifier = minimal_placetype and "-" or "+" -- Some categories have two "of"s in them, and depending on the category, it's correct to do either a greedy -- ([[:Category:en:Abbreviations of states of the United States]], with placetype `abbreviations of states`) -- or non-greedy ([[:Category:en:Provinces of the Democratic Republic of the Congo]], with placetype -- `provinces`) match. We can't know in advance which is correct so we try both possibilities, doing the -- non-greedy one first as it seems more common (there are many locations with "of" in them, but currently -- only `abbreviations of states` occurs with a following location). local placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (of) (.*)$") if not placetype then placetype, in_of, place = canon_label:match("^([A-Za-z%- ]" .. match_quantifier .. ") (in) (.*)$") end if placetype then local group, key, spec = find_canonical_key_from_place(place, canon_label) if group then local function find_placetype(divs) if divs then if type(divs) ~= "table" then divs = {divs} end for _, div in ipairs(divs) do if type(div) == "string" then div = {type = div} end local cat_as = div.cat_as or div.type if type(cat_as) ~= "table" then cat_as = {cat_as} end for _, pt_cat_as in ipairs(cat_as) do if type(pt_cat_as) == "string" then pt_cat_as = {type = pt_cat_as} end if placetype == pt_cat_as.type then local div_parent = pt_cat_as.container_parent_type if div_parent == nil then -- allow false div_parent = div.container_parent_type end if div_parent == nil then div_parent = placetype end return div_parent, pt_cat_as.prep or div.prep or "of" end end end end return nil end local div_parent, div_prep = find_placetype(spec.divs) if div_parent == nil then -- allow false div_parent, div_prep = find_placetype(spec.addl_divs) end if div_parent == nil then -- allow false div_parent, div_prep = find_placetype(spec.addl_divs_for_categorization) end if div_parent ~= nil then if div_prep ~= in_of then mw.log(("Mismatch in category name '%s', has '%s' when it should have '%s'"):format( canon_label, in_of, div_prep)) return nil end local linkdesc = m_placetypes.get_placetype_display_form(placetype, spec.is_city and "city" or "noncity", "return full") if linkdesc == false then mw.log(("Display form for placetype %s is false, can't categorize"):format(dump(placetype))) return nil end if not linkdesc then internal_error("Unrecognized placetype %s when processing key %s, data %s, label %s", placetype, key, spec, canon_label) end local desc = overriding_category_descriptions[canon_label] if not desc then desc = linkdesc .. " " .. in_of .. " " .. fetch_or_construct_location_desc(group, key, spec) end desc = "{{{langname}}} " .. desc .. "." local parents = {} insert(parents, key) if div_parent then -- div_parent may be `false` if spec.no_container_parent then -- top-level country, constituent country, continent or the like insert(parents, {name = placetype, sort = " " .. key}) if spec.placetype == "country" or m_table.contains(spec.placetype, "country") then insert(parents, "political divisions of specific countries") end else local container_iterator = m_locations.iterate_containers(group, key, spec) local next_containers = container_iterator() if next_containers then for _, container in ipairs(next_containers) do insert(parents, { name = div_parent .. " " .. in_of .. " " .. m_placetypes.get_prefixed_key( container.key, container.spec), sort = key }) end else -- unrecognized countries or the like insert(parents, {name = placetype, sort = " " .. key}) end end end return { type = "name", topic = canon_label, description = desc, breadcrumb = placetype, parents = parents, } end end end end end end) labels["exonyms"] = { type = "name", -- special-cased description description = "{{{langname}}} [[exonym]]s.", parents = {"places"}, } labels["political divisions of specific countries"] = { type = "grouping", description = "{{{langname}}} categories for political divisions of specific countries.", parents = {"places"}, } -- Misc. FIXME: Remove the need for this. labels["nomes of Ancient Egypt"] = { type = "name", -- special-cased description description = "{{{langname}}} names of the [[nome]]s of [[Ancient Egypt]].", breadcrumb = "nomes", parents = {"Ancient Egypt"}, } -- Sui generis place categories (mostly cross-jurisdictional subcontinental/transcontinental regions) -- FIXME: Everything here has been moved from [[Module:category tree/topic/Earth]]. Most should be removed. labels["Atlantic Ocean"] = { type = "related-to", description = "default with the", parents = {"Earth"}, } labels["British Isles"] = { type = "related-to", description = "=the people, culture, or territory of [[Great Britain]], [[Ireland]], and other nearby islands", parents = {"Europe", "islands"}, } labels["European Union"] = { type = "related-to", description = "default with the", parents = {"Europe"}, } labels["Gascony"] = { type = "related-to", parents = {"Occitania, France"}, } labels["Indian subcontinent"] = { type = "related-to", description = "default with the", parents = {"South Asia"}, } labels["Bengal"] = { type = "related-to", description = "{{{langname}}} terms related to the people, culture, or territory of [[Bengal]].", parents = {"Indian subcontinent"}, } labels["Kashmir"] = { type = "related-to", description = "{{{langname}}} terms related to the people, culture, or territory of [[Kashmir]].", parents = {"Indian subcontinent"}, } labels["Kashmir, India"] = { type = "related-to", description = "{{{langname}}} names of places in {{w|Kashmir, India}}.", parents = {"India", "Kashmir"}, } labels["Korea"] = { type = "related-to", description = "=the people, culture, or territory of [[Korea]]", parents = {"Asia"}, } labels["Languedoc"] = { type = "related-to", parents = {"Occitania, France"}, } labels["Lapland"] = { type = "related-to", description = "=[[Lapland]], a region in northernmost Europe", parents = {"Europe", "Finland", "Norway", "Russia", "Sweden"}, } labels["Middle East"] = { type = "related-to", description = "default with the", parents = {"Africa", "Asia"}, } labels["Netherlands Antilles"] = { type = "related-to", description = "=the people, culture, or territory of the [[Netherlands Antilles]]", parents = {"Netherlands", "North America"}, } labels["Overseas France"] = { type = "related-to", description = "={{w|Overseas France}} ({{m|fr||France d'outre-mer}})", parents = {"France"}, } labels["Provence"] = { type = "related-to", parents = {"Provence-Alpes-Côte d'Azur, France"}, } labels["Polish People's Republic"] = { type = "related-to", parents = {"Poland"}, } labels["South Asia"] = { type = "related-to", parents = {"Eurasia", "Asia"}, } return {LABELS = labels, HANDLERS = handlers} d3765m11xpzqpaf3g1rpd7tkzgydkgp साँचा:place 10 304761 489341 478025 2026-09-22T18:26:33Z SM7 6218 updating... 489341 wikitext text/x-wiki <includeonly>{{#invoke:place|show}}</includeonly><noinclude>{{documentation}}</noinclude> e5udahvzm41nr8p2qjycaj5kcvpvalr मॉड्यूल:place/placetypes 828 304762 489343 477896 2026-09-22T18:31:33Z SM7 6218 SM7 ने अनुप्रेषण छोड़े बिना पृष्ठ [[मॉड्यूल:place/data]] को [[मॉड्यूल:place/placetypes]] पर स्थानांतरित किया 477896 Scribunto text/plain local export = {} local m_shared = require("Module:place/shared-data") local m_links = require("Module:links") local m_strutils = require("Module:string utilities") local function ucfirst(label) return mw.getContentLanguage():ucfirst(label) end local function lc(label) return mw.getContentLanguage():lc(label) end export.force_cat = false -- set to true for testing -- 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 'placetype_equivs', which apply to categorization and -- other processes but not to display. export.placetype_aliases = { ["c"] = "country", ["cc"] = "constituent country", ["p"] = "province", ["ap"] = "autonomous province", ["r"] = "region", ["ar"] = "autonomous region", ["adr"] = "administrative region", ["sar"] = "special administrative region", ["s"] = "state", ["arch"] = "archipelago", ["bor"] = "borough", ["can"] = "canton", ["carea"] = "council area", ["cdblock"] = "community development block", ["cdep"] = "Crown dependency", ["cdp"] = "census-designated place", ["CDP"] = "census-designated place", ["co"] = "county", ["cobor"] = "county borough", ["colcity"] = "county-level city", ["coll"] = "collectivity", ["comm"] = "community", ["acomm"] = "autonomous community", ["cont"] = "continent", ["cpar"] = "civil parish", ["dep"] = "dependency", ["dept"] = "department", ["dist"] = "district", ["distmun"] = "district municipality", ["div"] = "division", ["fpref"] = "French prefecture", ["gov"] = "governorate", ["govnat"] = "governorate", ["ires"] = "Indian reservation", ["isl"] = "island", ["lbor"] = "London borough", ["lgarea"] = "local government area", ["lgdist"] = "local government district", ["metbor"] = "metropolitan borough", ["metcity"] = "metropolitan city", ["mtn"] = "mountain", ["mun"] = "municipality", ["mundist"] = "municipal district", ["obl"] = "oblast", ["aobl"] = "autonomous oblast", ["okr"] = "okrug", ["aokr"] = "autonomous okrug", ["par"] = "parish", ["parmun"] = "parish municipality", ["pen"] = "peninsula", ["pref"] = "prefecture", ["prefcity"] = "prefecture-level city", ["preflcity"] = "prefecture-level city", ["apref"] = "autonomous prefecture", ["rep"] = "republic", ["arep"] = "autonomous republic", ["riv"] = "river", ["rcomun"] = "regional county municipality", ["rdist"] = "regional district", ["rmun"] = "regional municipality", ["robor"] = "royal borough", ["runit"] = "regional unit", ["rurmun"] = "rural municipality", ["terrauth"] = "territorial authority", ["terr"] = "territory", ["aterr"] = "autonomous territory", ["uterr"] = "union territory", ["tjarea"] = "tribal jurisdictional area", ["twp"] = "township", ["twpmun"] = "township municipality", ["utwpmun"] = "united township municipality", ["val"] = "valley", ["voi"] = "voivodeship", ["wcomm"] = "Welsh community", ["range"] = "mountain range", ["departmental capital"] = "department capital", ["home-rule city"] = "home rule city", ["home-rule municipality"] = "home rule municipality", ["sprovcity"] = "subprovincial city", ["sub-provincial city"] = "subprovincial city", ["sub-provincial district"] = "subprovincial district", ["sprefcity"] = "sub-prefectural city", ["sub-prefecture-level city"] = "sub-prefectural city", ["nonmetropolitan county"] = "non-metropolitan county", ["inner-city area"] = "inner city area", } -- These qualifiers can be prepended onto any placetype and will be handled correctly. -- For example, the placetype "large city" will be displayed as such but otherwise -- treated exactly as if "city" were specified. Links will be added to the remainder -- of the placetype as appropriate, e.g. "small voivodeship" will display as -- "small [[voivoideship]]" because "voivoideship" has an entry in placetype_links. -- If the value is a string, the qualifier will display according to the string. -- Note that these qualifiers do not override placetypes with entries elsewhere that -- contain those same qualifiers. For example, the entry for "former colony" in -- placetype_equivs will apply in preference to treating "former colony" as equivalent -- to "colony". Also note that if an entry like "former colony" appears in either -- placetype_equivs or cat_data, the non-qualifier portion won't automatically be -- linked, so it needs to be specifically included in placetype_links if linking is -- desired. export.placetype_qualifiers = { -- generic qualifiers ["huge"] = true, ["tiny"] = true, ["large"] = true, ["small"] = true, ["sizable"] = true, ["important"] = true, ["long"] = true, ["short"] = true, ["major"] = true, ["minor"] = true, ["high"] = true, ["low"] = true, ["left"] = true, -- left tributary ["right"] = true, -- right tributary ["modern"] = true, -- for use in opposition to "ancient" in another definition -- "former" qualifiers ["abandoned"] = true, ["ancient"] = true, ["deserted"] = true, ["extinct"] = true, ["former"] = true, ["historic"] = "historical", ["historical"] = true, ["medieval"] = true, ["mediaeval"] = true, ["traditional"] = true, -- sea qualifiers ["coastal"] = true, ["inland"] = true, ["maritime"] = true, ["overseas"] = "[[overseas]]", ["seaside"] = "coastal", ["beachfront"] = "[[beachfront]]", ["beachside"] = "[[beachfront]]", ["riverside"] = true, -- political status qualifiers ["autonomous"] = "[[autonomous]]", ["incorporated"] = "[[incorporated]]", ["special"] = "[[special]]", ["unincorporated"] = "[[unincorporated]]", -- monetary status/etc. qualifiers ["fashionable"] = true, ["wealthy"] = true, ["affluent"] = "[[affluent]]", ["declining"] = "[[declining]]", -- city vs. rural qualifiers ["urban"] = true, ["suburban"] = "[[suburban]]", ["outlying"] = true, ["remote"] = true, ["rural"] = true, ["inner"] = true, ["outer"] = true, -- land use qualifiers ["residential"] = "[[residential]]", ["agricultural"] = "[[agricultural]]", ["business"] = true, ["commercial"] = "[[commercial]]", ["industrial"] = "[[industrial]]", -- business use qualifiers ["railroad"] = "[[railroad]]", ["railway"] = "[[railway]]", ["farming"] = "[[farming]]", ["fishing"] = "[[fishing]]", ["mining"] = "[[mining]]", ["logging"] = "[[logging]]", ["cattle"] = "[[cattle]]", -- religious qualifiers ["holy"] = true, ["sacred"] = true, ["religious"] = true, ["secular"] = true, -- qualifiers for nonexistent places ["fictional"] = true, ["mythological"] = true, -- directional qualifiers ["northern"] = true, ["southern"] = true, ["eastern"] = true, ["western"] = true, ["north"] = true, ["south"] = true, ["east"] = true, ["west"] = true, ["northeastern"] = true, ["southeastern"] = true, ["northwestern"] = true, ["southwestern"] = true, ["northeast"] = true, ["southeast"] = true, ["northwest"] = true, ["southwest"] = true, -- misc. qualifiers ["hilly"] = true, ["planned"] = true, ["chartered"] = true, } -- If there's an entry here, the corresponding placetype will use the text of the -- value, which should be used to add links. If the value is true, a simple link -- will be added around the whole placetype. If the value is "w", a link to -- Wikipedia will be added around the whole placetype. export.placetype_links = { ["administrative capital"] = "w", ["administrative center"] = "w", ["administrative centre"] = "w", ["administrative county"] = "w", ["administrative district"] = "w", ["administrative headquarters"] = "[[administrative]] [[headquarters]]", ["administrative region"] = true, ["administrative seat"] = "w", ["administrative village"] = "w", ["alliance"] = true, ["archipelago"] = true, ["associated province"] = "[[associated]] [[province]]", ["atoll"] = true, ["autonomous city"] = "w", ["autonomous community"] = true, ["autonomous oblast"] = true, ["autonomous okrug"] = true, ["autonomous prefecture"] = true, ["autonomous province"] = "w", ["autonomous region"] = "w", ["autonomous republic"] = "w", ["autonomous territory"] = "w", ["bailiwick"] = true, ["barangay"] = true, -- Philippines ["barrio"] = true, -- Spanish-speaking countries; Philippines ["bay"] = true, ["beach resort"] = "w", ["bishopric"] = true, ["borough"] = true, ["borough seat"] = true, ["branch"] = true, ["burgh"] = true, ["caliphate"] = true, ["canton"] = true, ["cape"] = true, ["capital"] = true, ["capital city"] = true, ["caplc"] = "[[capital]] and largest city", ["caravan city"] = true, ["cathedral city"] = true, ["cattle station"] = true, -- Australia ["census area"] = true, ["census-designated place"] = true, -- United States ["central business district"] = true, ["ceremonial county"] = true, ["channel"] = true, ["charter community"] = "w", -- Northwest Territories, Canada ["city-state"] = true, ["civil parish"] = true, ["coal town"] = "w", ["collectivity"] = true, ["commandery"] = true, ["commonwealth"] = true, ["commune"] = true, ["community"] = true, ["community development block"] = "w", -- India ["comune"] = true, -- Italy, Switzerland ["confederacy"] = true, ["confederation"] = true, ["constituent country"] = true, ["contregion"] = "[[continental]] region", ["council area"] = true, ["county-administered city"] = "w", -- Taiwan ["county-controlled city"] = "w", -- Taiwan ["county-level city"] = "w", -- China ["county borough"] = true, ["county seat"] = true, ["county town"] = true, ["crown dependency"] = true, ["Crown dependency"] = true, ["department"] = true, ["department capital"] = "[[department]] [[capital]]", ["dependency"] = true, ["dependent territory"] = "w", ["deserted mediaeval village"] = "w", ["deserted medieval village"] = "w", ["direct-administered municipality"] = "[[w:direct-administered municipalities of China|direct-administered municipality]]", ["direct-controlled municipality"] = "w", ["distributary"] = true, ["district"] = true, ["district capital"] = "[[district]] [[capital]]", ["district headquarters"] = "[[district]] [[headquarters]]", ["district municipality"] = "w", ["division"] = true, ["dormant volcano"] = true, ["duchy"] = true, ["emirate"] = true, ["empire"] = true, ["enclave"] = true, ["exclave"] = true, ["external territory"] = "[[external]] [[territory]]", ["federal city"] = "w", ["federal subject"] = "w", ["federal territory"] = "w", ["First Nations reserve"] = "[[First Nations]] [[w:Indian reserve|reserve]]", -- Canada ["fjord"] = true, ["former autonomous territory"] = "former [[w:autonomous territory|autonomous territory]]", ["former colony"] = "former [[colony]]", ["former maritime republic"] = "former [[maritime republic]]", ["former polity"] = "former [[polity]]", ["former separatist state"] = "former [[separatist]] [[state]]", ["frazione"] = "w", -- Italy ["French prefecture"] = "[[w:Prefectures in France|prefecture]]", ["geographical region"] = "w", ["geopolitical zone"] = true, -- Nigeria ["ghost town"] = true, ["glen"] = true, ["governorate"] = true, ["greater administrative region"] = "w", -- China (historical) ["gulf"] = true, ["hamlet"] = true, ["harbor city"] = "[[harbor]] [[city]]", ["harbour city"] = "[[harbour]] [[city]]", ["harbor town"] = "[[harbor]] [[town]]", ["harbour town"] = "[[harbour]] [[town]]", ["headland"] = true, ["headquarters"] = "w", ["heath"] = true, ["hill station"] = "w", ["hill town"] = "w", ["historical region"] = "w", ["home rule city"] = "w", ["home rule municipality"] = "w", ["housing estate"] = true, ["hromada"] = "w", -- Ukraine ["independent city"] = true, ["independent town"] = "[[independent city|independent town]]", ["Indian reservation"] = "w", -- United States ["Indian reserve"] = "w", -- Canada ["inactive volcano"] = "[[inactive]] [[volcano]]", ["inner city area"] = "[[inner city]] area", ["island country"] = "w", ["island municipality"] = "w", ["islet"] = "w", ["Israeli settlement"] = "w", ["judicial capital"] = "w", ["khanate"] = true, ["kibbutz"] = true, ["krai"] = true, ["league"] = true, ["legislative capital"] = "[[legislative]] [[capital]]", ["lieutenancy area"] = "w", ["local authority district"] = "w", ["local government area"] = "w", ["local government district"] = "w", ["local government district with borough status"] = "[[w:local government district|local government district]] with [[w:borough status|borough status]]", ["local urban district"] = "w", ["locality"] = "[[w:locality (settlement)|locality]]", ["London borough"] = "w", ["macroregion"] = true, ["marginal sea"] = true, ["market city"] = "[[market town|market city]]", ["market town"] = true, ["megacity"] = true, ["metropolitan borough"] = true, ["metropolitan city"] = true, ["metropolitan county"] = true, ["metro station"] = true, ["microdistrict"] = true, ["microstate"] = true, ["minster town"] = "[[minster]] town", -- England ["moor"] = true, ["moorland"] = true, ["mountain indigenous district"] = "[[w:district (Taiwan)|mountain indigenous district]]", -- Taiwan ["mountain indigenous township"] = "[[w:township (Taiwan)|mountain indigenous township]]", -- Taiwan ["mountain pass"] = true, ["mountain range"] = true, ["mountainous region"] = "[[mountainous]] [[region]]", ["municipal district"] = "w", ["municipality"] = true, ["municipality with city status"] = "[[municipality]] with [[w:city status|city status]]", ["national capital"] = "w", ["national park"] = true, ["new town"] = true, ["non-city capital"] = "[[capital]]", ["non-metropolitan county"] = "w", ["non-metropolitan district"] = "w", ["oblast"] = true, ["overseas collectivity"] = "w", ["overseas department"] = "w", ["overseas territory"] = "w", ["parish"] = true, ["parish municipality"] = "[[w:parish municipality (Quebec)|parish municipality]]", ["parish seat"] = true, ["pass"] = "[[mountain pass|pass]]", ["periphery"] = true, ["planned community"] = true, ["populated place"] = "[[w:populated place|locality]]", ["port"] = true, ["port city"] = true, ["port town"] = "w", ["prefecture"] = true, ["prefecture-level city"] = "w", ["protectorate"] = true, ["province"] = true, ["provincial capital"] = true, ["new area"] = "[[w:new areas|new area]]", -- China (type of economic development zone) ["raion"] = true, ["regency"] = true, ["regional capital"] = "[[regional]] [[capital]]", ["regional county municipality"] = "w", ["regional district"] = "w", ["regional municipality"] = "w", ["regional unit"] = "w", ["registration county"] = true, ["research base"] = "[[research]] [[base]]", ["residental area"] = "[[residential]] area", ["resort city"] = "w", ["resort town"] = "w", ["royal borough"] = "w", ["royal burgh"] = true, ["royal capital"] = "w", ["rural committee"] = "w", -- Hong Kong ["rural community"] = "w", ["rural municipality"] = "w", ["rural township"] = "[[w:rural township (Taiwan)|rural township]]", -- Taiwan ["satrapy"] = true, ["seaport"] = true, ["settlement"] = true, ["sheading"] = true, -- Isle of Man ["sheep station"] = true, -- Australia ["shire"] = true, ["shire county"] = "w", ["shire town"] = true, ["ski resort town"] = "[[ski resort]] town", ["spa city"] = "[[w:spa town|spa city]]", ["spa town"] = "w", ["special administrative region"] = "w", -- China; North Korea; Indonesia; East Timor ["special collectivity"] = "w", ["special ward"] = true, ["spit"] = true, ["state capital"] = true, ["state-level new area"] = "w", ["state park"] = true, ["statutory city"] = "w", ["statutory town"] = "w", ["strait"] = true, ["subdistrict"] = true, ["subdivision"] = true, ["submerged ghost town"] = "[[submerged]] [[ghost town]]", ["subprefecture"] = true, ["subprovince"] = true, ["subprovincial city"] = "w", ["subprovincial district"] = "w", ["sub-prefectural city"] = "w", ["subregion"] = true, ["suburb"] = true, ["subway station"] = "w", ["supercontinent"] = true, ["tehsil"] = true, ["territorial authority"] = "w", ["township"] = true, ["township municipality"] = "[[w:township municipality (Quebec)|township municipality]]", -- can't use templates in this code ["town with bystatus"] = "[[town]] with [[bystatus#Norwegian Bokmål|bystatus]]", ["traditional county"] = true, ["traditional region"] = "w", ["treaty port"] = "w", ["tribal jurisdictional area"] = "w", ["tributary"] = true, ["underground station"] = "w", ["unincorporated territory"] = "w", ["unitary authority"] = true, ["unitary district"] = "w", ["united township municipality"] = "[[w:united township municipality (Quebec)|united township municipality]]", ["unrecognised country"] = "w", ["unrecognized country"] = "w", ["urban area"] = "[[urban]] area", ["urban township"] = "w", ["urban-type settlement"] = "w", ["village municipality"] = "[[w:village municipality (Quebec)|village municipality]]", ["voivodeship"] = true, -- Poland ["volcano"] = true, ["ward"] = true, ["watercourse"] = true, ["Welsh community"] = "[[w:community (Wales)|community]]", } -- In this table, the key qualifiers should be treated the same as the value qualifiers for -- categorization purposes. This is overridden by cat_data, placetype_equivs and -- qualifier_to_placetype_equivs. export.qualifier_equivs = { ["abandoned"] = "historical", ["ancient"] = "historical", ["former"] = "historical", ["extinct"] = "historical", ["historic"] = "historical", -- This needs to be here. If we take it out, 'historic province' won't properly -- map to 'historical political subdivision'. ["historical"] = "historical", ["medieval"] = "historical", ["mediaeval"] = "historical", ["traditional"] = "historical", } -- In this table, any placetypes containing these qualifiers that do not occur in placetype_equivs -- or cat_data should be mapped to the specified placetypes for categorization purposes. Entries here -- are overridden by cat_data and placetype_equivs. export.qualifier_to_placetype_equivs = { ["fictional"] = "fictional location", ["mythological"] = "mythological location", } -- In this table, the key placetypes should be treated the same as the value placetypes for -- categorization purposes. Entries here are overridden by cat_data. -- NOTE: 'coal town', 'county town', 'ghost town', 'resort town', 'ski resort town', -- 'spa town', etc. aren't mapped to 'town' because they aren't necessarily towns. export.placetype_equivs = { ["administrative capital"] = "capital city", ["administrative center"] = "administrative centre", ["administrative headquarters"] = "administrative centre", ["administrative seat"] = "administrative centre", ["alliance"] = "confederation", ["ancient city"] = "ancient settlement", ["ancient hamlet"] = "ancient settlement", ["ancient town"] = "ancient settlement", ["ancient village"] = "ancient settlement", ["archipelago"] = "island", ["associated province"] = "province", ["autonomous territory"] = "dependent territory", ["bailiwick"] = "polity", ["barangay"] = "neighborhood", -- not completely correct, barangays are formal administrative divisions of a city ["barrio"] = "neighborhood", -- not completely correct, in some countries barrios are formal administrative divisions of a city ["bishopric"] = "polity", ["built-up area"] = "area", ["burgh"] = "borough", ["caliphate"] = "polity", ["cape"] = "peninsula", ["capital"] = "capital city", ["caplc"] = "capital city", ["caravan city"] = "city", -- should be 'former city' if we distinguish that ["cathedral city"] = "city", ["central business district"] = "neighborhood", ["ceremonial county"] = "county", ["chain of islands"] = "island", ["charter community"] = "village", ["colony"] = "dependent territory", ["commandery"] = "historical political subdivision", ["commune"] = "municipality", ["community"] = "village", ["comune"] = "municipality", ["confederacy"] = "confederation", ["contregion"] = "region", ["county-controlled city"] = "county-administered city", ["county-level city"] = "prefecture-level city", ["crown dependency"] = "dependent territory", ["Crown dependency"] = "dependent territory", ["department capital"] = "capital city", ["dependency"] = "dependent territory", ["deserted mediaeval village"] = "ancient settlement", ["deserted medieval village"] = "ancient settlement", ["direct-administered municipality"] = "municipality", ["direct-controlled municipality"] = "municipality", ["district capital"] = "capital city", ["district headquarters"] = "administrative centre", ["dormant volcano"] = "volcano", ["duchy"] = "polity", ["emirate"] = "polity", ["empire"] = "polity", ["external territory"] = "dependent territory", ["federal territory"] = "territory", ["First Nations reserve"] = "Indian reserve", ["frazione"] = "village", -- should be "hamlet" but hamlet in turn redirects to village ["geographical region"] = "region", ["glen"] = "valley", ["group of islands"] = "island", ["hamlet"] = "village", ["harbor city"] = "city", ["harbour city"] = "city", ["harbor town"] = "town", ["harbour town"] = "town", ["headquarters"] = "administrative centre", ["heath"] = "moor", ["hill station"] = "town", ["hill town"] = "town", -- We try to list all top-level polities and political subdivisions here and classify them -- accordingly. (Note that the following entries also apply to anything preceded by "former", -- "ancient", "historic", "medieval", etc., according to qualifier_equivs.) Anything we don't -- list will be categorized as if the qualifier were absent, e.g. "ancient city" will be -- categorized as a city and "former sea" as a sea. ["historical autonomous republic"] = "historical political subdivision", ["historical borough"] = "historical political subdivision", ["historical canton"] = "historical political subdivision", ["historical bailiwick"] = "historical polity", ["historical barangay"] = "historical political subdivision", ["historical bishopric"] = "historical polity", ["historical caliphate"] = "historical polity", ["historical city"] = "historical settlement", ["historical civilisation"] = "historical polity", ["historical civilization"] = "historical polity", ["historical civil parish"] = "historical political subdivision", ["historical commandery"] = "historical political subdivision", ["historical commonwealth"] = "historical polity", ["historical commune"] = "historical political subdivision", ["historical confederation"] = "historical polity", ["historical council area"] = "historical political subdivision", ["historical county"] = "historical political subdivision", ["historical county borough"] = "historical political subdivision", ["historical country"] = "historical polity", ["historical department"] = "historical political subdivision", ["historical district"] = "historical political subdivision", ["historical division"] = "historical political subdivision", ["historical duchy"] = "historical polity", ["historical emirate"] = "historical polity", ["historical empire"] = "historical polity", ["historical governorate"] = "historical political subdivision", ["historical hamlet"] = "historical settlement", ["historical khanate"] = "historical polity", ["historical kingdom"] = "historical polity", ["historical krai"] = "historical political subdivision", ["historical maritime republic"] = "historical polity", ["historical metropolitan borough"] = "historical political subdivision", ["historical municipality"] = "historical political subdivision", ["historical oblast"] = "historical political subdivision", ["historical okrug"] = "historical political subdivision", ["historical parish"] = "historical political subdivision", ["historical periphery"] = "historical political subdivision", ["historical prefecture"] = "historical political subdivision", ["historical province"] = "historical political subdivision", ["historical regency"] = "historical political subdivision", ["historical regional unit"] = "historical political subdivision", ["historical republic"] = "historical polity", ["historical satrapy"] = "historical polity", ["historical separatist state"] = "historical polity", -- The following could refer either to a state of a country (a subdivision) -- or a state = sovereign entity. The latter appears more common (e.g. in -- various "ancient states" of East Asia). ["historical state"] = "historical polity", ["historical subdistrict"] = "historical political subdivision", ["historical subdivision"] = "historical political subdivision", ["historical subprefecture"] = "historical political subdivision", ["historical town"] = "historical settlement", ["historical village"] = "historical settlement", ["historical voivodeship"] = "historical political subdivision", ["home rule city"] = "city", ["home rule municipality"] = "municipality", ["inactive volcano"] = "volcano", ["independent city"] = "city", ["independent town"] = "town", ["inner city area"] = "neighborhood", ["island country"] = "country", ["island municipality"] = "municipality", ["islet"] = "island", ["judicial capital"] = "capital city", ["khanate"] = "polity", ["kingdom"] = "polity", ["league"] = "confederation", ["legislative capital"] = "capital city", ["local authority district"] = "local government district", ["local government district with borough status"] = "local government district", ["local urban district"] = "unincorporated community", ["locality"] = "village", -- not necessarily true, but usually is the case ["macroregion"] = "region", ["market city"] = "city", ["market town"] = "town", ["mediaeval capital"] = "ancient capital", ["medieval capital"] = "ancient capital", ["mediaeval city"] = "ancient settlement", ["medieval city"] = "ancient settlement", ["mediaeval hamlet"] = "ancient settlement", ["medieval hamlet"] = "ancient settlement", ["mediaeval town"] = "ancient settlement", ["medieval town"] = "ancient settlement", ["mediaeval village"] = "ancient settlement", ["medieval village"] = "ancient settlement", ["megacity"] = "city", ["metropolitan county"] = "county", ["microdistrict"] = "neighborhood", ["microstate"] = "country", ["minster town"] = "town", ["moorland"] = "moor", ["mountain indigenous district"] = "district", ["mountain indigenous township"] = "township", ["mountain range"] = "mountain", ["mountainous region"] = "region", ["municipality with city status"] = "municipality", ["national capital"] = "capital city", ["national park"] = "park", ["neighbourhood"] = "neighborhood", ["new town"] = "town", ["non-metropolitan county"] = "county", ["non-metropolitan district"] = "local government district", ["overseas collectivity"] = "collectivity", ["overseas department"] = "department", ["overseas territory"] = "dependent territory", ["pass"] = "mountain pass", ["populated place"] = "village", -- not necessarily true, but usually is the case ["port city"] = "city", ["port town"] = "town", ["protectorate"] = "dependent territory", ["provincial capital"] = "capital city", ["regional capital"] = "capital city", ["regional municipality"] = "municipality", ["resort city"] = "city", ["royal burgh"] = "borough", ["royal capital"] = "capital city", ["settlement"] = "village", -- not necessarily true, but usually is the case ["sheading"] = "district", ["shire"] = "county", ["shire county"] = "county", ["shire town"] = "county seat", ["spa city"] = "city", ["spit"] = "peninsula", ["state capital"] = "capital city", ["state park"] = "park", ["statutory city"] = "city", ["statutory town"] = "town", ["stream"] = "river", ["submerged ghost town"] = "ghost town", ["sub-prefectural city"] = "subprovincial city", ["suburban area"] = "suburb", ["subway station"] = "metro station", ["supercontinent"] = "continent", ["territorial authority"] = "district", ["town with bystatus"] = "town", ["traditional county"] = "county", ["treaty port"] = "city", -- should be 'former city' if we distinguish that ["underground station"] = "metro station", ["unincorporated territory"] = "territory", ["unrecognised country"] = "unrecognized country", ["urban area"] = "neighborhood", ["urban township"] = "township", ["urban-type settlement"] = "town", ["ward"] = "neighborhood", -- not completely correct, wards are formal administrative divisions of a city } -- These contain transformations applied to certain placenames to convert them -- into displayed form. 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". export.placename_display_aliases = { ["autonomous community"] = { ["Valencian Community"] = "Valencia", }, ["city"] = { ["New York"] = "New York City", ["Washington, DC"] = "Washington, D.C.", ["Washington D.C."] = "Washington, D.C.", ["Washington DC"] = "Washington, D.C.", }, ["country"] = { ["US"] = "United States", ["U.S."] = "United States", ["USA"] = "United States", ["U.S.A."] = "United States", ["United States of America"] = "United States", ["UK"] = "United Kingdom", ["UAE"] = "United Arab Emirates", ["Macedonia"] = "North Macedonia", ["Republic of North Macedonia"] = "North Macedonia", ["Republic of Macedonia"] = "North Macedonia", ["Republic of Ireland"] = "Ireland", ["Republic of Armenia"] = "Armenia", ["Côte d'Ivoire"] = "Ivory Coast", ["Czechia"] = "Czech Republic", ["Vatican"] = "Vatican City", ["Bosnia and Hercegovina"] = "Bosnia and Herzegovina", }, ["region"] = { ["Northern Ostrobothnia"] = "North Ostrobothnia", ["Southern Ostrobothnia"] = "South Ostrobothnia", ["North Savo"] = "Northern Savonia", ["South Savo"] = "Southern Savonia", ["Päijät-Häme"] = "Päijänne Tavastia", ["Kanta-Häme"] = "Tavastia Proper", ["Åland"] = "Åland Islands", }, ["republic"] = { ["Kabardino-Balkarian Republic"] = "Kabardino-Balkar Republic", ["Tyva Republic"] = "Tuva Republic", }, ["state"] = { ["Mecklenburg-Western Pomerania"] = "Mecklenburg-Vorpommern", ["Mexico"] = "State of Mexico", }, ["territory"] = { ["U.S. Virgin Islands"] = "United States Virgin Islands", ["US Virgin Islands"] = "United States Virgin Islands", }, } -- These contain transformations applied to the displayed form of certain -- placenames to convert them into the form they will appear in categories. -- For example, either of "country/Myanmar" and "country/Burma" will be -- categorized into categories with "Burma" in them (but the displayed form -- will respect the form as input). (NOTE, the choice of names here should not -- be taken to imply any political position; it is just this way because it has -- always been this way.) export.placename_cat_aliases = { ["autonomous okrug"] = { ["Nenetsia"] = "Nenets Autonomous Okrug", ["Khantia-Mansia"] = "Khanty-Mansi Autonomous Okrug", ["Yugra"] = "Khanty-Mansi Autonomous Okrug", }, ["council area"] = { ["Glasgow"] = "City of Glasgow", ["Edinburgh"] = "City of Edinburgh", ["Aberdeen"] = "City of Aberdeen", ["Dundee"] = "City of Dundee", ["Western Isles"] = "Na h-Eileanan Siar", }, ["country"] = { -- will categorize into e.g. "Cities in Burma". ["Myanmar"] = "Burma", ["Nagorno-Karabakh"] = "Artsakh", ["People's Republic of China"] = "China", ["Republic of China"] = "Taiwan", ["Bosnia"] = "Bosnia and Herzegovina", ["Congo"] = "Democratic Republic of the Congo", ["Congo Republic"] = "Republic of the Congo", }, ["county"] = { ["Anglesey"] = "Isle of Anglesey", }, ["province"] = { ["Noord-Brabant"] = "North Brabant", ["Noord-Holland"] = "North Holland", ["Zuid-Holland"] = "South Holland", ["Fuchien"] = "Fujian", }, ["republic"] = { -- Only needs 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). Note that a couple -- of minor variants are recognized as display aliases, meaning that they -- will be canonicalized for display as well as categorization. ["Bashkiria"] = "Republic of Bashkortostan", ["Chechnya"] = "Chechen Republic", ["Chuvashia"] = "Chuvash Republic", ["Kabardino-Balkaria"] = "Kabardino-Balkar Republic", ["Kabardino-Balkariya"] = "Kabardino-Balkar Republic", ["Karachay-Cherkessia"] = "Karachay-Cherkess Republic", ["North Ossetia"] = "Republic of North Ossetia-Alania", ["Alania"] = "Republic of North Ossetia-Alania", ["Yakutia"] = "Sakha Republic", ["Yakutiya"] = "Sakha Republic", ["Republic of Yakutia (Sakha)"] = "Sakha Republic", ["Tyva"] = "Tuva Republic", ["Udmurtia"] = "Udmurt Republic", }, } -- 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": -- 1. Listed here. -- 2. Given in [[Module:place/shared-data]] with an initial "the". All such placenames -- are added to this map by the code just below the map. -- 3. The placetype of the placename has holonym_article = "the" in its cat_data. -- 4. A regex in placename_the_re matches the placename. -- Note that "the" is added only before the first holonym in a place spec. export.placename_article = { -- This should only contain info that can't be inferred from [[Module:place/shared-data]]. ["archipelago"] = { ["Cyclades"] = "the", ["Dodecanese"] = "the", }, ["borough"] = { ["Bronx"] = "the", }, ["country"] = { ["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", }, ["valley"] = { ["San Fernando Valley"] = "the", }, } -- 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_article = "the". ["*"] = {"^Isle of ", " Islands$", " Mountains$", " Empire$", " Country$", " Region$", " District$", "^City of "}, ["bay"] = {"^Bay of "}, ["lake"] = {"^Lake of "}, ["country"] = {"^Republic of ", " Republic$"}, ["republic"] = {"^Republic of ", " Republic$"}, ["region"] = {" [Rr]egion$"}, ["river"] = {" River$"}, ["local government area"] = {"^Shire of "}, ["county"] = {"^Shire of "}, ["Indian reservation"] = {" Reservation", " Nation"}, ["tribal jurisdictional area"] = {" Reservation", " Nation"}, } -- Now extract from the shared place data all the other places that need "the" -- prefixed. for _, group in ipairs(m_shared.polities) do for key, value in pairs(group.data) do key = key:gsub(", .*$", "") -- Chop off ", England" and such from the end local base = key:match("^the (.*)$") if base then local divtype = value.divtype or group.default_divtype if not divtype then error("Group in [[Module:place/shared-data]] is missing a default_divtype key") end if type(divtype) ~= "table" then divtype = {divtype} end for _, dt in ipairs(divtype) do if not export.placename_article[dt] then export.placename_article[dt] = {} end export.placename_article[dt][base] = "the" end end end end -- If any of the following holonyms are present, the associated holonyms are automatically added -- to the end of the list of holonyms for display and categorization purposes. -- FIXME: There are none here currently and the mechanism is broken in that it doesn't properly -- check for the presence of the holonym already. Don't add any without fixing this, or we'll -- get redundantly-displayed holonyms in the common case where e.g. "Alabama, USA" is specified. -- See below under cat_implications. -- FIXME: Consider implementing a handler to automatically add implications for all political -- subdivisions listed in the groups in [[Module:place/shared-data]], with the containing polity -- as the implicand. That way, if someone writes e.g. {{place|en|village|s/Thuringia}}, it will -- automatically display as if written {{place|en|village|s/Thuringia|c/Germany}}. export.implications = { } -- 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. -- FIXME: We should implement an implication handler to add cat_implications for all political -- subdivisions listed in the groups in [[Module:place/shared-data]], with the containing polity -- as the implicand. (This should be a handler not a preprocessing step to save memory.) Before -- doing that, we should fix the implication mechanism to not add a holonym if the holonym -- already exists or a conflicting holonym exists, where "conflicting" means a different holonym -- of the same placetype as the holonym being added. Hence, if e.g. two countries have a province of -- the same name, and we have an entry for one of the provinces, we won't add that province's country -- if the other country is already specified. export.cat_implications = { ["region"] = { ["Eastern Europe"] = {"continent/Europe"}, ["Central Europe"] = {"continent/Europe"}, ["Western Europe"] = {"continent/Europe"}, ["Southern Europe"] = {"continent/Europe"}, ["Northern 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"}, ["Asia Minor"] = {"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"}, } } export.cat_implication_handlers = {} table.insert(export.cat_implication_handlers, function(placetype, holonym_placetype, holonym_placename) for _, group in ipairs(m_shared.polities) do -- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture"). local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename) if key then local value = group.data[key] if value and value.containing_polity and value.containing_polity_type then local bare_containing_polity, linked_containing_polity = m_shared.construct_bare_and_linked_version(value.containing_polity) return {value.containing_polity_type, bare_containing_polity} end end end end ) ----------- Basic utilities ----------- 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. function export.maybe_singularize(placetype) if not placetype then return nil end local retval = m_strutils.singularize(placetype) if retval == placetype then return nil end return retval end -- Look up and resolve any category aliases that need to be applied to a holonym. For example, -- "country/Republic of China" maps to "Taiwan" for use in categories like "Counties in Taiwan". -- This also removes any links. function export.resolve_cat_aliases(holonym_placetype, holonym_placename) local retval local cat_aliases = export.get_equiv_placetype_prop(holonym_placetype, function(pt) return export.placename_cat_aliases[pt] end) holonym_placename = export.remove_links_and_html(holonym_placename) if cat_aliases then retval = cat_aliases[holonym_placename] end return retval or holonym_placename end -- Given a placetype, split the placetype into one or more potential "splits", each consisting of -- a three-element list {PREV_QUALIFIERS, THIS_QUALIFIER, BARE_PLACETYPE}, i.e. -- (a) 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); -- (b) a single recognized qualifier, normally canonicalized; -- (c) the "bare placetype" on the right. -- Splitting between the qualifier in (b) and the bare placetype in (c) happens at each space -- character, proceeding from left to right, and stops if a qualifier isn't recognized. (No checks -- are made as to whether to bare placetype is recognized, and it is not canonicalized in any way.) -- 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, "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, "small", "former haunted community"}, -- {"small", "former", "haunted community"}, -- } -- because "small" and "former" but not "haunted" are recognized as qualifiers. function export.split_qualifiers_from_placetype(placetype, no_canon_qualifiers) local splits = {} local prev_qualifier = nil while true do local qualifier, bare_placetype = placetype:match("^(.-) (.*)$") if qualifier then local canon = export.placetype_qualifiers[qualifier] if not canon then break end local new_qualifier = qualifier if not no_canon_qualifiers and canon ~= true then new_qualifier = canon end table.insert(splits, {prev_qualifier, new_qualifier, bare_placetype}) prev_qualifier = prev_qualifier and prev_qualifier .. " " .. new_qualifier or new_qualifier placetype = bare_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.) The placetype passed in always -- forms the first entry. function export.get_placetype_equivs(placetype) local equivs = {} -- Look up the equivalent placetype for `placetype` in `placetype_equivs`. If `placetype` is plural, also look up the -- equivalent for the singularized version. Return any equivalent placetype(s) found. local function lookup_placetype_equiv(placetype) local retval = {} -- Check for a mapping in placetype_equivs; add if present. if export.placetype_equivs[placetype] then table.insert(retval, export.placetype_equivs[placetype]) end local sg_placetype = export.maybe_singularize(placetype) -- Check for a mapping in placetype_equivs for the singularized equivalent. if sg_placetype and export.placetype_equivs[sg_placetype] then table.insert(retval, export.placetype_equivs[sg_placetype]) end return retval end -- Insert `placetype` into `equivs`, along with any equivalent placetype listed in `placetype_equivs`. `qualifier` is -- the preceding qualifier to insert into `equivs` along with the placetype (see comment at top of function). We also -- check to see if `placetype` is plural, and if so, insert the singularized version along with its equivalent (if any) -- in `placetype_equivs`. local function do_placetype(qualifier, placetype) -- FIXME! The qualifier (first arg) is inserted into the table, but isn't -- currently used anywhere. local function insert(pt) table.insert(equivs, {qualifier=qualifier, placetype=pt}) end -- First do the placetype itself. insert(placetype) -- Then check for a singularized equivalent. local sg_placetype = export.maybe_singularize(placetype) if sg_placetype then insert(sg_placetype) end -- Then check for a mapping in placetype_equivs, and a mapping for the singularized equivalent; add if present. local placetype_equiv_list = lookup_placetype_equiv(placetype) for _, placetype_equiv in ipairs(placetype_equiv_list) do insert(placetype_equiv) end end do_placetype(nil, placetype) -- Then successively split off recognized qualifiers and loop over successively greater sets of -- qualifiers from the left. local splits = export.split_qualifiers_from_placetype(placetype) for _, split in ipairs(splits) do local prev_qualifier, this_qualifier, bare_placetype = split[1], split[2], split[3] -- First see if the rightmost split-off qualifier is in qualifier_equivs (e.g. 'former' -> 'historical'). -- If so, create a placetype from the qualifier mapping + the following bare_placetype; then, add -- that placetype, and any mapping for the placetype in placetype_equivs. local equiv_qualifier = export.qualifier_equivs[this_qualifier] if equiv_qualifier then do_placetype(prev_qualifier, equiv_qualifier .. " " .. bare_placetype) end -- Also see if the remaining placetype to the right of the rightmost split-off qualifier has a placetype equiv, and -- if so, create placetypes from the qualifier + placetype equiv and qualifier equiv + placetype equiv, inserting them -- along with any equivalents. This way, if we are given the placetype "former alliance", and we have a mapping -- 'former' -> 'historical' in qualifier_equivs and a mapping 'alliance' -> 'confederation' in placetype_equivs, we -- check for placetypes 'former confederation' and (most importantly) 'historical confederation' and their equivalents -- (if any) in placetype_equivs. This allows the user to specify placetypes using any combination of -- "former/ancient/historical/etc." and "league/alliance/confederacy/confederation" and it will correctly map to the -- placetype 'historical confederation' and in turn to the category [[:Category:LANG:Historical polities]]. Similarly, -- any combination of "former/ancient/historical/etc." and "protectorate/autonomous territory/dependent territory" -- will correctly map to placetype 'historical dependent territory' and in turn to the category -- [[:Category:LANG:Historical political subdivisions]]. local bare_placetype_equiv_list = lookup_placetype_equiv(bare_placetype) for _, bare_placetype_equiv in ipairs(bare_placetype_equiv_list) do do_placetype(prev_qualifier, this_qualifier .. " " .. bare_placetype_equiv) if equiv_qualifier then do_placetype(prev_qualifier, equiv_qualifier .. " " .. bare_placetype_equiv) 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 export.qualifier_to_placetype_equivs[this_qualifier] then table.insert(equivs, {qualifier=prev_qualifier, placetype=export.qualifier_to_placetype_equivs[this_qualifier]}) end -- Finally, join the rightmost split-off qualifier to the previously split-off qualifiers to form a -- combined qualifier, and add it along with bare_placetype and any mapping in placetype_equivs for -- bare_placetype. local qualifier = prev_qualifier and prev_qualifier .. " " .. this_qualifier or this_qualifier do_placetype(qualifier, bare_placetype) end return equivs end function export.get_equiv_placetype_prop(placetype, fun) if not placetype then return fun(nil), nil end local equivs = export.get_placetype_equivs(placetype) for _, equiv in ipairs(equivs) do local retval = fun(equiv.placetype) if retval then return retval, equiv end end return nil, nil end ------------------------------------------------------ local function city_type_cat_handler(placetype, holonym_placetype, holonym_placename, allow_if_holonym_is_city, no_containing_polity, extracats) local plural_placetype = m_strutils.pluralize(placetype) if m_shared.generic_place_types[plural_placetype] then for _, group in ipairs(m_shared.polities) do -- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture"). local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename) if key then local value = group.data[key] if value then -- Use the group's value_transformer to ensure that 'is_city', 'containing_polity' -- and 'british_spelling' keys are present if they should be. value = group.value_transformer(group, key, value) if not value.is_former_place and (not value.is_city or allow_if_holonym_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_containing_polity_cat is set.) if plural_placetype == "neighborhoods" and value.british_spelling then plural_placetype = "neighbourhoods" end local retcats = {ucfirst(plural_placetype) .. " in " .. key} if value.containing_polity and not value.no_containing_polity_cat and not no_containing_polity then table.insert(retcats, ucfirst(plural_placetype) .. " in " .. value.containing_polity) end if extracats then for _, cat in ipairs(extracats) do table.insert(retcats, cat) end end return { ["itself"] = retcats } end end end end end end local function capital_city_cat_handler(holonym_placetype, holonym_placename, place_spec, non_city) -- 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'. if holonym_placetype then -- Simulate the loop in find_cat_specs() over holonyms so we get the proper -- 'Cities in ...' categories as well as the capital category/categories we add below. local c = 3 local inner_data if not non_city then while place_spec[c] do local h_placetype, h_placename = place_spec[c][1], place_spec[c][2] h_placename = export.resolve_cat_aliases(h_placetype, h_placename) inner_data = export.get_equiv_placetype_prop(h_placetype, function(pt) return city_type_cat_handler("city", pt, h_placename) end) if inner_data then break end c = c + 1 end end if not inner_data then inner_data = { ["itself"] = {} } 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/shared-data]], 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 = m_shared.placetype_to_capital_cat[holonym_placetype] if not capital_cat then capital_cat = m_shared.placetype_to_capital_cat[holonym_placetype:gsub("^.* ", "")] end if capital_cat then capital_cat = ucfirst(capital_cat) local inserted_specific_variant_cat = false for _, group in ipairs(m_shared.polities) do -- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture"). local key = group.place_cat_handler(group, "capital city", holonym_placetype, holonym_placename) if key then local value = group.data[key] if value then -- Use the group's value_transformer to ensure that 'containing_polity' -- is present if it should be. value = group.value_transformer(group, key, value) if value.containing_polity and not value.no_containing_polity_cat then table.insert(inner_data["itself"], capital_cat .. " of " .. value.containing_polity) inserted_specific_variant_cat = true break end end end end if not inserted_specific_variant_cat then table.insert(inner_data["itself"], capital_cat) end else -- We didn't recognize the holonym placetype; just put in 'Capital cities'. table.insert(inner_data["itself"], "Capital cities") end return inner_data end end -- This is used to add pages to base holonym categories like 'en:Places in Merseyside, England' -- (and 'en:Places in England') for any pages that have 'co/Merseyside' as their holonym. -- It also handles cities (e.g. 'en:Places in Boston', along with 'en:Places in Massachusetts, USA' -- and 'en:Places in the United States') for any pages that have 'city/Boston' as their holonym. local function generic_cat_handler(holonym_placetype, holonym_placename, place_spec) for _, group in ipairs(m_shared.polities) do -- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture"). local key = group.place_cat_handler(group, "*", holonym_placetype, holonym_placename) if key then local value = group.data[key] if value then -- Use the group's value_transformer to ensure that 'containing_polity' and 'no_containing_polity_cat' -- keys are present if they should be. value = group.value_transformer(group, key, value) -- Categorize both in key, and in the larger polity that the key is part of, -- e.g. [[Hirakata]] goes in both "Places in Osaka Prefecture" and "Places in Japan". local retcats = {"Places in " .. key} if value.containing_polity and not value.no_containing_polity_cat then table.insert(retcats, "Places in " .. value.containing_polity) end return { ["itself"] = retcats } end end end -- Check for cities mentioned as holonyms. if holonym_placetype == "city" then for _, city_group in ipairs(m_shared.cities) do local value = city_group.data[holonym_placename] if value and value.alias_of then local new_value = city_group.data[value.alias_of] if not new_value then error("City '" .. holonym_placename .. "' has an entry with non-existent alias_of='" .. value.alias_of .. "'") end holonym_placename = value.alias_of value = new_value end if value then -- Check if any of the city's containing polities are explicitly mentioned. If not, make sure -- that no other polities of the same sort are mentioned. local containing_polities = m_shared.get_city_containing_polities(city_group, holonym_placename, value) local containing_polities_match = false local containing_polities_mismatch = false for _, polity in ipairs(containing_polities) do local bare_polity, linked_polity = m_shared.construct_bare_and_linked_version(polity[1]) local divtype = polity.divtype or city_group.default_divtype local function holonym_matches_polity(placetype) if not place_spec[placetype] then return false end for _, holonym in ipairs(place_spec[placetype]) do if holonym == bare_polity then return true end end return false end containing_polities_match = export.get_equiv_placetype_prop(divtype, holonym_matches_polity) if containing_polities_match then break end containing_polities_mismatch = export.get_equiv_placetype_prop(divtype, function(pt) return not not place_spec[pt] end) if containing_polities_mismatch then break end end -- No mismatching containing polities, so add categories for the city and -- its containing polities. if not containing_polities_mismatch then local retcats = {"Places in " .. holonym_placename} for _, polity in ipairs(containing_polities) do local divtype = polity.divtype or city_group.default_divtype local drop_dead_now = false -- Find the group and key corresponding to the polity. for _, polity_group in ipairs(m_shared.polities) do local key = polity[1] if polity_group.placename_to_key then key = polity_group.placename_to_key(key) end local value = polity_group.data[key] if value then value = polity_group.value_transformer(polity_group, key, value) local key_divtype = value.divtype or polity_group.default_divtype if key_divtype == divtype or type(key_divtype) == "table" and key_divtype[1] == divtype then table.insert(retcats, "Places in " .. key) if value.no_containing_polity_cat then -- Stop adding containing polities if no_containing_polity_cat -- is found. (Used for 'United Kingdom'.) drop_dead_now = true end break end end end if drop_dead_now then break end end return { ["itself"] = retcats } end end end end end -- Inner data returned by cat handler for districts, neighborhoods, etc. local function district_inner_data(value, itself_dest) local retval = { ["city"] = value, ["town"] = value, ["township"] = value, ["municipality"] = value, ["borough"] = value, ["London borough"] = value, ["census-designated place"] = value, ["village"] = value, } if itself_dest then retval["itself"] = itself_dest end return retval end -- Cat handler for districts and areas. Districts are tricky because they can -- either be political subdivisions or city neighborhoods. We handle this as follows: -- (1) For countries etc. where they can be political subdivisions, an entry under -- "district" will be inserted for the country with something similar to the following: -- -- { -- ["itself"] = {"Districts of Foo"}, -- ["city"] = {"Neighborhoods in Foo"}, -- ["town"] = {"Neighborhoods in Foo"}, -- ["borough"] = {"Neighborhoods in Foo"}, -- ... -- } -- -- This way, a district in a city will categorize under "Neighborhoods in Foo" -- while some other district will categorize under "Districts of Foo". -- (2) For the remaining countries, we have a cat_handler that returns the following -- for all known countries and primary subdivisions: -- -- { -- ["city"] = {"Neighborhoods in Foo"}, -- ["town"] = {"Neighborhoods in Foo"}, -- ["borough"] = {"Neighborhoods in Foo"}, -- ... -- } -- -- This way, a district under a city will still categorize under "Neighborhoods in Foo" -- while other districts won't categorize. local function district_cat_handler(placetype, holonym_placetype, holonym_placename) for _, group in ipairs(m_shared.polities) do -- Find the appropriate key format for the holonym (e.g. "pref/Osaka" -> "Osaka Prefecture"). local key = group.place_cat_handler(group, placetype, holonym_placetype, holonym_placename) if key then local value = group.data[key] if value then value = group.value_transformer(group, key, value) if value.british_spelling then return district_inner_data({"Neighbourhoods in " .. key}) else return district_inner_data({"Neighborhoods in " .. key}) end end end end end local function chinese_subcity_cat_handler(holonym_placetype, holonym_placename, place_spec) local spec = m_shared.chinese_provinces_and_autonomous_regions[holonym_placename] if spec and holonym_placetype == (spec.divtype or "province") then return { ["itself"] = {"Cities in " .. holonym_placename} } end end function export.check_already_seen_string(holonym_placename, already_seen_strings) local canon_placename = lc(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 lc(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) if export.check_already_seen_string(holonym_placename, already_seen_strings or lc(suffix)) then return holonym_placename end if holonym_placename:find("%[%[") then return holonym_placename .. " " .. suffix end return "[[" .. holonym_placename .. "]] " .. suffix end -- Display handler for counties. Irish counties are displayed as e.g. "County [[Cork]]". -- Others are displayed as-is. local function county_display_handler(holonym_placetype, holonym_placename) local unlinked_placename = m_links.remove_links(holonym_placename) if m_shared.irish_counties["County " .. unlinked_placename .. ", Ireland"] or m_shared.northern_irish_counties["County " .. unlinked_placename .. ", Northern Ireland"] then return prefix_display_handler("County", holonym_placename) end return holonym_placename 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_shared.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 -- 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_shared.japanese_prefectures[unlinked_placename .. " Prefecture"] and "Prefecture" or "prefecture" return suffix_display_handler(suffix, holonym_placename) end export.cat_data = { ["administrative village"] = { preposition = "of", ["default"] = { ["municipality"] = {true}, }, }, ["administrative centre"] = { article = "the", preposition = "of", }, ["airport"] = { ["default"] = { ["itself"] = {true}, }, }, ["ancient capital"] = { article = "the", preposition = "of", ["default"] = { ["itself"] = {"Ancient settlements", "Historical capitals"}, }, }, ["ancient settlement"] = { ["default"] = { ["itself"] = {"Ancient settlements"}, }, }, ["area"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) return district_cat_handler("area", holonym_placetype, holonym_placename) end, }, ["atoll"] = { ["default"] = { ["itself"] = {true}, }, }, ["autonomous city"] = { preposition = "of", fallback = "city", }, ["autonomous community"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["autonomous oblast"] = { preposition = "of", affix_type = "Suf", no_affix_strings = "oblast", }, ["autonomous okrug"] = { preposition = "of", affix_type = "Suf", no_affix_strings = "okrug", }, ["autonomous region"] = { preposition = "of", ["country/Portugal"] = { ["itself"] = {"Districts and autonomous regions of +++"}, }, ["country/China"] = { ["country"] = {true}, }, }, ["autonomous republic"] = { preposition = "of", ["country/Soviet Union"] = { ["country"] = {true}, }, }, ["bay"] = { preposition = "of", ["default"] = { ["itself"] = {true}, }, }, ["beach"] = { ["default"] = { ["itself"] = {true}, }, }, ["borough"] = { preposition = "of", display_handler = borough_display_handler, cat_handler = function(holonym_placetype, holonym_placename, place_spec) if holonym_placetype == "county" then local cat_form = holonym_placename .. ", England" if not m_shared.english_counties[cat_form] then cat_form = "the " .. cat_form if not m_shared.english_counties[cat_form] then cat_form = nil end end if cat_form then return { ["itself"] = {"Districts of " .. cat_form, "Districts of England"} } end end if (holonym_placetype == "country" or holonym_placetype == "constituent country") and holonym_placename == "England" then return { ["itself"] = {"Districts of +++"}, } end end, ["state/Alaska"] = { ["itself"] = {"Boroughs of +++, USA"}, }, ["city/New York City"] = { ["itself"] = {"Boroughs in +++"}, }, ["state/Pennsylvania"] = { ["itself"] = {"Boroughs in +++, USA"}, }, ["state/New Jersey"] = { ["itself"] = {"Boroughs in +++, USA"}, }, }, ["borough seat"] = { article = "the", preposition = "of", ["state/Alaska"] = { ["itself"] = {"Borough seats of +++, USA"}, }, }, ["branch"] = { preposition = "of", fallback = "river", }, ["canton"] = { preposition = "of", affix_type = "suf", ["default"] = { ["country"] = {true}, }, }, ["capital city"] = { article = "the", preposition = "of", cat_handler = capital_city_cat_handler, ["default"] = { ["itself"] = {true}, }, }, ["census area"] = { affix_type = "Suf", }, ["census-designated place"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) if holonym_placetype == "state" then return city_type_cat_handler("census-designated place", holonym_placetype, holonym_placename) end end, ["country/United States"] = { ["itself"] = {true}, }, }, ["city"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("city", holonym_placetype, holonym_placename) end, ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, }, ["city-state"] = { ["default"] = { ["continent"] = {"City-states", "Cities", "Countries", "Countries in +++", "National capitals"}, ["itself"] = {"City-states", "Cities", "Countries", "National capitals"}, }, }, ["civil parish"] = { preposition = "of", affix_type = "suf", ["constituent country/England"] = { ["itself"] = {"Civil parishes of +++"}, }, }, ["collectivity"] = { preposition = "of", ["default"] = { ["itself"] = {"Polities"}, ["country"] = {true}, }, }, ["commonwealth"] = { preposition = "of", }, ["commune"] = { preposition = "of", ["country/Chile"] = { ["province"] = {"Communes of +++, Chile", "Communes of Chile"}, ["country"] = {true}, }, }, ["community development block"] = { affix_type = "suf", no_affix_strings = "block", }, ["constituent country"] = { preposition = "of", fallback = "country", }, ["continent"] = { ["default"] = { ["itself"] = {true}, }, }, ["council area"] = { preposition = "of", affix_type = "suf", ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, }, ["country"] = { ["default"] = { ["continent"] = {true, "Countries"}, ["itself"] = {true}, }, }, ["county"] = { preposition = "of", -- UNITED STATES cat_handler = function(holonym_placetype, holonym_placename, place_spec) local spec = m_shared.us_states[holonym_placename .. ", USA"] if spec and holonym_placetype == "state" and not spec.county_type then return { ["itself"] = {"Counties of " .. holonym_placename .. ", USA"} } end end, display_handler = county_display_handler, ["country/Holy Roman Empire"] = { }, ["constituent country/Northern Ireland"] = { ["itself"] = {"Traditional counties of +++"}, }, ["constituent country/Scotland"] = { ["itself"] = {"Traditional counties of +++"}, }, ["default"] = { ["itself"] = {"Polities"}, ["country"] = {true}, }, }, ["county-administered city"] = { ["default"] = { ["country"] = {"Cities in +++"}, }, }, ["county borough"] = { preposition = "of", affix_type = "suf", fallback = "borough", }, ["county seat"] = { article = "the", preposition = "of", -- UNITED STATES cat_handler = function(holonym_placetype, holonym_placename, place_spec) local spec = m_shared.us_states[holonym_placename .. ", USA"] if spec and holonym_placetype == "state" and not spec.county_type then return { ["itself"] = {"County seats of " .. holonym_placename .. ", USA"} } end end, }, ["county town"] = { article = "the", preposition = "of", fallback = "town", }, ["department"] = { preposition = "of", affix_type = "suf", holonym_article = "the", ["default"] = { ["country"] = {true}, }, }, ["dependent territory"] = { preposition = "of", ["default"] = { ["itself"] = {"Dependent territories"}, ["country"] = {"Dependent territories of +++"}, }, }, ["desert"] = { ["default"] = { ["itself"] = {true}, }, }, ["distributary"] = { preposition = "of", fallback = "river", }, ["district"] = { preposition = "of", affix_type = "suf", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return district_cat_handler("district", holonym_placetype, holonym_placename) end, ["country/Portugal"] = { ["itself"] = {"Districts and autonomous regions of +++"}, }, -- No default. Countries for which districts are political subdivisions will get entries. }, ["district municipality"] = { preposition = "of", affix_type = "suf", no_affix_strings = {"district", "municipality"}, fallback = "municipality", }, ["division"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["enclave"] = { preposition = "of", }, ["exclave"] = { preposition = "of", }, ["federal city"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["federal subject"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["fictional location"] = { ["default"] = { ["itself"] = {true}, }, }, ["forest"] = { ["default"] = { ["itself"] = {true}, }, }, ["French prefecture"] = { article = "the", preposition = "of", ["country/France"] = { ["itself"] = {"Prefectures of +++", "Departmental capitals"}, }, }, ["geopolitical zone"] = { -- Nigeria preposition = "of", }, ["ghost town"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) local function check_for_recognized(divlist, default_divtype, placename_to_key) local key = placename_to_key and placename_to_key(holonym_placename) or holonym_placename local spec = divlist[key] if not spec then key = "the " .. key spec = divlist[key] end if spec and holonym_placetype == (spec.divtype or default_divtype) then return { ["itself"] = {"Ghost towns in " .. key} } end end return ( check_for_recognized(m_shared.us_states, "state", function(placename) return placename .. ", USA" end) or check_for_recognized(m_shared.canadian_provinces_and_territories, "province") or check_for_recognized(m_shared.australian_states_and_territories, "state") ) end, ["default"] = { ["country"] = {true}, ["itself"] = {true}, }, }, ["governorate"] = { preposition = "of", affix_type = "suf", }, ["greater administrative region"] = { -- China (historical subdivision) preposition = "of", }, ["gulf"] = { preposition = "of", holonym_article = "the", ["default"] = { ["itself"] = {true}, }, }, ["headland"] = { ["default"] = { ["itself"] = {true}, }, }, ["hill"] = { ["default"] = { ["itself"] = {true}, }, }, ["historical capital"] = { article = "the", preposition = "of", ["default"] = { ["itself"] = {"Historical settlements", "Historical capitals"}, }, }, ["historical county"] = { preposition = "of", ["constituent country/Northern Ireland"] = { ["itself"] = {"Traditional counties of +++"}, }, ["constituent country/Scotland"] = { ["itself"] = {"Traditional counties of +++"}, }, ["default"] = { ["itself"] = {"Historical political subdivisions"}, }, }, ["historical dependent territory"] = { preposition = "of", ["default"] = { ["itself"] = {true}, }, }, ["historical polity"] = { ["default"] = { ["itself"] = {true}, }, }, ["historical political subdivision"] = { preposition = "of", ["default"] = { ["itself"] = {true}, }, }, ["historical region"] = { ["default"] = { ["itself"] = {"Historical and traditional regions"}, }, }, ["historical settlement"] = { ["default"] = { ["itself"] = {"Historical settlements"}, }, }, ["hromada"] = { preposition = "of", affix_type = "Suf", }, ["island"] = { ["default"] = { ["itself"] = {true}, }, }, ["kibbutz"] = { plural = "kibbutzim", ["default"] = { ["itself"] = {true}, }, }, ["krai"] = { preposition = "of", affix_type = "Suf", ["default"] = { ["country"] = {true}, }, }, ["lake"] = { ["default"] = { ["itself"] = {true}, }, }, ["largest city"] = { article = "the", fallback = "city", }, ["local government district"] = { preposition = "of", affix_type = "suf", affix = "district", cat_handler = function(holonym_placetype, holonym_placename, place_spec) if holonym_placetype == "county" then local cat_form = holonym_placename .. ", England" if not m_shared.english_counties[cat_form] then cat_form = "the " .. cat_form if not m_shared.english_counties[cat_form] then cat_form = nil end end if cat_form then return { ["itself"] = {"Districts of " .. cat_form, "Districts of England"} } end end if (holonym_placetype == "country" or holonym_placetype == "constituent country") and holonym_placename == "England" then return { ["itself"] = {"Districts of +++"}, } end end, }, ["London borough"] = { preposition = "of", affix_type = "pref", affix = "borough", fallback = "local government district", }, ["marginal sea"] = { preposition = "of", ["default"] = { ["itself"] = {"Seas"}, }, }, ["metropolitan borough"] = { preposition = "of", affix_type = "Pref", no_affix_strings = {"borough", "city"}, fallback = "local government district", }, ["metropolitan city"] = { preposition = "of", affix_type = "Pref", no_affix_strings = {"metropolitan", "city"}, fallback = "city", ["country/Italy"] = { ["itself"] = {"Metropolitan cities of Italy"}, }, }, ["moor"] = { ["default"] = { ["itself"] = {true}, }, }, ["mountain"] = { ["default"] = { ["itself"] = {true}, }, }, ["mountain pass"] = { ["default"] = { ["itself"] = {true}, }, }, ["municipal district"] = { preposition = "of", affix_type = "Pref", no_affix_strings = "district", fallback = "municipality", }, ["municipality"] = { preposition = "of", ["country/Austria"] = { ["state"] = {true, "Municipalities of Austria"}, ["country"] = {true}, }, ["country/Brazil"] = { ["state"] = {"Municipalities of +++, Brazil"}, ["country"] = {true}, }, ["country/Finland"] = { ["region"] = {"Municipalities of +++, Finland", "Municipalities of Finland"}, ["country"] = {true}, }, ["country/Netherlands"] = { ["province"] = {"Municipalities of +++, Netherlands", "Municipalities of the Netherlands"}, ["country"] = {true}, }, ["country/Philippines"] = { ["province"] = {"Municipalities of +++, Philippines", "Municipalities of the Philippines"}, ["country"] = {true}, }, ["default"] = { ["country"] = {true}, }, }, ["mythological location"] = { ["default"] = { ["itself"] = {true}, }, }, ["neighborhood"] = { preposition = "of", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("neighborhood", holonym_placetype, holonym_placename, "allow if holonym is city", "no containing polity") end, }, ["new area"] = { -- China (type of economic development zone) preposition = "in", }, ["non-city capital"] = { article = "the", preposition = "of", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return capital_city_cat_handler(holonym_placetype, holonym_placename, place_spec, "non-city") end, ["default"] = { ["itself"] = {"Capital cities"}, }, }, ["oblast"] = { preposition = "of", affix_type = "Suf", }, ["ocean"] = { holonym_article = "the", ["default"] = { ["itself"] = {true}, }, }, ["okrug"] = { preposition = "of", affix_type = "Suf", }, ["parish"] = { preposition = "of", affix_type = "suf", ["state/Louisiana"] = { ["itself"] = {"Parishes of +++, USA"}, }, }, ["parish municipality"] = { preposition = "of", fallback = "municipality", ["province/Quebec"] = { ["itself"] = {"Parishes of +++", "Municipalities of Canada"}, }, }, ["parish seat"] = { article = "the", preposition = "of", ["state/Louisiana"] = { ["itself"] = {"Parish seats of +++, USA"}, }, }, ["park"] = { ["default"] = { ["itself"] = {true}, }, }, ["peninsula"] = { ["default"] = { ["itself"] = {true}, }, }, ["periphery"] = { preposition = "of", ["country/Greece"] = { ["itself"] = {"Regions of +++"}, }, }, ["planned community"] = { -- Include this empty so we don't categorize 'planned community' into -- villages, as 'community' does. }, ["polity"] = { ["default"] = { ["itself"] = {true}, }, }, ["prefecture"] = { preposition = "of", display_handler = prefecture_display_handler, ["default"] = { ["country"] = {true}, }, }, ["prefecture-level city"] = { -- China cat_handler = chinese_subcity_cat_handler, ["default"] = { ["country"] = {"Cities in +++"}, }, }, ["province"] = { preposition = "of", ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, }, ["raion"] = { preposition = "of", affix_type = "Suf", }, ["range"] = { holonym_article = "the", ["default"] = { ["itself"] = {true}, ["continent"] = {true}, }, }, ["regency"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["region"] = { preposition = "of", ["country/Armenia"] = { ["country"] = {true}, }, ["country/Brazil"] = { ["country"] = {true}, }, ["constituent country/England"] = { ["itself"] = {"Counties and regions of +++"}, }, ["country/Finland"] = { ["country"] = {true}, }, ["country/France"] = { ["country"] = {true}, }, ["country/Georgia"] = { ["country"] = {true}, }, ["country/Greece"] = { ["country"] = {true}, }, ["country/Italy"] = { ["country"] = {true}, }, ["country/Latvia"] = { ["country"] = {true}, }, ["country/Peru"] = { ["country"] = {true}, }, ["country/Portugal"] = { ["country"] = {true}, }, ["country/Romania"] = { ["country"] = {true}, }, }, ["regional district"] = { preposition = "of", affix_type = "Pref", no_affix_strings = "district", fallback = "district", ["province/British Columbia"] = { ["itself"] = {"Regional districts of +++"}, }, }, ["regional county municipality"] = { preposition = "of", affix_type = "Suf", no_affix_strings = {"municipality", "county"}, fallback = "municipality", }, ["regional municipality"] = { preposition = "of", affix_type = "Pref", no_affix_strings = "municipality", fallback = "municipality", }, ["regional unit"] = { preposition = "of", }, ["republic"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["river"] = { holonym_article = "the", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("river", holonym_placetype, holonym_placename) end, ["default"] = { ["itself"] = {true}, ["continent"] = {true}, }, }, ["royal borough"] = { preposition = "of", affix_type = "Pref", no_affix_strings = {"royal", "borough"}, fallback = "local government district", }, ["rural committee"] = { affix_type = "Suf", }, ["rural municipality"] = { preposition = "of", affix_type = "Pref", no_affix_strings = "municipality", fallback = "municipality", }, ["satrapy"] = { preposition = "of", }, ["sea"] = { holonym_article = "the", ["default"] = { ["itself"] = {true}, }, }, ["special administrative region"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["star"] = { ["default"] = { ["itself"] = {true}, }, }, ["state"] = { preposition = "of", ["default"] = { ["country"] = {true}, }, }, ["state-level new area"] = { -- China preposition = "in", }, ["strait"] = { ["default"] = { ["itself"] = {true}, }, }, ["subdistrict"] = { preposition = "of", ["country/Indonesia"] = { ["municipality"] = {true}, }, ["default"] = { ["itself"] = {true}, }, }, ["subdivision"] = { preposition = "of", affix_type = "suf", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return district_cat_handler("subdivision", holonym_placetype, holonym_placename) end, }, ["subprefecture"] = { preposition = "of", }, ["subprovince"] = { preposition = "of", }, ["subprovincial city"] = { -- China cat_handler = chinese_subcity_cat_handler, ["default"] = { ["country"] = {"Cities in +++"}, }, }, ["subprovincial district"] = { -- China preposition = "of", }, ["subregion"] = { preposition = "of", }, ["suburb"] = { preposition = "of", cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("suburb", holonym_placetype, holonym_placename, "allow if holonym is city", "no containing polity") end, }, ["tehsil"] = { affix_type = "suf", no_affix_strings = {"tehsil", "tahsil"}, }, ["territory"] = { preposition = "of", ["default"] = { ["itself"] = {"Polities"}, ["country"] = {true}, }, }, ["town"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("town", holonym_placetype, holonym_placename) end, ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, }, ["township"] = { ["default"] = { ["itself"] = {true}, }, }, ["township municipality"] = { preposition = "of", fallback = "municipality", ["province/Quebec"] = { ["itself"] = {"Townships in +++", "Townships in Canada", "Municipalities of Canada"}, }, }, ["traditional region"] = { ["default"] = { ["itself"] = {"Historical and traditional regions"}, }, }, ["tributary"] = { preposition = "of", fallback = "river", }, ["unincorporated community"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) if holonym_placetype == "state" then return city_type_cat_handler("unincorporated community", holonym_placetype, holonym_placename) end end, ["country/United States"] = { ["itself"] = {true}, }, }, ["union territory"] = { preposition = "of", article = "a", }, ["unitary authority"] = { article = "a", fallback = "local government district", }, ["unitary district"] = { article = "a", fallback = "local government district", }, ["united township municipality"] = { article = "a", fallback = "township municipality", }, ["university"] = { article = "a", ["default"] = { ["itself"] = {true}, }, }, ["unrecognized country"] = { ["default"] = { ["itself"] = {"Countries"}, }, }, ["valley"] = { ["default"] = { ["itself"] = {true}, }, }, ["village"] = { cat_handler = function(holonym_placetype, holonym_placename, place_spec) return city_type_cat_handler("village", holonym_placetype, holonym_placename) end, ["default"] = { ["itself"] = {true}, ["country"] = {true}, }, }, ["village municipality"] = { preposition = "of", ["province/Quebec"] = { ["itself"] = {"Villages in +++", "Villages in Canada", "Municipalities of Canada"}, }, }, ["voivodeship"] = { preposition = "of", holonym_article = "the", }, ["volcano"] = { plural = "volcanoes", ["default"] = { ["itself"] = {true}, }, }, ["Welsh community"] = { preposition = "of", affix_type = "suf", affix = "community", ["constituent country/Wales"] = { ["itself"] = {"Communities of +++"}, }, }, ["*"] = { cat_handler = generic_cat_handler, }, } -- Now augment the category data with political subdivisions extracted from the -- shared data. We don't need to do this if there's already an entry under "default" -- for the divtype of the containing polity. for _, group in ipairs(m_shared.polities) do for key, value in pairs(group.data) do value = group.value_transformer(group, key, value) if value.poldiv or value.miscdiv then local bare_key, linked_key = m_shared.construct_bare_and_linked_version(key) local divtype = value.divtype or group.default_divtype if type(divtype) ~= "table" then divtype = {divtype} end for pass=1,2 do local list if pass == 1 then list = value.poldiv else list = value.miscdiv end if list then for _, div in ipairs(list) do if type(div) == "string" then div = {div} end local sgdiv = m_strutils.singularize(div[1]) for _, dt in ipairs(divtype) do if not export.cat_data[sgdiv] then -- If there is an entry in placetype_equivs[], it will be ignored once -- we insert an entry in cat_data. For example, "traditional county" is -- listed as a miscdiv of Scotland and Northern Ireland but it's also -- an entry in placetype_equivs[]. Once we insert an entry here for -- "traditional county", it will override placetype_equivs[]. To get -- around that, simulate the effect of placetype_equivs[] using a -- fallback = "..." entry. if export.placetype_equivs[sgdiv] then export.cat_data[sgdiv] = { preposition = "of", fallback = export.placetype_equivs[sgdiv], } else export.cat_data[sgdiv] = { preposition = "of", ["default"] = { }, } end end if not export.cat_data[sgdiv]["default"] or not export.cat_data[sgdiv]["default"][dt] then local itself_dest = bare_key == key and {true} or {ucfirst(div[1]) .. " of " .. key} if sgdiv == "district" then -- see comment above under district_cat_handler(). local neighborhoods_in = value.british_spelling and "Neighbourhoods in " .. key or "Neighborhoods in " .. key local inner_data = district_inner_data({neighborhoods_in}, itself_dest) export.cat_data[sgdiv][dt .. "/" .. bare_key] = inner_data else export.cat_data[sgdiv][dt .. "/" .. bare_key] = { ["itself"] = itself_dest, } end end end end end end end end end return export tc9q8je9c20bjz43gxvl148ku4elid9 489344 489343 2026-09-22T18:31:59Z SM7 6218 updating... 489344 Scribunto text/plain local export = {} export.force_cat = false -- set to true for testing local m_locations = require("Module:place/locations") local m_links = require("Module:links") local m_table = require("Module:table") local m_strutils = require("Module:string utilities") local debug_track_module = "Module:debug/track" local en_utilities_module = "Module:en-utilities" local dump = mw.dumpObject local insert = table.insert local concat = table.concat local internal_error = m_locations.internal_error export.internal_error = internal_error local process_error = m_locations.process_error export.process_error = process_error local unpack = unpack or table.unpack -- Lua 5.2 compatibility local ucfirst = m_strutils.ucfirst local ulower = m_strutils.lower local rmatch = m_strutils.match local split = m_strutils.split --[==[ intro: This module contains placetype data used by [[Module:place]] and {{tl|place}}, along with a significant amount of code to work with both placetypes and locations, as well as some placename-related info (FIXME: Consider moving it to [[Module:place/locations]]). See also [[Module:place/locations]], which has definitions of all known locations. You must currently load this module using {{cd|require()}}, not using {{cd|mw.loadData()}}. In particular, it contains two fundamental and tricky functions: # `get_placetype_equivs`, which finds the equivalent placetypes to look under in order to find a given property, and in the process correctly handles placetypes with qualifiers (including qualifiers that act similar to "type-raising" operators in that they do something non-trivial to the placetype to their right) as well as form-of directives and fallbacks. # `find_matching_holonym_location`, which looks up a holonym to find a matching known location, but in the process checks holonyms to the right to make sure there isn't a clash between the user-specified containing holonyms and the containers of the known location being considered. This is done to prevent overcategorizing when either there are two known locations with the same name (e.g. Birmingham in England and Birmingham, Alabama in the US), or more generally two locations with the same name, one of which is a known location but where the other is not (e.g. we're processing non-known-location Mérida, Spain and don't want it categorized like known location Mérida, Yucatán, Mexico). Both of these functions are invoked repeatedly, and probably are invoked several times on the same inputs and as a result are candidates for memoization to speed up the operation of {{tl|place}}. ]==] ------------------------------------------------------------------------------------------ -- Basic utilities -- ------------------------------------------------------------------------------------------ --[==[ Return true if `force_cat` is set either in this module or in [[Module:place/locations]]. ]==] function export.get_force_cat() return export.force_cat or m_locations.force_cat end -- Add the page to a tracking "category". To see the pages in the "category", -- go to [[Wiktionary:Tracking/place/PAGE]] and click on "What links here". local function track(page) require(debug_track_module)("place/" .. page) return true end function export.remove_links_and_html(text) text = m_links.remove_links(text) return text:gsub("<.->", "") end --[==[ Return the singular version of a maybe-plural placetype, or nil if not plural. This correctly handles placetypes with irregular plurals such as `kibbutzim` plural of `kibbutz` by looking up in a table constructed from the `plural` values specified in `placetype_data`. If a special plural value is not found, the regular singularization algorithm in [[Module:en-utilities]] is invoked, which reverses the y -> ies change after vowels and the 'es' addition after sh/ch/x, and otherwise just subtracts a final 's' (which will incorrectly generate 'passe' for plural 'passes'; FIXME: consider changing this for words ending in '-sses'). If the generated singular is the same as the passed-in value, nil is returned. ]==] function export.maybe_singularize_placetype(placetype) if not placetype then return nil end if export.plural_placetype_to_singular[placetype] then return export.plural_placetype_to_singular[placetype] end local retval = require(en_utilities_module).singularize(placetype) if retval == placetype then return nil end return retval end -- Return the correct plural of a placetype, and (if `do_ucfirst` is given) make the first letter uppercase. We first -- look up the plural in `placetype_data`, falling back to pluralize() in [[Module:en-utilities]], which is almost -- always correct. function export.pluralize_placetype(placetype, do_ucfirst) local ptdata = export.placetype_data[placetype] if ptdata and ptdata.plural then placetype = ptdata.plural else placetype = require(en_utilities_module).pluralize(placetype) end if do_ucfirst then return ucfirst(placetype) else return placetype end end --[==[ Get the data associated with a placetype, which may be in its singular or plural form. If `from_category` is specified, we also look for category-only placetypes (generally plural) followed by `!`. Return three values: (a) the placetype under which the data can be looked up (i.e. in its singular form if the passed-in `placetype` is plural and did not match a category-only placetype followed by `!`); (b) the placetype data structure; (c) the type of `placetype` match that occurred, one of `"direct"` if the canonical placetype is the same as the passed-in `placetype` and also the same as the key under which `ptdata` was looked up, or `"direct-category"` if the `ptdata` was looked up under a key formed from the passed-in `placetype` by adding `!`, or `"plural"` if the `ptdata` was looked up under the singularized version of the plural passed-in `placetype`. ]==] function export.get_placetype_data(placetype, from_category) local ptdata = export.placetype_data[placetype] if ptdata then return placetype, ptdata, "direct" end if from_category then ptdata = export.placetype_data[placetype .. "!"] if ptdata then return placetype .. "!", ptdata, "direct-category" end end local sg_placetype = export.maybe_singularize_placetype(placetype) if sg_placetype then ptdata = export.placetype_data[sg_placetype] if ptdata then return sg_placetype, ptdata, "plural" end end return nil end --[==[ Check for special pseudo-placetypes that should be ignored for categorization purposes. ]==] function export.placetype_is_ignorable(placetype) return placetype == "and" or placetype == "or" or placetype:find("^%(") end function export.resolve_placetype_aliases(placetype) return export.placetype_aliases[placetype] or placetype end --[==[ Return a property from `placetype_data` for a given placetype. If the placetype isn't found in `placetype_data`, or the key isn't found in the placetype's entry in `placetype_data`, return nil. ]==] function export.get_placetype_prop(placetype, key) -- Usually we are called on equivalent placetypes returned from `get_placetype_equivs`, in which case placetype -- aliases have been resolved, but sometimes not, e.g. when fetching the indefinite article in -- get_placetype_article(). `resolve_placetype_aliases` is just a simple lookup and it doesn't hurt to do it twice. placetype = export.resolve_placetype_aliases(placetype) if export.placetype_data[placetype] then return export.placetype_data[placetype][key] else return nil end end --[==[ Given a placetype, split the placetype into one or more potential ''splits'', each consisting of a three-element list { {``prev_qualifiers``, ``this_qualifier``, ``reduced_placetype``}}, i.e. # the concatenation of zero or more previously-recognized qualifiers on the left, normally canonicalized (if there are zero such qualifiers, the value will be nil); # a single recognized qualifier, normally canonicalized (if there is no qualifier, the value will be nil); # the "reduced placetype" on the right. Splitting between the qualifier in (2) and the reduced placetype in (3) happens at each space character, proceeding from left to right, and stops if a qualifier isn't recognized. All placetypes are canonicalized by checking for aliases in `placetype_aliases`, but no other checks are made as to whether the reduced placetype is recognized. Canonicalization of qualifiers does not happen if `no_canon_qualifiers` is specified. For example, given the placetype `"small beachside unincorporated community"`, the return value will be { { {nil, nil, "small beachside unincorporated community"}, {nil, "small", "beachside unincorporated community"}, {"small", "[[beachfront]]", "unincorporated community"}, {"small [[beachfront]]", "[[unincorporated]]", "community"}, }} Here, `"beachside"` is canonicalized to `"[[beachfront]]"` and `"unincorporated"` is canonicalized to `"[[unincorporated]]"`, in both cases according to the entry in `placetype_qualifiers`. On the other hand, if given `"small former haunted community"`, the return value will be { { {nil, nil, "small former haunted community"}, {nil, "small", "former haunted community"}, {"small", "former", "haunted community"}, }} because `"small"` and `"former"` but not `"haunted"` are recognized as qualifiers. Finally, if given `"former adr"`, the return value will be { { {nil, nil, "former adr"}, {nil, "former", "administrative region"}, }} because `"adr"` is a recognized placetype alias for `"administrative region"`. ]==] function export.split_qualifiers_from_placetype(placetype, no_canon_qualifiers) local splits = {{nil, nil, export.resolve_placetype_aliases(placetype)}} local prev_qualifier = nil while true do local qualifier, reduced_placetype = placetype:match("^(.-) (.*)$") if qualifier then local canon = export.placetype_qualifiers[qualifier] if canon == nil then break end local new_qualifier = qualifier if type(canon) == "table" then canon = canon.link end if not no_canon_qualifiers and canon ~= false then if canon == true then new_qualifier = "[[" .. qualifier .. "]]" else new_qualifier = canon end end insert(splits, {prev_qualifier, new_qualifier, export.resolve_placetype_aliases(reduced_placetype)}) prev_qualifier = prev_qualifier and prev_qualifier .. " " .. new_qualifier or new_qualifier placetype = reduced_placetype else break end end return splits end --[==[ Given a `placetype` (which may be pluralized), return an ordered list of equivalent placetypes to look under to find the placetype's properties (such as the category or categories to be inserted). The return value is actually an ordered list of objects of the form `{qualifier=``qualifier``, placetype=``equiv_placetype``}` where ``equiv_placetype`` is a placetype whose properties to look up, derived from the passed-in placetype or from a contiguous subsequence of the words in the passed-in placetype (always including the rightmost word in the placetype, i.e. we successively chop off qualifier words from the left and use the remainder to find equivalent placetypes). ``qualifier`` is the remaining words not part of the subsequence used to find ``equiv_placetype``; or nil if all words in the passed-in placetype were used to find ``equiv_placetype``. (FIXME: This qualifier is not currently used anywhere.) Only placetypes for which there is an entry in `placetype_data` are included. The placetype passed in is always checked first, and will form the first entry if it exists in `placetype_data`. '''NOTE:''' This is a tricky function as it implements handling of (a) qualifiers, (b) fallback logic, (c) "type-raising" qualifiers such as `former`/`ancient`/etc. as well as `fictional` and `mythological`, and (d) form-of directives, which act somewhat similarly to `former`, and allows interaction between more than one of these simultaneously (e.g. official names of former places, which have their own categorization). If {{tl|place}} gets too slow, one potential speedup is to memoize the results of this function, as it appears to be getting called more than once on the same inputs. Another similar potential speedup is to memoize the results of `iterate_matching_holonym_location()`. For example, given the placetype `left tributary`, the following placetype/qualifier combinations are checked in turn: ``` {qualifier = nil, placetype="left tributary"} {qualifier = "left", placetype="tributary"} {qualifier = "left", placetype="river"} ``` and the return value will be { { {qualifier = "left", placetype="tributary"}, {qualifier = "left", placetype="river"}, }} The algorithm first enters the placetype itself into the list, then checks for `left tributary` as a recognized placetype in `placetype_data` and doesn't find it, so it doesn't enter it into the returned list (if it found it, it would add it as well as any fallbacks directly after it). It then splits off the recognized qualifier `left` to form the ''reduced placetype'' `tributary`, which is entered into the list because it is found in `placetype_data`. Then, because it has a fallback `river`, which exists in `placetype_data`, the fallback is entered next. Another example is `small rural fraziones` (where a ''frazione'' is type of subdivision of a ''comune'' or municipality, often specifically an outlying hamlet). the placetype/qualifier combinations checked are: ``` {qualifier = nil, placetype="small rural fraziones"} {qualifier = nil, placetype="small rural frazione"} {qualifier = "small", placetype="rural fraziones"} {qualifier = "small", placetype="rural frazione"} {qualifier = "small [[rural]]", placetype="fraziones"} {qualifier = "small [[rural]]", placetype="frazione"} {qualifier = "small [[rural]]", placetype="hamlet"} {qualifier = "small [[rural]]", placetype="village"} ``` The return value ends up as {qualifier = "small [[rural]]", placetype="frazione"}, {qualifier = "small [[rural]]", placetype="hamlet"}, {qualifier = "small [[rural]]", placetype="village"}, }} Here, because the result of singularizing `fraziones` returns a different value from the placetype itself, that singularized value is checked after the original plural value. Also, in the process of splitting off qualifiers, they are canonicalized if the entry in `placetype_qualifiers` says to do so; in this case, links are placed around `rural`. Finally, `frazione` has `hamlet` as its fallback, which in turn has `village` as its fallback, so both fallbacks end up being returned. `no_fallback`, if set, disables returning equivalent placetypes based on the `fallback` setting for a placetype. This is used in the first of two loops in find_placetype_cat_specs() in [[Module:place]] to prefer exact matches for placetypes such as barangays with later holonyms to matches based on a fallback such as `neighborhood` with an earlier holonym. See the comment in that function in [[Module:place]] for a more detailed explanation of why this is needed. Only the placetype itself, and any reduced placetypes created by chopping off recognized qualifiers at the beginning, are returned; but we do not return reduced placetypes if a containing placetype exists in `placetype_data`. (For example, `"overseas territory"` has a fallback `"dependent territory"`, and `"overseas"` is also a recognized qualifier. When `no_fallback` is in place, without the above proviso, we would return `"overseas territory"` followed by `"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 = "the" else art = export.get_placetype_prop(placetype, "entry_placetype_indefinite_article") if not art then art = require(en_utilities_module).get_indefinite_article(placetype) end end end if ucfirst then art = m_strutils.ucfirst(art) end return art end --[==[ Return the preposition that should be used after `placetype` when occurring as an entry placetype or in categories (e.g. `city >in< France` but `country >of< South America`). The preposition defaults to `"in"` 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 "in" 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 "country" with the list value {"Italy"} will be added to the place desc's `holonyms_by_placetype` field. If there is already a key with that place type, the new placename will be added to the end of the value's list. ]==] function export.key_holonym_into_place_desc(place_desc, holonym) if not holonym.placetype then return end -- Key in equivalent placetypes, so that e.g. `cities/San Francisco` gets keyed under `city`; but don't do -- fallbacks, as it doesn't seem correct for the "do other holonyms of the same placetype" algorithm to do holonyms -- of different types just because they have the same fallback. local equiv_placetypes = export.get_placetype_equivs(holonym.placetype, {no_fallback = true}) local unlinked_placename = holonym.unlinked_placename for _, equiv in ipairs(equiv_placetypes) do local placetype = equiv.placetype if not place_desc.holonyms_by_placetype then place_desc.holonyms_by_placetype = {} end if not place_desc.holonyms_by_placetype[placetype] then place_desc.holonyms_by_placetype[placetype] = {unlinked_placename} else insert(place_desc.holonyms_by_placetype[placetype], unlinked_placename) end end end --[=[ Construct a formatted link from the raw link spec `link` given the canonical singular placetype `sg_placetype`. If the placetype was originally plural, `orig_placetype` should contain this plural value; otherwise it should be nil. This will construct the appropriate type of link that displays as `orig_placetype` (or otherwise `sg_placetype`) but links to whatever the `link` spec specifies (which may be `sg_placetype`, a Wikipedia article, etc.). `ptdata` is the placetype data structure for the placetype, and `from_category` indicates that we are generating the description of a category (otherwise we are generating the display form of an entry placetype). ]=] local function make_placetype_link(link, sg_placetype, orig_placetype, ptdata, from_category, noerror) if not from_category and ptdata.disallow_in_entries then if noerror then return "[not meant to be specified directly, with warning: " .. ptdata.disallow_in_entries .. "]" else process_error("Placetype %s is not meant to be specified directly: " .. ptdata.disallow_in_entries, sg_placetype) end end if link == nil then internal_error("Placetype data present for placetype %s but no link= setting given", sg_placetype) elseif link == true then if orig_placetype then return ("[[%s|%s]]"):format(sg_placetype, orig_placetype) else return ("[[%s]]"):format(sg_placetype) end elseif link == false then process_error("Placetype %s is not meant to be specified directly, but is only for internal use", sg_placetype) elseif link == "w" then return ("[[w:%s|%s]]"):format(sg_placetype, orig_placetype or sg_placetype) elseif link == "separately" then if orig_placetype then local sg_words = split(sg_placetype, " ") local orig_words = split(orig_placetype, " ") if #sg_words ~= #orig_words then internal_error("Can't construct 'separately' link for plural placetype %s as original placetype %s " .. "has different number of words", orig_placetype, sg_placetype) else for i = 1, #sg_words do if sg_words[i] == orig_words[i] then sg_words[i] = ("[[%s]]"):format(sg_words[i]) else sg_words[i] = ("[[%s|%s]]"):format(sg_words[i], orig_words[i]) end end return concat(sg_words, " ") end else return (sg_placetype:gsub("([^ ]+)", "[[%1]]")) end elseif link:find("^%+") then link = link:sub(2) -- discard initial + return ("[[%s|%s]]"):format(link, orig_placetype or sg_placetype) elseif not orig_placetype then return link else return require(en_utilities_module).pluralize(link) end end --[==[ Get the display form of a placetype by looking it up in `placetype_data`. If the placetype is recognized, or is the plural of a recognized placetype, the corresponding linked display form is returned (with plural placetypes displaying as plural but linked to the singular form of the placetype). Otherwise, return nil. If we're generating the description of a category, `category_type` should be set to one of `"top-level"` (for top-level categories like [[:Category:Neighborhoods]]), `"noncity"` (for non-city categories like [[:Category:Neighborhoods in Illinois, USA]]) or `"city"` (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 == "city" 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 "city"', category_type) end if type(raw_link) == "string" then return maybe_prefix(raw_link), ptdata elseif raw_link ~= nil then return raw_link, ptdata end raw_link, fetched_full = fetch_maybe_full("category_link") if raw_link == false then return raw_link, ptdata end if is_linked_string(raw_link) then return maybe_prefix(raw_link), ptdata end if ptmatch == "plural" then raw_link, fetched_full = fetch_maybe_full("plural_link") if raw_link == false then return raw_link, ptdata end if is_linked_string(raw_link) then return maybe_prefix(raw_link), ptdata end end if raw_link == nil then raw_link, fetched_full = fetch_maybe_full("link") end if raw_link == false then return raw_link, ptdata end return maybe_prefix(make_placetype_link(raw_link, canon_placetype, placetype ~= canon_placetype and placetype or nil, ptdata, from_category, noerror)), ptdata else if ptmatch == "plural" then raw_link = ptdata.plural_link if raw_link == false then process_error("Placetype %s cannot appear plural", placetype) end if is_linked_string(raw_link) then return raw_link, ptdata end end if raw_link == nil then raw_link = ptdata.link end return make_placetype_link(raw_link, canon_placetype, placetype ~= canon_placetype and placetype or nil, ptdata, from_category, noerror), ptdata end end return nil end local function resolve_unlinked_placename_display_aliases(placetype, placename) local equiv_placetypes = export.get_placetype_equivs(placetype) for i, equiv in ipairs(equiv_placetypes) do equiv_placetypes[i] = equiv.placetype end local all_display_aliases_found = {} local all_others_found = {} for group, key, spec in m_locations.iterate_matching_location { placetypes = equiv_placetypes, placename = placename, alias_resolution = "display", } do if spec.alias_of and spec.display then insert(all_display_aliases_found, {group, key, spec, spec.display_as_full}) else insert(all_others_found, {group, key, spec}) end end if not all_display_aliases_found[1] then return placename elseif all_display_aliases_found[2] then internal_error("Found multiple matching display aliases for placename %s, placetype %s: " .. "all_display_aliases_found=%s, all_others_found=%s", placename, placetype, all_display_aliases_found, all_others_found) elseif all_others_found[1] then internal_error("Found a display alias along with other possible meanings for placename %s, placetype %s: " .. "all_display_aliases_found=%s, all_others_found=%s", placename, placetype, all_display_aliases_found, all_others_found) else local group, key, spec, as_full = unpack(all_display_aliases_found[1]) local full, elliptical = m_locations.key_to_placename(group, key) return as_full and full or elliptical end end --[==[ If `placename` of type `placetype` is a display alias, convert it to its canonical form; otherwise, return unchanged. Display aliases transform certain placenames into canonical displayed forms. For example, if any of `country/US`, `country/USA` or `country/United States of America` (or `c/US`, etc.) are given, the result will be displayed as `United States`. '''NOTE''': Display aliases change what is displayed from what the editor wrote in the Wikitext. As a result, they should (a) be non-political in nature, and (b) not involve a change where the word `the` needs to be added or removed. For example, normalizing `US` and `USA` to `United States` for display purposes is OK but normalizing `Burma` to `Myanmar` is not (instead a cat alias should be used) because the terms `Burma` and `Myanmar` have clear political connotations. Similarly, we have a display alias that maps the old name of `Macedonia` as a country (but not a region!) to `North Macedonia`, but `Republic of Macedonia` is mapped to `North Macedonia` only as a cat alias because the two terms differ in their use of `the`. (For example, if we had a display alias mapping `Republic of Macedonia` to `North Macedonia`, the call {{tl|place|en|the <<capital city>> of the <<c/Republic of Macedonia>>}} would wrongly display as `the [[capital city]] of the [[North Macedonia]]`.) Generally, display normalizations tend to involve alternative forms (e.g. abbreviations, ellipses, foreign spellings) where the normalization improves clarity and consistency. ]==] function export.resolve_placename_display_aliases(placetype, placename) -- If the placename is a link, apply the alias inside the link. -- This pattern matches both piped and unpiped links. If the link is not piped, the second capture (linktext) will -- be empty. local link, linktext = rmatch(placename, "^%[%[([^|%[%]]+)|?([^|%[%]]-)%]%]$") if link then if linktext ~= "" then local alias = resolve_unlinked_placename_display_aliases(placetype, linktext) return "[[" .. link .. "|" .. alias .. "]]" else local alias = resolve_unlinked_placename_display_aliases(placetype, link) return "[[" .. alias .. "]]" end else return resolve_unlinked_placename_display_aliases(placetype, placename) end end --[==[ Generate the "prefixed" version of a bare key, i.e. prefix it with `the` if correct for this key. ]==] function export.get_prefixed_key(key, spec) if spec.the then return "the " .. key else return key end end -- Necessary for use by [[Module:place]]. FIXME: Reorganize the modules so this isn't necessary. export.iterate_matching_location = m_locations.iterate_matching_location --[=[ Iterator that iterates over holonyms in `place_desc`. If `first_holonym_index` is given, start iterating at the specified holonym and stop either when there are no more holonyms or a holonym with modifier `:also` is found. If `first_holonym_index` is nil or omitted, iterate over all holonyms regardless. If `include_raw_text_holonyms` is specified, raw text holonyms (those not of the form `placetype/placename`) are returned as well; they can be identified by the fact that the `placetype` field in the holonym structure is nil. Two values are returned at each iteration, the holonym index and holonym structure, similar to `ipairs()`. ]=] function export.get_holonyms_to_check(place_desc, first_holonym_index, include_raw_text_holonyms) local stop_at_also = not not first_holonym_index return function(place_desc, index) while true do index = index + 1 local this_holonym = place_desc.holonyms[index] -- If we were passed in a starting holonym index, go up to but not including a holonym marked with `:also` -- (continue_cat_loop); the categorization code will then restart the loop at that holonym. That holonym -- will have `:also` marked on it, so make sure not to stop immediately if the first holonym is marked with -- `:also`. if not this_holonym or stop_at_also and index > first_holonym_index and this_holonym.continue_cat_loop then return nil end -- If not placetype, we're processing raw text, which we normally want to skip. if include_raw_text_holonyms or this_holonym.placetype then return index, this_holonym end end end, place_desc, first_holonym_index and first_holonym_index - 1 or 0 end --[==[ If the holonym in `data` (in the format as passed to a category handler) refers to a known location, iterate over all such known locations, returning for each location the corresponding key, spec and group as well as the trail of ancestral containers. Unlike `iterate_matching_location()`, this specifically checks that there is no mismatch between the location's containers at any level and any of the following holonyms in the {{tl|place}} spec. The fields in `data` are: * `holonym_placetype`: The placetype of the holonym. It can actually be a list of possible placetypes, as with `iterate_matching_location()`. * `holonym_placename`: The placename of the holonym. * `holonym_index`: The index of the holonym among the holonyms in `place_desc`, or nil if the holonym is not among the holonyms in `place_desc`. (If a holonym index is given, we check for container mismatches among the holonyms following the specified index, stopping either when encountering a holonym marked with modifier `:also` or, if none exist, when we run out of holonyms. If no holonym index is given, we check all holonyms for container mismatches.) * `place_desc`: Description of the place; used for the holonyms, to check for container mismatches. Returns four values: the location group, the canonical key by which the location is known, the spec object describing the location and the trail of ancestral containers for the location. The first three values are the same as for `iterate_matching_location`. ]==] function export.iterate_matching_holonym_location(data) local holonym_placetype, holonym_placename, holonym_index, place_desc = data.holonym_placetype, data.holonym_placename, data.holonym_index, data.place_desc local matching_location_iterator = m_locations.iterate_matching_location { placetypes = holonym_placetype, placename = holonym_placename, } return function() while true do local group, key, spec = matching_location_iterator() if not group then return nil end local container_trail = {} -- For each level of container, check that there are no mismatches (i.e. other location of the same -- placetype) mentioned. We allow a mismatch at a given level if there's also a match with the container -- at that level. For example, in the case of Kansas City, defined in [[Module:place/locations]] as a city -- in Missouri, if we define it as {{tl|place|city|s/Missouri,Kansas}}, we ignore the mismatching state of -- Kansas because the correct state of Missouri was also mentioned. But imagine we are defining Newark, -- Delaware as {{tl|place|city|s/Delaware|c/US}} and (as is the case) we have an entry for Newark, New -- Jersey in [[Module:place/locations]]. Just because the containing location `US` matches isn't enough, -- because Newark, NJ also has New Jersey as a containing location and there's a mismatch at that level. If -- there are no mismatches at any level we assume we're dealing with the right known location. -- -- If at a given level there are multiple containing locations, we count a match if any holonym matches any -- containing location, and a mismatch only if a holonym exists of the same placetype that doesn't match any -- containing location. local containers_mismatch = false for containers in m_locations.iterate_containers(group, key, spec) do insert(container_trail, containers) local match_at_level = false local mismatch_at_level = false for other_holonym_index, other_holonym in export.get_holonyms_to_check(place_desc, holonym_index and holonym_index + 1 or nil) do local other_source_holonym = other_holonym.augmented_from_holonym if other_source_holonym and other_source_holonym.placetype == holonym_placetype and other_source_holonym.unlinked_placename ~= holonym_placename then -- Ignore holonyms added during the augmentation process for other holonyms of the same -- placetype as the placetype of the holonym we're considering. See comment in -- augment_holonyms_with_container() for why we do this. -- continue; grrr, no 'continue' in Lua else local holonym_matches_at_level = false local holonym_exists_with_same_placetype = false for _, container in ipairs(containers) do if not container.spec.no_check_holonym_mismatch then local full_container_placename, elliptical_container_placename = m_locations.key_to_placename(container.group, container.key) local placetypes = container.spec.placetype if type(placetypes) ~= "table" then placetypes = {placetypes} end local placetype_equivs = {} for _, pt in ipairs(placetypes) do m_table.extend(placetype_equivs, export.get_placetype_equivs(pt)) end local this_holonym_matches = export.get_equiv_placetype_prop_from_equivs( placetype_equivs, function(placetype) return other_holonym.placetype == placetype and (other_holonym.unlinked_placename == full_container_placename or other_holonym.unlinked_placename == elliptical_container_placename) end ) if this_holonym_matches then holonym_matches_at_level = true break end local this_holonym_exists_with_same_placetype = export.get_equiv_placetype_prop_from_equivs( placetype_equivs, function(placetype) return other_holonym.placetype == placetype end ) if this_holonym_exists_with_same_placetype then -- We seem to have a mismatch at this level. But before we decide conclusively that this -- is the case, check to see whether the putative mismatch is an alias and matches when -- we resolve the alias. for oh_group, oh_key, oh_spec, oh_container_trail in export.iterate_matching_holonym_location { holonym_placetype = other_holonym.placetype, holonym_placename = other_holonym.unlinked_placename, holonym_index = other_holonym_index, place_desc = place_desc, } do local oh_full_placename, oh_elliptical_placename = m_locations.key_to_placename(oh_group, oh_key) if oh_full_placename == full_container_placename or oh_elliptical_placename == elliptical_container_placename then -- Alias matched when resolved. this_holonym_matches = true break end end if this_holonym_matches then -- Alias matched above when resolved. holonym_matches_at_level = true break else -- Not an alias, or doesn't match when resolved. We have a true mismatch. holonym_exists_with_same_placetype = true end end end end if holonym_matches_at_level then match_at_level = true break end if holonym_exists_with_same_placetype then mismatch_at_level = true end end end if not match_at_level and mismatch_at_level then containers_mismatch = true break end end if not containers_mismatch then return group, key, spec, container_trail end end end end --[==[ If the holonym in `data` (in the format as passed to a category handler) refers to a known location, find and return the corresponding key, spec and group as well as the trail of ancestral containers. This is like `iterate_matching_holonym_location()` but throws an error if more than one location matches. (An example where this would happen is {{tl|place|en|neighborhood|city/Newcastle}}, because there are two known locations named Newcastle. To fix this, specify additional following disambiguating holonyms, e.g. {{tl|place|en|neighborhood|city/Newcastle|s/New South Wales}}. ]==] function export.find_matching_holonym_location(data) local all_found = {} for group, key, spec, container_trail in export.iterate_matching_holonym_location(data) do insert(all_found, {group, key, spec, container_trail}) end if not all_found[1] then return nil elseif all_found[2] then local holonym_placetype = data.holonym_placetype if type(holonym_placetype) == "table" then holonym_placetype = concat(holonym_placetype, ",") end local found_keys = {} for _, found in ipairs(all_found) do local _, key, _, _ = unpack(found) insert(found_keys, key) end error(("Found multiple matching locations for holonym '%s/%s'; specify disambiguating context in the " .. "containing holonyms: %s"):format(holonym_placetype, data.holonym_placename, dump(found_keys))) else return unpack(all_found[1]) end end ------------------------------------------------------------------------------------------ -- Placename and placetype data -- ------------------------------------------------------------------------------------------ --[==[ var: This is a map from aliases to their canonical forms. Any placetypes appearing as keys here will be mapped to their canonical forms in all respects, including the display form. Contrast entries in 'placetype_data' with a fallback, which applies to categorization and other processes but not to display. The most important aliases are for holonym placetypes, particularly those that occur often such as "country", "state", "province" and the like. Particularly long placetypes that mostly occur as entry placetypes (e.g. "census-designated place") can be given abbreviations, but it is generally preferred to spell out the entry placetype. Note also that we purposely avoid certain abbreviations that would be ambiguous (e.g. "d", which could variously be interpreted as "department", "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"] = "country", ["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"] = "continent", ["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"] = "mountain", ["mun"] = "municipality", ["mundist"] = "municipal district", ["nonmetropolitan county"] = "non-metropolitan county", ["obl"] = "oblast", ["okr"] = "okrug", ["p"] = "province", ["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"] = "province", ["r"] = "region", ["range"] = "mountain range", ["rcm"] = "regional county municipality", ["rcomun"] = "regional county municipality", ["rdist"] = "regional district", ["rep"] = "republic", ["rhrom"] = "rural hromada", ["riv"] = "river", ["rmun"] = "regional municipality", ["robor"] = "royal borough", ["romp"] = "Roman province", ["runit"] = "regional unit", ["rurmun"] = "rural municipality", ["s"] = "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 = "the"} local no_link_no_article = {link = false, article = false} --[==[ var: These qualifiers can be prepended onto any placetype and will be handled correctly. For example, the placetype `large city` will be displayed as `large <nowiki>[[city]]</nowiki>` and categorized as if `city` were specified. If the value in the following table is a string, the qualifier will display according to the string. If the value is `true`, the qualifier will be linked to its corresponding Wiktionary entry. If the value is `false`, the qualifier will not be linked but will appear as-is. Note that these qualifiers do not override placetypes with entries elsewhere that contain those same qualifiers. For example, the entry for `inland sea` in `placetype_data` will apply in preference to treating `inland sea` as equivalent to `sea`. ]==] export.placetype_qualifiers = { -- generic qualifiers ["huge"] = false, ["tiny"] = false, ["large"] = false, ["big"] = false, ["mid-size"] = false, ["mid-sized"] = false, ["small"] = false, ["sizable"] = false, ["important"] = false, ["long"] = false, ["short"] = false, ["major"] = false, ["minor"] = false, ["high"] = false, ["tall"] = false, ["low"] = false, ["left"] = false, -- left tributary ["right"] = false, -- right tributary ["modern"] = false, -- for use in opposition to "ancient" in another definition -- "former" qualifiers ["abandoned"] = true, ["ancient"] = true, ["deserted"] = true, ["extinct"] = true, ["former"] = false, ["historic"] = "historical", ["historical"] = true, ["medieval"] = true, ["mediaeval"] = true, ["ruined"] = true, ["traditional"] = true, -- sea qualifiers ["coastal"] = true, ["inland"] = true, -- note, we also have an entry in placetype_data for 'inland sea' to get a link to [[inland sea]] ["maritime"] = true, ["overseas"] = true, ["seaside"] = true, ["beachfront"] = true, ["beachside"] = true, ["riverside"] = true, -- lake qualifiers ["freshwater"] = true, ["saltwater"] = true, ["endorheic"] = true, ["oxbow"] = true, ["ox-bow"] = "[[oxbow]]", -- [[ox-bow]] is a red link ["tidal"] = true, -- land qualifiers ["hilltop"] = true, ["hilly"] = true, ["insular"] = true, ["peninsular"] = true, ["chalk"] = true, ["karst"] = true, ["limestone"] = true, ["mountainous"] = true, ["mountaintop"] = true, ["alpine"] = true, ["volcanic"] = true, -- for an island -- political status qualifiers ["autonomous"] = true, ["incorporated"] = true, ["special"] = true, ["unincorporated"] = true, ["coterminous"] = true, -- monetary status/etc. qualifiers ["fashionable"] = true, ["wealthy"] = true, ["affluent"] = true, ["declining"] = true, -- city vs. rural qualifiers ["urban"] = true, ["suburban"] = true, ["exurban"] = true, ["outlying"] = true, ["remote"] = true, ["rural"] = true, ["outback"] = true, ["inner"] = false, ["inner-city"] = true, ["central"] = false, ["outer"] = false, -- land use qualifiers ["residential"] = true, ["agricultural"] = true, ["business"] = true, ["commercial"] = true, ["industrial"] = true, -- business use qualifiers ["railroad"] = true, ["railway"] = true, ["farming"] = true, ["fishing"] = true, ["mining"] = true, ["logging"] = true, ["cattle"] = true, -- tourism use qualifiers ["resort"] = true, -- note, we also have 'resort city' and 'resort town', that take precedecne ["spa"] = true, -- note, we also have 'spa city' and 'spa town', that take precedecne ["ski"] = true, -- note, we also have 'ski resort city' and 'ski resort town', that take precedecne -- religious qualifiers ["holy"] = true, ["sacred"] = true, ["religious"] = true, ["secular"] = true, -- qualifiers for nonexistent places ["claimed"] = false, ["fictional"] = true, ["legendary"] = true, ["mythical"] = true, ["mythological"] = true, -- directional qualifiers ["northern"] = false, ["southern"] = false, ["eastern"] = false, ["western"] = false, ["north"] = false, ["south"] = false, ["east"] = false, ["west"] = false, ["northeastern"] = false, ["southeastern"] = false, ["northwestern"] = false, ["southwestern"] = false, ["northeast"] = false, ["southeast"] = false, ["northwest"] = false, ["southwest"] = false, -- seasonal qualifiers ["summer"] = true, -- e.g. for 'summer capital' ["winter"] = true, -- legal status qualifiers -- FIXME: Two-word qualifiers don't work yet. But you can enter "de-facto" and it's canonicalized to [[de facto]]. ["official"] = true, ["unofficial"] = true, ["de facto"] = true, -- 'de facto capital' ["de-facto"] = "[[de facto]]", -- [[de-facto]] is a red link ["de jure"] = true, -- 'de jure capital' ["de-jure"] = "[[de jure]]", -- [[de-jure]] is a red link -- NOTE: 'unrecognized/unrecognised' are handled as placetypes 'unrecognized country', 'unrecognized state' -- misc. qualifiers ["planned"] = true, ["chartered"] = true, ["landlocked"] = true, ["uninhabited"] = true, -- superlative qualifiers ["first"] = no_link_def_article, ["second"] = no_link_def_article, -- for "second largest" etc. ["third"] = no_link_def_article, ["fourth"] = no_link_def_article, ["last"] = no_link_def_article, ["only"] = no_link_def_article, ["sole"] = no_link_def_article, ["main"] = no_link_def_article, ["largest"] = no_link_def_article, ["biggest"] = no_link_def_article, ["smallest"] = no_link_def_article, ["shortest"] = no_link_def_article, ["longest"] = no_link_def_article, ["tallest"] = no_link_def_article, ["highest"] = no_link_def_article, ["lowest"] = no_link_def_article, ["leftmost"] = no_link_def_article, ["rightmost"] = no_link_def_article, ["innermost"] = no_link_def_article, ["outermost"] = no_link_def_article, ["northernmost"] = no_link_def_article, ["southernmost"] = no_link_def_article, ["westernmost"] = no_link_def_article, ["easternmost"] = no_link_def_article, ["northwesternmost"] = no_link_def_article, ["southwesternmost"] = no_link_def_article, ["northeasternmost"] = no_link_def_article, ["southeasternmost"] = no_link_def_article, -- several/various ["several"] = no_link_no_article, ["various"] = no_link_no_article, ["numerous"] = no_link_no_article, ["multiple"] = no_link_no_article, ["many"] = no_link_no_article, ["other"] = no_link_no_article, } --[==[ var: In this table, the key qualifiers should be treated the same as the value qualifiers for categorization purposes. This is overridden by `placetype_data` and `qualifier_to_placetype_equivs`. ]==] export.former_qualifiers = { ["abandoned"] = {"FORMER"}, ["ancient"] = {"ANCIENT", "FORMER"}, ["former"] = {"FORMER"}, ["extinct"] = {"FORMER"}, ["historic"] = {"FORMER"}, ["historical"] = {"FORMER"}, ["medieval"] = {"ANCIENT", "FORMER"}, ["mediaeval"] = {"ANCIENT", "FORMER"}, ["ruined"] = {"ANCIENT", "FORMER"}, ["traditional"] = {"FORMER"}, } --[==[ var: In this table, any placetypes containing these qualifiers that do not occur in `placetype_data` should be mapped to the specified placetypes for categorization purposes. Entries here are overridden by `placetype_data`. ]==] export.qualifier_to_placetype_equivs = { ["fictional"] = "fictional location", ["legendary"] = "mythological location", ["mythical"] = "mythological location", ["mythological"] = "mythological location", -- For e.g. Taiwan as a "claimed province" of China; parts of Belize as claimed by Guatemala; various islands -- claimed by various parties in East Asia. FIXME: We should conditionalize on what is being claimed since there are -- also claimed capitals, e.g. Israel and Palestine claim Jerusalem as their capital. ["claimed"] = "claimed political division", } --[==[ var: Mapping from placetypes to the corresponding plural category-only placetype for a capital of that placetype. The reverse mapping also exists. ]==] export.placetype_to_capital_cat = { ["autonomous community"] = "autonomous community capitals", ["canton"] = "cantonal capitals", ["comarca"] = "comarca capitals", ["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", ["province"] = "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"] = {"^Bay of "}, ["lake"] = {"^Lake of "}, ["country"] = {"^Republic of ", " Republic$"}, ["republic"] = {"^Republic of ", " Republic$"}, ["region"] = {" [Rr]egion$"}, ["river"] = {" River$"}, ["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 = "city", holonym_placetype = h_placetype, holonym_placename = h_placename, holonym_index = h_index, place_desc = place_desc, } if retcats then break end end end if not retcats then retcats = {} end -- Now find the appropriate capital-type category for the placetype of the holonym, e.g. 'State capitals'. If we -- recognize the holonym among the known holonyms in [[Module:place/locations]], also add a category like 'State -- capitals of the United States'. Truncate e.g. 'autonomous region' to 'region', 'union territory' to 'territory' -- when looking up the type of capital category, if we can't find an entry for the holonym placetype itself (there's -- an entry for 'autonomous community'). local capital_cat = export.placetype_to_capital_cat[holonym_placetype] if not capital_cat then capital_cat = export.placetype_to_capital_cat[holonym_placetype:gsub("^.* ", "")] end if capital_cat then capital_cat = ucfirst(capital_cat) local inserted_specific_variant_cat = false if holonym_index then -- Now find the first recognized holonym location. We don't stop when :also is seen because of the common pattern -- where we use :also to specify that a given city is the capital at multiple surrounding levels. local matching_group, matching_key, matching_spec, matching_container_trail, matching_holonym_index for h_index = holonym_index, #place_desc.holonyms do if place_desc.holonyms[h_index].placetype then matching_group, matching_key, matching_spec, matching_container_trail = export.find_matching_holonym_location { holonym_placetype = place_desc.holonyms[h_index].placetype, holonym_placename = place_desc.holonyms[h_index].unlinked_placename, holonym_index = h_index, place_desc = place_desc, } if matching_group then matching_holonym_index = h_index break end end end if matching_holonym_index == holonym_index then if matching_container_trail[1] and not matching_spec.no_container_cat then for _, container in ipairs(matching_container_trail[1]) do insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(container.key, container.spec))) inserted_specific_variant_cat = true end end elseif matching_holonym_index then -- Check to make sure that the holonym placetype we were called on is listed among the -- divtypes of the location we found. local function insert_specific_variant_if_possible(key, spec) return export.get_equiv_placetype_prop(holonym_placetype, function(pt) local plural_holonym_placetype = export.pluralize_placetype(pt) local saw_matching_div if spec.divs then local divs = spec.divs if type(divs) ~= "table" then divs = {divs} end for _, div in ipairs(divs) do if type(div) ~= "table" then div = {type = div} end if plural_holonym_placetype == div.type then saw_matching_div = true break end end end if saw_matching_div then insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(key, spec))) return true end return false end) end if insert_specific_variant_if_possible(matching_key, matching_spec) then inserted_specific_variant_cat = true elseif not matching_spec.no_container_cat then for _, containers in ipairs(matching_container_trail) do local saw_no_container_cat = false for _, container in ipairs(containers) do if insert_specific_variant_if_possible(container.key, container.spec) then inserted_specific_variant_cat = true break end saw_no_container_cat = saw_no_container_cat or container.spec.no_container_cat end if inserted_specific_variant_cat or saw_no_container_cat then break end end end end else -- This happens when in an invocation like {{place|en|capital city|s/Haryana,Punjab}} for -- [[Chandigarh]]. We fall back to older code that doesn't depend on the holonym index existing. -- FIXME: This may not be necessary. In the example just given, when processing Haryana we add to -- [[:Category:en:State capitals of India]], and nothing extra gets added when processing Punjab. -- Possibly we can just skip this case entirely. local group, key, spec, container_trail = export.find_matching_holonym_location(data) if group and container_trail[1] and not spec.no_container_cat then for _, container in ipairs(container_trail[1]) do insert(retcats, ("%s of %s"):format(capital_cat, export.get_prefixed_key(container.key, container.spec))) inserted_specific_variant_cat = true end end end if not inserted_specific_variant_cat then insert(retcats, capital_cat) end else -- We didn't recognize the holonym placetype; just put in 'Capital cities'. insert(retcats, "Capital cities") 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, ("Places in %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 "of" local cat_as = div.cat_as or div.type if type(cat_as) ~= "table" then cat_as = {cat_as} end if not export.placetype_data[sgdiv] then internal_error("Placetype %s associated with known location key %s and data %s not found in " .. "`placetype_data`", sgdiv, key, spec) end if sgdiv == data.entry_placetype then local retcats = {} for _, pt_cat in ipairs(cat_as) do if type(pt_cat) == "string" then pt_cat = {type = pt_cat} end local pt_prep = pt_cat.prep or prep insert(retcats, ucfirst(pt_cat.type) .. " " .. pt_prep .. " " .. export.get_prefixed_key(key, spec)) end return retcats end end end end end --[==[ This is used to add pages to "bare" categories like [[:Category:en:Georgia, USA]] for `[[Georgia]]` and any foreign-language terms that are translations of the state of Georgia. We look at the page title (or its overridden value in {{para|pagename}}) as well as the glosses in {{para|t}}/{{para|t2}} etc., various extra-info values such as the modern names in {{para|modern}}, and any values specified using a form-of directive. We need to pay attention to the entry placetypes specified so we don't overcategorize; e.g. the US state of Georgia is `[[Джорджия]]` in Russian but the country of Georgia is `[[Грузия]]`, and if we just looked for matching names, we'd get both Russian terms categorized into both [[:Category:ru:Georgia, USA]] and [[:Category:ru:Georgia]]. We also need to check the containing holonyms to make sure there isn't a mismatch (so we don't e.g. categorize Newark, Delaware in [[:Category:en:Newark]], which is intended for Newark, New Jersey). ]==] function export.get_bare_categories(args, overall_place_spec) local bare_cats = {} local place_descs = overall_place_spec.descs local possible_placetypes_by_place_desc = {} for i, place_desc in ipairs(place_descs) do possible_placetypes_by_place_desc[i] = {} for _, placetype in ipairs(place_desc.placetypes) do if not export.placetype_is_ignorable(placetype) then local equivs = export.get_placetype_equivs(placetype, {register_former_as_non_former = true}) for _, equiv in ipairs(equivs) do insert(possible_placetypes_by_place_desc[i], equiv.placetype) end end end end local function check_term(term) -- Treat Wikipedia links like local ones. term = term:gsub("%[%[w:", "[["):gsub("%[%[wikipedia:", "[[") term = export.remove_links_and_html(term) term = term:gsub("^the ", "") for i, place_desc in ipairs(place_descs) do -- Iterate over all matching locations in case there are multiple, as with Delhi defined as -- {{place|en|megacity/and/union territory|c/India|containing the national capital [[New Delhi]]}}. for group, key, spec, container_trail in export.iterate_matching_holonym_location { holonym_placetype = possible_placetypes_by_place_desc[i], holonym_placename = term, place_desc = place_desc, } do insert(bare_cats, key) end end end -- FIXME: Should we only do the following if the language is English (requires that the lang is passed in)? -- We should always do it if `pagename` is given (as it is with {{tcl}}) but maybe not otherwise unless 1=en. There -- are cases like [[Ankara]] = English name for capital of Turkey, but also the name in various languages for the -- capital of Ghana (= English [[Accra]]). But this should get caught by mismatching the containing country. The -- advantage of checking when the language isn't English is we catch those places that fail to give an English -- translation but where the translation happens to be the same as the other-language spelling. However, I don't -- know how often this situation occurs. check_term(args.pagename or mw.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 "of", 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["County " .. unlinked_placename .. ", Ireland"] or m_locations.northern_ireland_counties["County " .. unlinked_placename .. ", Northern Ireland"] then return prefix_display_handler("County", holonym_placename) end -- Display handler for Taiwanese counties. Taiwanese counties are displayed as e.g. "[[Chiayi]] County". if m_locations.taiwan_counties[unlinked_placename .. " County, Taiwan"] then return suffix_display_handler("County", holonym_placename) end -- Display handler for Romanian counties. Romanian counties are displayed as e.g. "[[Cluj]] County". if m_locations.romania_counties[unlinked_placename .. " County, Romania"] then return suffix_display_handler("County", holonym_placename) end -- FIXME, we need the same for US counties but need to key off the country, not the specific county. -- Others are displayed as-is. return holonym_placename end -- Display handler for prefectures. Japanese prefectures are displayed as e.g. "[[Fukushima]] Prefecture". -- Others are displayed as e.g. "[[Fthiotida]] prefecture". local function prefecture_display_handler(holonym_placetype, holonym_placename) local unlinked_placename = m_links.remove_links(holonym_placename) local suffix = m_locations.japan_prefectures[unlinked_placename .. " Prefecture, Japan"] and "Prefecture" or "prefecture" return suffix_display_handler(suffix, holonym_placename) end -- Display handler for provinces of 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 .. "Province, Bulgaria"] or m_locations.iran_provinces[unlinked_placename .. " Province, Iran"] or m_locations.laos_provinces[unlinked_placename .. " Province, Laos"] or m_locations.north_korea_provinces[unlinked_placename .. " Province, North Korea"] or m_locations.south_korea_provinces[unlinked_placename .. " Province, South Korea"] or m_locations.thailand_provinces[unlinked_placename .. " Province, Thailand"] or m_locations.turkey_provinces[unlinked_placename .. " Province, Turkey"] or m_locations.vietnam_provinces[unlinked_placename .. " Province, Vietnam"] then return suffix_display_handler("Province", holonym_placename) end return holonym_placename end -- Display handler for Nigerian states. Nigerian states are display as "[[Kano]] State". Others are displayed as-is. local function state_display_handler(holonym_placetype, holonym_placename) local unlinked_placename = m_links.remove_links(holonym_placename) if m_locations.nigeria_states[unlinked_placename .. " State, 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 voivodeship_display_handler(holonym_placetype, holonym_placename) return suffix_display_handler("Voivodeship", holonym_placename, nil, "include_suffix_in_link") end ------------------------------------------------------------------------------------------ -- Placetype data -- ------------------------------------------------------------------------------------------ --[==[ var: Main placetype data structure. This specifies, for each canonicalized placetype, various properties. The keys are placetypes (in the singular, except for category-only placetypes, which are plural and followed by `!`), and the value is a table of properties. The `"*"` key is special and is used for adding "generic" categories of the form `Places in ``location`` `; it runs for all entry placetypes. Keys in the form of plural placetypes followed by `!` are used only in [[Module:category tree/topic cat/data/Places]] for specifying the properties of categories containing the specified placetype, esp. bare categories like [[:Category:States and territories]] (rather than qualified categories like [[:Category:States and territories of Australia]]). Keys under the value table for a given placetype of are two types: ''property keys'' (which specify the value of specific properties) and ''categorization keys'' (which tell how to categorize certain sorts of holonyms if the placetype in question occurs as an entry placetype). Categorization keys are either the special value `default` or are wildcard strings with a slash in them, such as `"country/*"`. Note that only wildcard strings are currently allowed directly in the placetype data; everything else is handled through category handlers, either per-placetype or special (such as `political_division_cat_handler`). The algorithm for how category keys and handlers are used to generate categories is described at the top of [[Module:place]]. There are several recognized property keys, of various types: 1. The following link-related property keys are recognized: * `link`: '''Required''' except in category-only placetypes ending in `!`. Describes how to link and display the placetype in the formatted description when occurring as an entry placetype. Also used for formatting pluralized placetypes (which may occur in entry placetypes, esp. new-format ones, such as `two <<islands>>`) and may occur in categories). The possible values are: *# `true`: Link to the same-named Wiktionary entry. This creates a raw link, e.g. `<nowiki>[[city]]</nowiki>`, which is converted to an English-specific link by JavaScript postprocessing. If the placetype is plural, this creates a two-part raw link e.g. `<nowiki>[[city|cities]]</nowiki>`. *# `"w"`: Link to the same-named Wikipedia entry. This creates a two-part link, e.g. `<nowiki>[[w:census town|census town]]</nowiki>`, or `<nowiki>[[w:census town|census towns]]</nowiki>` if the placetype is given plural. *# `"+..."`: Create a two-part link to the entry following the `+` sign. For example, if `cercle` specifies `"+w:cercles of Mali"`, a two-part link `<nowiki>[[w:cercles of Mali|cercle]]</nowiki>` will be generated, or `<nowiki>[[w:cercles of Mali|cercles]]</nowiki>` if plural `cercles` is specified. *# `"separately"`: Link each word separately. For example, if `administrative territory` specifies `"separately"`, it will be linked as `<nowiki>[[administrative]] [[territory]]</nowiki>`, or as `<nowiki>[[administrative]] [[territory|territories]]</nowiki>` if plural `administrative territories` is given. *# another string: Use that string directly. If the placetype is plural, `pluralize()` in [[Module:en-utilities]] is called on the string, which will correctly pluralize most strings, including those with links in them. (If there are multiple links, the display form of the last link is pluralized.) *# `false`: This placetype is not allowed as an entry placetype. An error will be thrown if this placetype is given as an entry placetype. This is specified for internal-use placetypes, especially placetypes used in conjunction with the qualifiers `former`, `ancient`, `historical` and such. * `plural_link`: If specified and the placetype is plural, use the value in place of generating a pluralized version of the link spec in `link`. Most commonly, this is either a string with links in it (which is used directly) or the value `false`, indicating that the placetype cannot occur plural. (This is used for example by `caplc`, which displays as `<nowiki>[[capital]] and [[large]]st [[city]]</nowiki>`, where a plural version doesn't make sense.) Generally if this is specified, `plural` also needs to be specified to give a special placetype plural; this situation occurs especially with multiword placetypes where something other than the last word is pluralized. An example is `town with bystatus`, whose plural is `towns with bystatus`, which needs to be explicitly given. This example uses `link = <nowiki>"[[town]] with [[bystatus#Norwegian Bokmål|bystatus]]"</nowiki>` ({{m|nb|bystatus}}) is a Norwegian Bokmål word, and template calls aren't currently permitted in link strings), along with `plural_link = <nowiki>"[[town]]s with [[bystatus#Norwegian Bokmål|bystatus]]"</nowiki>`. * `category_link`: Spec indicating how to display the placetype when occurring in category descriptions. Defaults to the value of `link`, and in turn is overridden by more specific `category_link_*` keys; see below. Category-only placetypes (which are plural and end in `!`) usually use `category_link` in preference to `link`. The value of `category_link` can be any of the types of specs given above, but most commonly is a plural string with links in it, spelling out the description; in this case it is used directly. When both `category_link` and `link` are given, the value in `category_link` is typically longer and more descriptive. For example, `polity` uses `link = true`, which just generates a link `<nowiki>[[polity]]</nowiki>` or plural `<nowiki>[[polity|polities]]</nowiki>`, but specifies a separate `category_link = <nowiki>"[[independent]] or [[semi-]][[independent]] [[polity|polities]]"</nowiki>`, which clarifies in the category description what a polity is. * `category_link_top_level`: Spec indicating how to display top-level (bare/unqualified) categories, i.e. categories where the placetype is not followed by `in ``location`` ` or `of ``location`` `. If given, this overrides `category_link` for this type of category. * `category_link_before_noncity`: Spec indicating how to display qualified categories of the form ` ``placetypes`` in/of ``location`` ` where ``location`` does not refer to a city. If given, this overrides `category_link` for this type of category. * `category_link_before_city`: Spec indicating how to display qualified categories of the form ` ``placetypes`` in/of ``location`` ` where ``location`` refer to a city. If given, this overrides `category_link` for this type of category. An example where this is given is `neighborhood`, which uses the following specs:<ol> <li>`link = true`</li> <li>`category_link = <nowiki>"[[neighborhood]]s, [[district]]s and other subportions of [[city|cities]]"</nowiki>`</li> <li>`category_link_before_city = <nowiki>"[[neighborhood]]s, [[district]]s and other subportions"</nowiki>`</li> </ol> This has the effect of making the entry placetype `neighborhood` display as just `<nowiki>[[neighborhood]]</nowiki>`, while e.g. a category like `Neighborhoods of Chicago` displays as `<nowiki>[[neighborhood]]s, [[district]]s and other subportions of [[Chicago]], ...</nowiki>` and a category like `Neighborhoods in Illinois, USA` displays as `<nowiki>[[neighborhood]]s, [[district]]s and other subportions of [[city|cities]] in [[Illinois]], ...</nowiki>`. * `disallow_in_entries`: If specified, this placetype cannot occur as an entry placetype, and the specified value (a message indicating what to use instead) is displayed in the error message. * `disallow_in_holonyms`: If specified, this placetype cannot occur as a holonym placetype, and the specified value (a message indicating what to use instead) is displayed in the error message. 2. There is currently one fallback-related property key recognized: * `fallback`: If specified, its value is a placetype which will be used for categorization purposes if no categories get added using the placetype itself. As an example, `branch` sets a fallback of `river` but also sets `preposition = "of"`, 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 = "of", 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 = "of", 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 = "of", 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 = "of", 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 = "of", 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 = "of", class = "natural feature", default = {"Seas"}, }, ["arrondissement"] = { link = true, preposition = "of", -- 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 = "province", }, ["atoll"] = { -- FIXME! Atolls are administrative divisions of the Maldives but natural features elsewhere. Need to -- conditionalize `class` on the country. See also `administrative atoll`. link = true, class = "natural feature", bare_category_parent = "islands", default = {true}, }, ["autonomous city"] = { link = "w", preposition = "of", fallback = "city", has_neighborhoods = true, }, ["autonomous community"] = { -- Spain; refers to regional entities, not village-like entities, as might be expected from "community" link = true, preposition = "of", class = "subpolity", }, ["autonomous island"] = { -- Comoros; seems like an administrative atoll of the Maldives. link = "+w:autonomous islands of Comoros", preposition = "of", class = "subpolity", }, ["autonomous oblast"] = { link = true, preposition = "of", affix_type = "Suf", no_affix_strings = "oblast", class = "subpolity", }, ["autonomous okrug"] = { link = true, preposition = "of", affix_type = "Suf", no_affix_strings = "okrug", class = "subpolity", }, ["autonomous prefecture"] = { link = true, fallback = "prefecture", }, ["autonomous province"] = { link = "w", fallback = "province", }, ["autonomous region"] = { link = "w", preposition = "of", 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 = "of", class = "subpolity", }, ["autonomous territorial unit"] = { -- Moldova; only two of them, one for Gagauzia and one for Transnistria. link = "w", preposition = "of", 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", }, ["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", }, ["bay"] = { link = true, preposition = "of", class = "natural feature", addl_bare_category_parents = {"bodies of water"}, default = {true}, }, ["beach"] = { link = true, class = "natural feature", addl_bare_category_parents = {"water"}, default = {true}, }, ["beach resort"] = { link = "w", fallback = "resort town", }, ["bishopric"] = { link = true, fallback = "polity", }, ["bodies of water!"] = { -- FIXME: This is (maybe?) a type category not a name category. There should be an option for this. We need to -- straighten out the type vs. name vs. related-to issue. category_link = "[[body of water|bodies of water]]", class = "natural feature", addl_bare_category_parents = {"landforms", "ecosystems", "water"}, }, ["borough"] = { link = true, preposition = "of", 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 = "separately", entry_placetype_use_the = true, preposition = "of", has_neighborhoods = true, class = "capital", }, ["branch"] = { link = true, preposition = "of", 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 = "of", affix_type = "suf", class = "subpolity", }, ["cape"] = { link = true, fallback = "headland", }, ["capital"] = { link = true, fallback = "capital city", }, ["capital city"] = { link = true, category_link = "[[capital city|capital cities]]: the [[seat of government|seats of government]] for a country or [[political]] [[division]] of a country", entry_placetype_use_the = true, preposition = "of", has_neighborhoods = true, class = "capital", bare_category_parent = "cities", cat_handler = capital_city_cat_handler, default = {true}, -- The following is necessary so that e.g. [[Melbourne]] defined as {{place|en|capital city|s/Victoria|c/Australia}} -- gets categorized in the bare category [[Category:en:Melbourne]]; otherwise placetype 'capital city' wouldn't -- match against the placetype 'city' of Melbourne. fallback = "city", }, ["caplc"] = { link = "[[capital]] and [[large]]st [[city]]", plural_link = false, fallback = "capital city", }, ["captaincy"] = { link = true, preposition = "of", class = "subpolity", inherently_former = {"FORMER"}, }, ["caravan city"] = { link = "w", fallback = "city", class = "settlement", inherently_former = {"ANCIENT", "FORMER"}, }, ["castle"] = { link = true, fallback = "building", }, ["cathedral city"] = { link = true, fallback = "city", }, ["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 = "of", class = "subpolity", }, ["census town"] = { link = "w", fallback = "town", }, ["central business district"] = { link = true, fallback = "neighborhood", }, ["cercle"] = { -- Mali link = "+w:cercles of Mali", preposition = "of", 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", }, ["chiwog"] = { -- Bhutan link = true, preposition = "of", class = "subpolity", }, ["city"] = { link = true, generic_before_non_cities = "in", 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 +++", "Countries in +++", "National capitals"}, default = {"City-states", "Cities", "Countries", "National capitals"}, }, ["civil parish"] = { -- Mostly England; similar to municipalities link = true, preposition = "of", 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 = "city", }, ["coal town"] = { link = "w", fallback = "town", }, ["collectivity"] = { link = "w", preposition = "of", -- 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 = "of", class = "subpolity", }, ["commandery"] = { link = true, preposition = "of", class = "subpolity", inherently_former = {"ANCIENT", "FORMER"}, }, ["commonwealth"] = { link = true, preposition = "of", -- 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 = "of", class = "subpolity", }, ["constituent country"] = { link = true, preposition = "of", class = "subpolity", }, ["constituent part"] = { link = "separately", preposition = "of", class = "subpolity", }, ["constituent republic"] = { -- Of Russia, Yugoslavia, etc. link = "separately", preposition = "of", 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 = {"Continents and continental regions"}, }, ["continental region"] = { link = "separately", category_link = false, -- can't occur as a bare category class = "geographic region", fallback = "continent", }, ["continents and continental regions!"] = { category_link = "[[continent]]s and [[continent]]-[[level]] [[region]]s (e.g. [[Polynesia]])", class = "geographic region", }, ["council area"] = { link = true, -- in Scotland; similar to a county preposition = "of", affix_type = "suf", class = "subpolity", }, ["country"] = { link = true, class = "polity", ["continent/*"] = {true, "Countries"}, default = {true}, }, ["country-like entities!"] = { category_link = "[[polity|polities]] not normally considered [[country|countries]] but treated similarly for categorization purposes; typically, [[unrecognized]] [[de-facto]] countries or [[w:dependent territory|dependent territories]]", class = "polity", }, ["county"] = { link = true, preposition = "of", display_handler = county_display_handler, class = "subpolity", }, ["county borough"] = { link = true, -- in Wales; similar to a county preposition = "of", affix_type = "suf", fallback = "borough", class = "subpolity", }, ["county seat"] = { link = "separately", entry_placetype_use_the = true, preposition = "of", has_neighborhoods = true, class = "capital", }, ["county town"] = { link = true, entry_placetype_use_the = true, preposition = "of", 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 = "city", 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 = "of", class = "subpolity", }, ["department"] = { link = true, preposition = "of", affix_type = "suf", class = "subpolity", }, ["departmental capital"] = { link = "separately", fallback = "capital city", }, ["dependency"] = { link = true, fallback = "dependent territory", }, ["dependent territory"] = { link = "w", preposition = "of", class = "subpolity", former_type = "dependent territory", bare_category_parent = "political divisions", ["country/*"] = {true}, default = {true}, }, ["desert"] = { link = true, class = "natural feature", addl_bare_category_parents = {"ecosystems"}, 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 = "of", fallback = "river", }, ["district"] = { link = true, preposition = "of", 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 = "of", affix_type = "suf", no_affix_strings = {"district", "municipality"}, fallback = "municipality", class = "subpolity", }, ["division"] = { link = true, preposition = "of", class = "subpolity", }, ["division capital"] = { link = "separately", fallback = "capital city", }, ["dome"] = { link = true, fallback = "mountain", }, ["dormant volcano"] = { link = true, fallback = "volcano", }, ["duchy"] = { link = true, fallback = "polity", }, ["emirate"] = { link = true, preposition = "of", -- FIXME: Can be subpolities (of the United Arab Emirates). fallback = "polity", }, ["empire"] = { link = true, fallback = "polity", }, ["enclave"] = { link = true, preposition = "of", -- Enclaves can theoretically be any size but assume a subpolity. class = "subpolity", }, ["entity"] = { -- Bosnia and Herzegovina link = "+w:entities of Bosnia and Herzegovina", preposition = "of", class = "subpolity", }, ["escarpment"] = { link = true, fallback = "mountain", }, ["ethnographic region"] = { -- used in Lithuania link = "+w:ethnographic regions of Lithuania", fallback = "geographic and cultural area", }, ["exclave"] = { link = true, preposition = "of", -- 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 = "of", fallback = "city", }, ["federal district"] = { link = true, preposition = "of", -- 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 = "of", class = "subpolity", }, ["federal territory"] = { link = "w", fallback = "territory", }, ["fictional location"] = { link = "separately", former_type = "!", class = "hypothetical location", bare_category_parent = "places", 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 = {"bodies of water"}, default = {true}, }, ["footpath"] = { link = true, fallback = "road", }, ["forest"] = { link = true, class = "natural feature", addl_bare_category_parents = {"ecosystems", "forestry"}, 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 = "of", 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 = "of", preposition = "of", class = "geographic region", bare_category_parent = "places", ["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 = "of", class = "subpolity", }, ["gewog"] = { -- Bhutan link = true, preposition = "of", 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 = "of", affix_type = "suf", class = "subpolity", }, ["greater administrative region"] = { -- China (former division) link = "w", preposition = "of", class = "subpolity", inherently_former = {"FORMER"}, }, ["gromada"] = { -- Poland (former division) link = "w", preposition = "of", 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", }, ["gulf"] = { link = true, preposition = "of", holonym_use_the = true, class = "natural feature", addl_bare_category_parents = {"bodies of water"}, default = {true}, }, ["hamlet"] = { link = true, fallback = "village", }, ["harbor city"] = { link = "separately", fallback = "city", }, ["harbor town"] = { link = "separately", fallback = "town", }, ["harbour city"] = { link = "separately", fallback = "city", }, ["harbour town"] = { link = "separately", fallback = "town", }, ["headland"] = { link = true, class = "natural feature", addl_bare_category_parents = {"landforms"}, default = {true}, }, ["headquarters"] = { link = "w", fallback = "administrative centre", }, ["heath"] = { link = true, fallback = "moor", }, ["hemisphere"] = { link = true, entry_placetype_use_the = true, fallback = "continental region", }, ["highway"] = { link = true, fallback = "road", }, ["hill"] = { link = true, class = "natural feature", addl_bare_category_parents = {"landforms"}, 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 = "city", }, ["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 = "of", affix_type = "suf", class = "subpolity", }, ["inactive volcano"] = { link = "w", fallback = "dormant volcano", }, ["independent city"] = { link = true, fallback = "city", }, ["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 = "of", 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 = "of", 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", }, ["island"] = { link = true, preposition = "of", class = "natural feature", addl_bare_category_parents = {"landforms"}, 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 = "of", affix_type = "Suf", class = "subpolity", }, ["lake"] = { link = true, class = "natural feature", addl_bare_category_parents = {"bodies of water"}, default = {true}, }, ["landforms!"] = { category_link = "[[landform]]s", bare_category_parent = "places", addl_bare_category_parents = {"Earth"}, }, ["largest city"] = { link = "[[large]]st [[city]]", entry_placetype_use_the = true, fallback = "city", 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 = "of", class = "subpolity", }, ["local council"] = { -- Malta; similar to municipalities link = "+w:local councils of Malta", preposition = "of", fallback = "municipality", }, ["local government district"] = { link = "w", preposition = "of", 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 = "of", 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 = "of", 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 = "places", }, ["manor"] = { -- FIXME: or is this more like a farm? link = true, fallback = "building", }, ["marginal sea"] = { link = true, preposition = "of", fallback = "sea", }, ["market city"] = { link = "+market town", fallback = "city", }, ["market town"] = { link = true, fallback = "town", }, ["massif"] = { link = true, fallback = "mountain", }, ["megacity"] = { link = true, fallback = "city", }, ["metro station"] = { link = true, class = "man-made structure", }, ["metropolitan borough"] = { link = true, preposition = "of", affix_type = "Pref", no_affix_strings = {"borough", "city"}, 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 = "of", affix_type = "Pref", no_affix_strings = {"metropolitan", "city"}, 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 = "of", 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 = "countries", }, ["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", }, ["moor"] = { link = true, class = "natural feature", addl_bare_category_parents = {"landforms", "ecosystems"}, default = {true}, }, ["moorland"] = { link = true, fallback = "moor", }, ["motorway"] = { link = true, fallback = "road", }, ["mountain"] = { link = true, class = "natural feature", addl_bare_category_parents = {"landforms"}, 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 = {"mountains"}, default = {true}, }, ["mountain range"] = { link = true, fallback = "mountain", }, ["mountainous region"] = { link = "separately", fallback = "region", }, ["mukim"] = { -- Malaysia, Brunei, Indonesia, Singapore link = true, preposition = "of", 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 = "of", affix_type = "Pref", no_affix_strings = "district", fallback = "municipality", }, ["municipality"] = { link = true, preposition = "of", 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", }, ["mythological location"] = { link = "separately", former_type = "!", class = "hypothetical location", bare_category_parent = "places", 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", }, ["natural features!"] = { category_link = "[[w:geographical feature#Natural features|natural features]] such as [[lake]]s, [[mountain]]s, [[island]]s and [[ocean]]s", bare_category_parent = "places", }, ["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 = "of", -- 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 "of" before cities and "in" before non-cities regardless. (FIXME: We should change that.) preposition = "of", 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 = "of", 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 = "of", 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", }, ["ocean"] = { link = true, holonym_use_the = true, class = "natural feature", addl_bare_category_parents = {"seas", "bodies of water"}, default = {true}, }, ["okrug"] = { link = true, preposition = "of", 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 = "of", 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 = "of", fallback = "municipality", has_neighborhoods = true, }, ["parish seat"] = { link = "separately", entry_placetype_use_the = true, preposition = "of", 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 = "mountain", }, ["peninsula"] = { link = true, class = "natural feature", addl_bare_category_parents = {"landforms"}, default = {true}, }, ["periphery"] = { link = true, preposition = "of", class = "subpolity", }, ["places!"] = { generic_before_non_cities = "in", generic_before_cities = "in", 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 = "names", }, ["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 = "places", }, ["polity"] = { link = true, category_link = "[[independent]] or [[semi-]][[independent]] [[polity|polities]]", class = "polity", bare_category_parent = "places", 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 = "city", }, ["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 = "of", 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 = "of", 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 = "of", 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", }, ["province"] = { link = true, preposition = "of", 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 = "separately", fallback = "capital city", }, ["raion"] = { link = true, preposition = "of", affix_type = "Suf", class = "subpolity", }, ["ranch"] = { link = true, fallback = "farm", }, ["range"] = { -- FIXME: Where is this used? Is it a mountain range? link = true, holonym_use_the = true, class = "natural feature", }, ["regency"] = { link = true, preposition = "of", class = "subpolity", }, ["region"] = { link = true, preposition = "of", -- 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 = "of", affix_type = "Suf", no_affix_strings = {"municipality", "county"}, fallback = "municipality", }, ["regional district"] = { link = "w", preposition = "of", affix_type = "Pref", no_affix_strings = "district", fallback = "district", }, ["regional municipality"] = { link = "w", preposition = "of", affix_type = "Pref", no_affix_strings = "municipality", fallback = "municipality", }, ["regional unit"] = { link = "w", preposition = "of", 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 = "city", }, ["resort town"] = { link = "w", fallback = "town", }, ["river"] = { link = true, generic_before_non_cities = "in", holonym_use_the = true, class = "natural feature", addl_bare_category_parents = {"bodies of water"}, 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 = "of", 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 = "of", 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 = "of", class = "subpolity", inherently_former = {"ANCIENT", "FORMER"}, }, ["sea"] = { link = true, holonym_use_the = true, class = "natural feature", addl_bare_category_parents = {"bodies of water"}, default = {true}, }, ["seaport"] = { link = true, fallback = "port", }, ["seat"] = { link = true, fallback = "administrative centre", }, ["self-administered area"] = { -- Myanmar (groups self-administered divisions and zones) link = "+w:self-administered zone", preposition = "of", 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 = "places", -- 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 = "city", }, ["ski resort town"] = { link = "[[ski resort]] [[town]]", fallback = "town", }, ["spa city"] = { link = "+w:spa town", fallback = "city", }, ["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 = "of", 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 = "of", 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 = "separately", 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 = "city", }, ["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 = "city", }, ["sub-prefectural city"] = { link = "w", fallback = "subprovincial city", }, ["subdistrict"] = { link = true, preposition = "of", 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 = "of", 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 = "of", class = "subpolity", }, ["subprovince"] = { link = true, preposition = "of", 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 = "of", 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 "of" for cities. (FIXME: Change this.) generic_before_non_cities = "in", generic_before_cities = "of", preposition = "of", 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 = "of", class = "subpolity", }, ["theme"] = { link = "+w:theme (Byzantine district)", preposition = "of", 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 = "of", 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 = "city", class = "settlement", inherently_former = {"FORMER"}, }, ["tributary"] = { link = true, preposition = "of", 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 = "of", 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 = "city", }, ["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 = "of", fallback = "municipality", has_neighborhoods = true, --? }, ["voivodeship"] = { -- Poland link = true, display_handler = voivodeship_display_handler, preposition = "of", class = "subpolity", }, ["volcano"] = { link = true, plural = "volcanoes", class = "natural feature", addl_bare_category_parents = {"landforms"}, default = {true, "Mountains"}, }, ["ward"] = { 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 = "of", affix_type = "suf", affix = "community", has_neighborhoods = true, class = "settlement", }, ["zone"] = { -- administrative division of Ethiopia, Qatar, Nepal, India link = "+w:zone#Place names", preposition = "of", class = "subpolity", }, ---------------------------------------------------------------------------------------------- -- Categories for former places -- ---------------------------------------------------------------------------------------------- ["ANCIENT capital"] = { link = false, entry_placetype_use_the = true, preposition = "of", 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 = "of", 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 = "of", 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 = "places", }, ["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 = "of", 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 = "of", 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 = "countries", bare_category_parent = "abbreviations of places", }, ["abbreviations of departments!"] = { -- For categorizing abbreviations of departments of e.g. France full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[department]]s", bare_category_breadcrumb = "departments", bare_category_parent = "abbreviations of political divisions", }, ["abbreviations of districts!"] = { -- For categorizing abbreviations of districts of e.g. ??? full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[district]]s", bare_category_breadcrumb = "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 = "countries", bare_category_parent = "abbreviations of former places", }, ["abbreviations of former places!"] = { full_category_link = "{{glossary|abbreviation}}s of [[place]]s that no longer [[exist]]", bare_category_breadcrumb = "abbreviations", bare_category_parent = "former places", addl_bare_category_parents = {{name = "abbreviations of places", sort = "former"}}, }, ["abbreviations of places!"] = { full_category_link = "{{glossary|abbreviation}}s of [[name]]s of [[place]]s", bare_category_breadcrumb = "abbreviations", bare_category_parent = "places", }, ["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 barangay"] = { link = false, fallback = "ABBREVIATION_OF subpolity", }, ["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 = "places", }, ["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 = "places", }, ["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 = "places", }, ["DATED_FORM_OF place"] = { link = false, default = {"Dated forms of places"}, }, ---------- Derogatory names ---------- ["derogatory names for cities!"] = { full_category_link = "{{glossary|derogatory}} [[name]]s for [[city|cities]]", bare_category_breadcrumb = "cities", bare_category_parent = "derogatory names for places", addl_bare_category_parents = {"nicknames for cities"}, }, ["derogatory names for continents!"] = { full_category_link = "{{glossary|derogatory}} [[name]]s for [[continent]]s", bare_category_breadcrumb = "continents", bare_category_parent = "derogatory names for places", addl_bare_category_parents = {"nicknames for continents"}, }, ["derogatory names for countries!"] = { full_category_link = "{{glossary|derogatory}} [[name]]s for [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "derogatory names for places", addl_bare_category_parents = {"nicknames for countries"}, }, ["derogatory names for places!"] = { full_category_link = "{{glossary|derogatory}} [[name]]s for [[place]]s", bare_category_breadcrumb = "derogatory names", bare_category_parent = "nicknames for places", }, ["derogatory names for states!"] = { full_category_link = "{{glossary|derogatory}} [[name]]s for [[state]]s", bare_category_breadcrumb = "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 "city" 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 "city" 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 = "places", }, ["ELLIPSIS_OF place"] = { link = false, default = {"Ellipses of places"}, }, ---------- Former long-form names ---------- ["former long-form names of countries!"] = { full_category_link = "no-longer-[[use]]d [[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "former long-form names of places", addl_bare_category_parents = {{name = "former names of countries", sort = "long-form"}}, }, ["former long-form names of places!"] = { full_category_link = "no-longer-[[use]]d [[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[place]]s", bare_category_breadcrumb = "long-form", bare_category_parent = "former names of places", }, ["FORMER_LONG_FORM_OF country"] = { link = false, default = {"Former long-form names of countries"}, }, ["FORMER_LONG_FORM_OF place"] = { link = false, default = {"Former long-form names of places"}, }, ---------- Former names ---------- ["former names of capitals!"] = { full_category_link = "[[former]] [[name]]s of [[capital city|capital cities]] that generally still exist but under a different name", bare_category_breadcrumb = "capitals", bare_category_parent = "former names of settlements", }, ["former names of countries!"] = { full_category_link = "[[former]] [[name]]s of [[country|countries]] that generally still exist but under a different name", bare_category_breadcrumb = "countries", bare_category_parent = "former names of places", }, ["former names of places!"] = { full_category_link = "[[former]] [[name]]s of [[place]]s that generally still exist but under a different name", bare_category_breadcrumb = "former names", bare_category_parent = "places", }, ["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 "city" 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 "city" but things like "county-level city" and -- "subprovincial city" fall back to "prefecture-level city" link = false, default = {"Former nicknames for cities"}, }, ["FORMER_NICKNAME_FOR town"] = { link = false, default = {"Former nicknames for cities"}, }, ---------- Former official names ---------- ["former official names of countries!"] = { full_category_link = "no-longer-[[use]]d [[official]] [[name]]s of [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "former official names of places", addl_bare_category_parents = {{name = "former names of countries", sort = "official"}}, }, ["former official names of places!"] = { full_category_link = "no-longer-[[use]]d [[official]] [[name]]s of [[place]]s", bare_category_breadcrumb = "official", bare_category_parent = "former names of places", }, ["FORMER_OFFICIAL_NAME_OF country"] = { link = false, default = {"Former official names of countries"}, }, ["FORMER_OFFICIAL_NAME_OF place"] = { link = false, default = {"Former official names of places"}, }, ---------- Long-form names ---------- ["long-form names of countries!"] = { full_category_link = "[[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "long-form names of places", }, ["long-form names of places!"] = { full_category_link = "[[long]]-[[form]] (but typically [[unofficial]]) [[name]]s of [[place]]s", bare_category_breadcrumb = "long-form names", bare_category_parent = "places", }, ["LONG_FORM_OF country"] = { link = false, default = {"Long-form names of countries"}, }, ["LONG_FORM_OF place"] = { link = false, default = {"Long-form names of places"}, }, ---------- Nicknames ---------- ["nicknames for cities!"] = { full_category_link = "[[nickname]]s for [[city|cities]], e.g. the [[Big Apple]] for [[New York City]]", bare_category_breadcrumb = "cities", bare_category_parent = "nicknames for places", addl_bare_category_parents = {"cities"}, }, ["nicknames for continents!"] = { full_category_link = "[[nickname]]s for [[continent]]s", bare_category_breadcrumb = "continents", bare_category_parent = "nicknames for places", addl_bare_category_parents = {"continents"}, }, ["nicknames for countries!"] = { full_category_link = "[[nickname]]s for [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "nicknames for places", addl_bare_category_parents = {"countries"}, }, ["nicknames for places!"] = { full_category_link = "[[nickname]]s for [[place]]s", bare_category_breadcrumb = "places", bare_category_parent = "nicknames", addl_bare_category_parents = {"places"}, }, ["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 "city" 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 "city" 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 = "places", }, ["OBSOLETE_FORM_OF place"] = { link = false, default = {"Obsolete forms of places"}, }, ---------- Official names ---------- ["official names of countries!"] = { full_category_link = "[[official]] [[name]]s of [[country|countries]]", bare_category_breadcrumb = "countries", bare_category_parent = "official names of places", }, ["official names of former countries!"] = { full_category_link = "[[official]] [[name]]s of [[country|countries]] that no longer [[exist]]", bare_category_breadcrumb = "countries", bare_category_parent = "official names of former places", }, ["official names of former places!"] = { full_category_link = "[[official]] [[name]]s of [[place]]s that no longer [[exist]]", bare_category_breadcrumb = "official names", bare_category_parent = "former places", addl_bare_category_parents = {{name = "official names of places", sort = "former"}}, }, ["official names of places!"] = { full_category_link = "[[official]] [[name]]s of [[place]]s", bare_category_breadcrumb = "official names", bare_category_parent = "places", }, ["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 bol6ubcotcmvhwkrt0fz0gh99ul396h मॉड्यूल:also 828 304799 489337 488632 2026-09-22T17:59:24Z SM7 6218 localization...more 489337 Scribunto text/plain local export = {} local debug_track_module = "Module:debug/track" local headword_data_module = "Module:headword/data" local links_module = "Module:links" local script_utilities_module = "Module:script utilities" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local unicode_data_module = "Module:Unicode data" local insert = table.insert local ipairs = ipairs local require = require local type = type --[==[ Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==] local function codepoint(...) codepoint = require(string_utilities_module).codepoint return codepoint(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function lookup_name(...) lookup_name = require(unicode_data_module).lookup_name return lookup_name(...) end local function plain_link(...) plain_link = require(links_module).plain_link return plain_link(...) end local function serial_comma_join(...) serial_comma_join = require(table_module).serialCommaJoin return serial_comma_join(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function track(...) track = require(debug_track_module) return track(...) end --[==[ Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==] local pagename local function get_pagename() pagename, get_pagename = mw.loadData(headword_data_module).pagename, nil return pagename end function export.main(terms) local items, use_semicolon = {}, false for _, v in ipairs(terms) do local term = type(v) == "string" and v or v.term -- Don't add the link if it's the current pagename. if term ~= (pagename or get_pagename()) then local uni = v.uni if uni == nil then -- Use uni_default iff uni is not specified at all. uni = terms.uni_default end if not use_semicolon and term:find(",") then use_semicolon = true end -- Get the script if not already given. local sc = v.sc or find_best_script_without_lang(term) -- Create the link. local link = tag_text(plain_link{term = term, sc = sc}, nil, sc, "bold") local cp if uni then track("also/uni") if uni == "auto" then cp = term:match("^.[\128-\191]*$") and codepoint(term) or nil else cp = tonumber(uni) track(("also/uni/%s"):format( term:match("^.[\128-\191]*$") and cp == codepoint(term) and "auto" or "noauto" )) end end if cp then link = link .. (" <small>[U+%04X %s]</small>"):format( cp, lookup_name(cp):gsub("<", "&lt;"):gsub(">", "&gt;") ) end insert(items, link) end end if #items == 0 then error("Please specify at least one term which is not the current page title.") end return ("<div class=\"disambig-see-also\">''यह भी देखें:'' %s</div>"):format(serial_comma_join(items, { conj = "''और''", punc = use_semicolon and ";" or "," })) end return export la0gv33giduzufaebfnv7i2t2b7j2zm मॉड्यूल:languages/errorGetBy 828 304831 489351 478439 2026-09-23T07:27:16Z SM7 6218 updating... 489351 Scribunto text/plain local function get_text(allowEtymLang, allowFamily) local list = {"language"} if allowEtymLang then table.insert(list, "etymology language") end if allowFamily then table.insert(list, "family") end return mw.text.listToText(list, nil, " or ") end local export = {} function export.code(code, paramForError, allowEtymLang, allowFamily) local text = get_text(allowEtymLang, allowFamily) .. " code" require("Module:languages/error")(code, paramForError, text) end function export.canonicalName(name, allowEtymLang, allowFamily) local text = get_text(allowEtymLang, allowFamily) .. " name" error("The " .. text .. " \"" .. name .. "\" is not valid.") end return export 8he6zfk10jecfi5djjxj71luig4f6wv मॉड्यूल:attention 828 305014 489352 479805 2026-09-23T07:36:02Z SM7 6218 updating... 489352 Scribunto text/plain local export = {} local format_categories = require("Module:utilities").format_categories local html_create = mw.html.create local insert = table.insert local process_params = require("Module:parameters").process function export.show(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, type = "language"}, [2] = true, ["id"] = true, ["sort"] = true, }) local lang = args[1] local lang_code = lang:getCode() local title = args[2] local id = args["id"] or "" local categories = {"Requests for attention concerning " .. lang:getCanonicalName()} if not title then insert(categories, {cat = "attention lacking explanation", sort_key = "-"}) end -- mw.html escapes special characters in the id and title attributes. local ret = html_create("span") :addClass("attentionseeking") :attr("data-lang", lang_code) if id ~= "" then ret = ret:attr("id", "attentionseeking" .. lang_code .. id) end if title then ret = ret:attr("title", title) end return tostring(ret) .. format_categories(categories, lang, args.sort) end return export q3y41ve83j8zdz4ho0m280bteqe8ugg आसामी 0 306942 489335 487734 2026-09-22T16:27:42Z अजीत कुमार तिवारी 4887 पुनर्प्रेषण अनुचित. 489335 wikitext text/x-wiki * देखिए—[[असमिया]] k5u6qg3qzk4ubdis0bx6s8u43teyagv 489336 489335 2026-09-22T17:57:38Z SM7 6218 सुधार... 489336 wikitext text/x-wiki {{also|आसाम|असमिया}} mlg63bh5r5rh32c89qva9sa9ce963ht 489339 489336 2026-09-22T18:15:03Z SM7 6218 सुधार 489339 wikitext text/x-wiki {{also|आसाम|असमिया}} ==हिंदी== ===संज्ञा=== {{hi-noun|m}} # [[असमिया]] व्यक्ति #: {{syn|hi|असमिया}} # [[असमिया]] भाषा; आसाम देश (वर्तमान प्रदेश) की भाषा। #: {{syn|hi|असमिया}} === प्रकाशितकोशों से अर्थ === ==== शब्दसागर ==== आसामी ^१ संज्ञा पुं॰ स्त्री॰ [हि॰] दे॰ 'असामी' । आसामी ^२ वि॰ [हि॰ आसाम] आसाम देश का । आसाम देश संबंधी । आसामी ^३ संज्ञा पुं॰ आसाम देश का निवासी । आसामी ^४ संज्ञा स्त्री॰ आसाम देश की भाषा । [[श्रेणी:हिन्दी-प्रकाशितकोशों से अर्थ-शब्दसागर]] 4jjmd42pnzmqugtuqvfgim51bpf02hh 489340 489339 2026-09-22T18:21:11Z SM7 6218 सुधार 489340 wikitext text/x-wiki {{also|आसाम|असमिया}} ==हिंदी== ===संज्ञा=== {{hi-noun|m}} # [[असमिया]] व्यक्ति #: {{syn|hi|असमिया}} # [[असमिया]] भाषा; आसाम देश (वर्तमान प्रदेश) की भाषा। #: {{syn|hi|असमिया}} ===विशेषण=== {{hi-adj|ind=1}} # असम से संबंधित। === प्रकाशितकोशों से अर्थ === ==== शब्दसागर ==== आसामी ^१ संज्ञा पुं॰ स्त्री॰ [हि॰] दे॰ 'असामी' । आसामी ^२ वि॰ [हि॰ आसाम] आसाम देश का । आसाम देश संबंधी । आसामी ^३ संज्ञा पुं॰ आसाम देश का निवासी । आसामी ^४ संज्ञा स्त्री॰ आसाम देश की भाषा । [[श्रेणी:हिन्दी-प्रकाशितकोशों से अर्थ-शब्दसागर]] mn0wde6c7t045lasmx8w12c2iy25vln साँचा:welcome/draft 10 307419 489353 489141 2026-09-23T07:39:06Z SM7 6218 SM7 ने अनुप्रेषण छोड़े बिना पृष्ठ [[साँचा:Welcome/draft]] को [[साँचा:welcome/draft]] पर स्थानांतरित किया 489141 wikitext text/x-wiki == स्वागत == नमस्कार, विक्षनरी में आपका [[विक्षनरी:स्वागत|स्वागत]] है{{<includeonly>safesubst:</includeonly>#ifeq:{{{contribs|}}}|no||, और अब तक किए गए आपके योगदान के लिए धन्यवाद}}। यदि आप विकि-संपादन से परिचित नहीं हैं, तो [[सहायता:संपादन|किसी पृष्ठ को संपादित कैसे करें]] पर एक नज़र डालें। इसमें यहाँ इस्तेमाल किए जाने वाले विकि प्रारूप से संबंधित तकनीकी दिशानिर्देश संक्षेप में दिए गए हैं; जैसे, पाठ को बोल्ड कैसे करें या हाइपरलिंक कैसे बनाएँ। आप [[विक्षनरी:प्रयोगस्थल|सैंडबॉक्स]] में इनका अभ्यास कर सकते/सकती हैं।<!-- यदि आप धीरे-धीरे सीखना चाहते हैं, तो हमारा छोटा-सा वीडियो ट्यूटोरियल भी देख सकते/सकती हैं।--> इसके अलावा, नीचे दी गयी कड़ियाँ आपको विक्षनरी की कार्यप्रणाली से परिचित होने में मदद कर सकती हैं: * [[विक्षनरी:प्रविष्टि विन्यास|प्रविष्टि विन्यास]] (EL) विक्षनरी के पृष्ठों के प्रारूपण से संबंधित विस्तृत नीति है; सभी प्रविष्टियों को इसका पालन करना आवश्यक है। शुरुआत करने का सबसे आसान तरीका है कि उसी भाषा की किसी मौजूदा प्रविष्टि की सामग्री को कॉपी करके अपनी बनाई जा रही प्रविष्टि के अनुसार उसमें आवश्यक बदलाव कर दिए जाएँ। <!--* किसी विशेष भाषा के लिए संपादन कैसे किया जाता है, यह जानने के लिए भाषा संबंधी विचारबिंदु देखें।--> * हमारे [[विक्षनरी:समावेशन मापदंड|समावेशन के मानदंड]] (CFI) में स्पष्ट रूप से बताया गया है कि किन शब्दों को विक्षनरी में जोड़ा जा सकता है। इसका सबसे महत्वपूर्ण भाग यह है कि विक्षनरी में केवल ऐसे शब्द स्वीकार किए जाते हैं जो कम-से-कम एक वर्ष की अवधि में कुछ व्यापक रूप से प्रचलित रहे हों। जहाँ इसके बारे में संदेह हो, वहाँ शब्द के प्रयोग को प्रमाणित करने वाले उद्धरण माँगे जा सकते हैं। * विक्षनरी एक ऑनलाइन [[शब्दकोश]] है, इसके स्वरूप से अच्छी तरह परिचित होने के लिये [[विक्षनरी:विक्षनरी क्या नहीं है|विक्षनरी क्या नहीं है]] अवश्य देखें। * यदि आपको हमारी सह-परियोजना [[w:मुखपृष्ठ|विकिपीडिया]] के संपादन का पहले से कुछ अनुभव है, तो आपको विकिपीडियंस के लिए [[विक्षनरी:विकिपीडियंस के लिये विक्षनरी|हमारी मार्गदर्शिका]] उपयोगी लग सकती है। * यदि आपके कोई प्रश्न हैं, तो पहले [[विक्षनरी:अक्सर पूछे जाने वाले सवाल]] देखें; अगर आपके प्रश्न का उत्तर वहाँ नहीं मिलता [[विक्षनरी:चौपाल]] पर पूछें या मेरे वार्ता पृष्ठ पर मुझसे पूछ सकते/सकती हैं। * आपको अपने सदस्य पृष्ठ पर [[विक्षनरी:बेबल|बैबेल बॉक्स]] जोड़ने के लिए प्रोत्साहित किया जाता है। इससे आप विभिन्न भाषाओं के बारे में अपने स्वयं के आकलन के अनुसार अपने ज्ञान का स्तर बता सकते/सकती हैं। विक्शनरी पर आपका प्रवास सुखद हो!<!--<noinclude>{{documentation}}</noinclude>--> {{{1|}}} mgmacq7pegs19142u0n8j28p7btyayb অশোভন 0 307479 489330 2026-09-22T16:11:58Z अजीत कुमार तिवारी 4887 +असमिया से शब्द. 489330 wikitext text/x-wiki == असमिया == {{lbor|as|sa|अशोभन}} === संज्ञा === {{as-adj}} # [[अशोभन]]; # असुंदर, अभद्र, सुंदर न लगने वाला, अरुचिकर, अप्रिय। === प्रकाशित कोशों से अर्थ === ==== हिंदी-असमिया-अंग्रेज़ी त्रिभाषा कोश ==== # अशोभन, जो देखने में भला या सुंदर न लगे, असुंदर; # अनुचित, अनुपयुक्त, अभद्र। ====संदर्भ==== {{R:as:HI-AS-EN-v1|pages=137|pageref=137}} 23687auqi7mdmz4miz9cb4b7oghadlx 489331 489330 2026-09-22T16:13:08Z अजीत कुमार तिवारी 4887 489331 wikitext text/x-wiki == असमिया == {{lbor|as|sa|अशोभन}} === विशेषण === {{as-adj}} # [[अशोभन]]; # असुंदर, अभद्र, सुंदर न लगने वाला, अरुचिकर, अप्रिय। === प्रकाशित कोशों से अर्थ === ==== हिंदी-असमिया-अंग्रेज़ी त्रिभाषा कोश ==== # अशोभन, जो देखने में भला या सुंदर न लगे, असुंदर; # अनुचित, अनुपयुक्त, अभद्र। ====संदर्भ==== {{R:as:HI-AS-EN-v1|pages=137|pageref=137}} hikv5t6idxixlti42sl3d0llz692gue অশুত 0 307480 489332 2026-09-22T16:15:24Z अजीत कुमार तिवारी 4887 +असमिया से शब्द. 489332 wikitext text/x-wiki == असमिया == {{lbor|as|sa|अश्रुत}} === विशेषण === {{as-adj}} # [[अश्रुत]]। === प्रकाशित कोशों से अर्थ === ==== हिंदी-असमिया-अंग्रेज़ी त्रिभाषा कोश ==== # अश्रुत, जो पहले कभी सुनने में न आया हो। ====संदर्भ==== {{R:as:HI-AS-EN-v1|pages=138|pageref=138}} acwamsj2sj7o1y3phxapxhclgbxeyu3 অশ্লীল 0 307481 489333 2026-09-22T16:18:21Z अजीत कुमार तिवारी 4887 +असमिया से शब्द. 489333 wikitext text/x-wiki == असमिया == {{lbor|as|sa|अश्लील}} === विशेषण === {{as-adj}} # [[अश्लील]]; # जिसमें शील न हो, फूहड़, भद्दा, घृणास्पद, अमर्यादित, गंदा; # जो नैतिक व सामाजिक आदर्शों से परे हो; # जिससे लज्जा उत्पन्न होती हो, लज्जाजनक, लज्जाप्रद। === प्रकाशित कोशों से अर्थ === ==== हिंदी-असमिया-अंग्रेज़ी त्रिभाषा कोश ==== # अश्लील, नैतिक या सामाजिक आदर्शों से च्युत, सभ्य पुरुषों की रूचि के प्रतिकूल, गंदा, फूहड़। ====संदर्भ==== {{R:as:HI-AS-EN-v1|pages=138|pageref=138}} gzp3bfmxer7a4wazuqvz6jncqhjbhdt অশ্লীলতা 0 307482 489334 2026-09-22T16:21:29Z अजीत कुमार तिवारी 4887 +असमिया से शब्द. 489334 wikitext text/x-wiki == असमिया == {{lbor|as|sa|अश्लीलता}} === संज्ञा === {{as-noun|f}} # [[अश्लीलता]]; # अश्लील होने की अवस्था या भाव, फूहड़पन, भद्दापन, गंदापन, लज्जा का उल्लंघन, निर्लज्जता; # भारतीय काव्यशास्त्र में वर्णित एक काव्यदोष, जिसके तीन भेद किए गए हैं—व्रीड़ाव्यंजक, जुगुप्साव्यंजक और अमंगलव्यंजक। === प्रकाशित कोशों से अर्थ === ==== हिंदी-असमिया-अंग्रेज़ी त्रिभाषा कोश ==== # अश्लीलता, अश्लील होने की अवस्था, गुण या भाव, फूहड़पन, भद्दापन। ====संदर्भ==== {{R:as:HI-AS-EN-v1|pages=138|pageref=138}} o9fmk6p9zt0uon4bip2r2zhpf2geyrk मॉड्यूल:place/locations 828 307483 489345 2026-09-22T18:32:50Z SM7 6218 निर्मित / अंग्रेजी अनुसार++ 489345 Scribunto text/plain local export = {} export.force_cat = false -- set to true to force category generation even on non-mainspace pages local m_table = require("Module:table") local insert = table.insert local dump = mw.dumpObject local unpack = unpack or table.unpack -- Lua 5.2 compatibility --[==[ intro: This module contains data on all known locations, along with some lower-level code to process them (higher-level known-location code is in [[Module:place/placetypes]]). You must load this module using require(), not using mw.loadData(). ===Location data=== '''NOTE: In order to understand the following better, first read the introductory documentation in [[Module:place]], especially the section `More about known locations`.''' The bulk of the code in this module (after some helper functions and placetype tables) describes the known locations and their relationships. Locations are grouped into ''location groups'' that share some common properties (examples are states of the United States and cities in Brazil). Each location group is associated with two tables, a ''data table'' that lists the locations and their individual properties, and a ''metadata table'' that lists group-level properties and defaults for the location properties. Each metadata table points to the associated data table (i.e. contains the data table as its `data` field), and the global `locations` variable holds a list of all group metadata tables. A given location is generally described by three values: (a) the group metadata table for the group the location is part of; (b) the location's canonical ''key'', which is the actual key in the group's data table and is globally unique across all locations; and (c) the location's ''spec'', which is the initialized object describing the properties of the location and comes from the value in the data table corresponding to the canonical key, transformed by the `initialize_spec()` function. These are typically named `group`, `key` and `spec`, respectively and in that order, and are found in the arguments to many functions. In a per-group data table, the keys are either ''canonical keys'' describing locations (which, as mentioned above, must be globally unique) or ''alias keys'' specifying an allowed alias for a given location. There may be multiple aliases for a given location and the alias keys only need to be unique within a particular group data table, not across all groups. It is also possible for the same string to serve as an alias key in one group and a canonical key in another group. (For example, `Newcastle` appears as an alias key in two different groups, referring to two different locations, canonically known as `Newcastle upon Tyne`, for the city in England, and `Newcastle, New South Wales`, for the city in New South Wales, Australia; and `Birmingham` appears both as a canonical key in the group of English cities and an alias key for canonical `Birmingham, Alabama` in the group of US cities.) The corresponding value objects are different for canonical and alias keys. Corresponding to canonical keys are ''location specs'', describing the properies of the location that cannot be derived from default properties of the group or global defaults. Corresponding to alias keys are ''alias specs'', which are highly restricted in the properties they can contain, and whose properties do not have per-group defaults, but only global defaults. The canonical key is always the same as the bare category corresponding to the location, which is one of the reasons it must be globally unique. For example, the country of Georgia uses the canonical key `Georgia` and corresponding bare category [[:Category:Georgia]], while the US state of Georgia uses the canonical key `Georgia, USA` and corresponding bare category [[:Category:Georgia, USA]]. The following conventions are followed in naming keys: * Countries, ''country-like entities'' (which are a mixture of unrecognized de-facto states and dependent territories) and ''former countries'' (which also includes other types of polities, such as the Roman Empire) use their unqualified placename as the canonical key. (See the documentation for [[Module:place]] for the distinction between keys and placenames, which is critical to understand when working with location data.) This also applies to constituent countries (such as England, Aruba and the Faroe Islands) and constituent parts of grouped dependent territories (such as the island of Saint Helena, which is administratively part of the British overseas territory of Saint Helena, Ascension and Tristan da Cunha). * Cities (including prefecture-level cities in China, which behave in most respects more like non-city administrative divisions) also normally use their unqualified placename as the canonical key, but if this causes name conflicts or ambiguities, they use a ''qualified key'' containing either the country name or immediate containing division (if different) following a comma, such as the case of `Newcastle, New South Wales` and `Birmingham, Alabama` above. Examples of name conflicts are the two cities just given; examples of ambiguities are the major cities of León and Mérida in Mexico and city of Cartagena, Colombia, which are given the respective canonical keys of `León, Guanajuato`, `Mérida, Yucatán` and `Cartagena, Colombia` to avoid ambiguity with the well-known respective cities of the same name in Spain, even though none of those cities are large enough to be included as known locations in this module. (The cutoff is generally having a metro area of at least 1,000,000 inhabitants, although there are exceptions.) * Administrative divisions of countries, other than the exceptions noted above for constituent countries and dependent territories, use a qualified key that contains the name of the country or constituent country in it, e.g. `Normandy, France` (a region), `Calvados, France` (a department in the region of Normandy), `Herefordshire, England` (a ceremonial county), `Northwest Territories, Canada` (a territory), `Central Finland, Finland` (a region), `Antalya Province, Turkey` (a province), `Cluj County, Romania` (a county), `County Cork, Ireland` (a county) and `New York, USA` (a state). As shown in these various examples, (a) first and second-level divisions are sometimes both included (as in France, the United Kingdom and China); (b) the qualifier after the comma is sometimes a constituent country (England) instead of a country (United Kingdom), and is sometimes abbreviated (USA rather than United States or Unites States of America); (c) the word `the` is not normally included in the key even if the location is normally preceded by `the` when following a preposition (there is a property in the location and alias specs to indicate this), except in a very few cases (most notably `The Hague`); (d) the country is included as a qualifier even if it creates an apparent redundancy, as with `Central Finland, Finland`; and (e) sometimes the placetype is included in the key, as with provinces in Turkey and several other countries; states in Nigeria; and counties in Ireland, Romania and several other countries. Whether the placetype is included, and whether it follows or precedes the placename, depends on per-country conventions. For example, provinces in Turkey, Iran and several other countries (likewise for states in Nigeria, oblasts in Russia, etc.) conventionally include the word "Province", "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. "country", "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, Australia]] and in old-style place descriptions when the location occurs as the first holonym, such as the city [[Darwin]] described using {{tl|place|city|terr/Northern Territory|c/Australia}}. Note that the global default for this and all Boolean properties is {nil}, which amounts to the same as {false}. * `british_spelling`: Boolean indicating whether the location in question uses British spelling. Currently this only affects whether the spelling `neighborhoods` or `neighbourhoods` is used in categories such as [[:Category:Neighborhoods of New York City]] and [[:Category:Neighbourhoods of Sydney]]. This usually needs to be set only at the top level (i.e. country or country-like entity), because lower-level entities look up the container trail for any container that has `british_spelling = true` set, and if found, assume that British spelling applies. The general principle used in setting this is that all countries in Europe, all dependent territories of any such country, all former British colonies, and any dependent territories of these former colonies, are assumed to use British spelling, while all other countries and associated dependent territories are assumed to use American spelling. This can potentially be modified on a case-by-case basis. * `is_city`: Boolean indicating whether the location in question is a city. This is explicitly set to `true` for city-states (e.g. Monaco and Vatican City), dependent territories that are cities (e.g. Hong Kong, Macau, Bonaire, Gibraltar, etc.), certain city-level administrative divisions (such as `City of Belfast, Northern Ireland`) and (through a group-levell setting) New York boroughs. In addition, it is set to `true` in initialize_spec() whenever the group-level `default_placetype == "city"`, so that all cities get it set without explicitly needing to add a group-level setting for this. Note that the condition `default_placetype == "city"` intentionally excludes Chinese prefecture-level cities, which aren't really cities in that (for example) they don't directly contain neighborhoods, but do contain cities within them. This setting is used in various places: (a) to add cities, rivers, etc. to categories like [[:Category:Rivers in Osaka Prefecture, Japan]] and [[:Category:Cities in Wuhan]] for holonyms that are ''not'' cities; (b) to add districts, neighborhoods, and the like to categories like [[:Category:Neighborhoods of Brooklyn]] and [[:Category:Neighborhoods of Monaco]] for holoynms that ''are'' cities; (c) generally, to determine which "generic" placetypes (cities, rivers, neighborhoods, etc.) apply to the location. (Those that can occur with cities have a `generic_before_cities` setting in [[Module:place/placetypes]], and those that can occur with non-cities have a `generic_before_non_cities` setting.) * `is_former_place`: Boolean that should be set on former places such as the Soviet Union and the Roman Empire. For such places, categories such as [[:Category:fr:Rivers in the Soviet Union]] are neither generated nor recognized (more generally, no "generic" placetypes apply except for `places`), and category descriptions include the word `former`. * `overriding_bare_label_parents`: Document me! * `bare_category_parent_type`: Document me! * `no_container_cat`: Document me! * `no_container_parent`: Document me! * `no_generic_place_cat`: Document me! * `no_check_holonym_mismatch`: Document me! * `no_auto_augment_container`: Document me! * `no_include_container_in_desc`: Document me! ====Location divisions==== The `divs` field of a location describes the recognized political division types of that location. Specifying a given division type will cause places defined as being of the specified division type and with the location as a holonym will cause the place to be categorized as ` ``placetypes`` in/of ``location`` `; for example, specifying that the United States has `"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 `"country"`. ====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 == "city"`, 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 == "city" 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 == "country" 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 = "country"} 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 == "city"` 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 == "city") 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(", England$"), ``` or (when the political division is part of the key) ``` key_to_placename = make_key_to_placename(", South Korea$", " County$") ``` ]=] local function make_key_to_placename(container_patterns, divtype_patterns) if type(container_patterns) == "string" then container_patterns = {container_patterns} end if type(divtype_patterns) == "string" then divtype_patterns = {divtype_patterns} end return function(key) local full_placename = key if container_patterns then for _, container_pattern in ipairs(container_patterns) do local nsubs full_placename, nsubs = full_placename:gsub(container_pattern, "") if nsubs > 0 then break end end end local elliptical_placename = full_placename if divtype_patterns then for _, divtype_pattern in ipairs(divtype_patterns) do local nsubs elliptical_placename, nsubs = elliptical_placename:gsub(divtype_pattern, "") if nsubs > 0 then break end end end return full_placename, elliptical_placename end end --[=[ This is typically used to define `placename_to_key`. It generates a function that appends a string to the end of a given placename to get the key (see the definition of `placename_to_key` above in the documentation under "Location group tables"). Optional `divtype_suffix` is a raw string (which should not contain hyphens or other characters that have special meaning in Lua patterns) to be appended first to the placename; if already present at the end, it is not appended. `container_suffix` is then added in the same fashion if given. Typical usage is like this: ``` placename_to_key = make_placename_to_key(", England") ``` (which will convert e.g. `"Hampshire"` into `"Hampshire, England"`) or ``` placename_to_key = make_placename_to_key(", South Korea", " County") ``` (which will convert e.g. `"Gangwon"` or `"Gangwon County"` into `"Gangwon County, South Korea"`). ]=] local function make_placename_to_key(container_suffix, divtype_suffix) return function(placename) local key = placename if divtype_suffix then if not key:find(divtype_suffix .. "$") then key = key .. divtype_suffix end end if container_suffix then key = key .. container_suffix end return key end end --[=[ This is typically used to define `canonicalize_key_container`, which converts a container as specified in the location data into the canonical form containing both the full container key and its placetype. It generates a function to do the canonicalization of a given container. If the container is a string, `suffix` is appended onto the string (use {nil} or {""} if there is no suffix to append), and the placetype is set to `placetype`. Otherwise the container is left as-is. Typical usage is like this: ``` canonicalize_key_container = make_canonicalize_key_container(", Canada", "province") ``` which will convert e.g. `"Ontario"` into `{key = "Ontario, Canada", placetype = "province"}`. ]=] local function make_canonicalize_key_container(suffix, placetype) return function(container) if type(container) == "string" then return {key = container .. (suffix or ""), placetype = placetype} else return container end end end ----------------------------------------------------------------------------------- -- Top-level tables -- ----------------------------------------------------------------------------------- export.continents = { ["Earth"] = {the = true, placetype = "planet", addl_parents = {"nature"}, fulldesc = "=the planet [[Earth]] and the features found on it"}, ["Africa"] = {placetype = "continent", container = {key = "Earth", placetype = "planet"}}, ["America"] = {placetype = {"supercontinent", "continent"}, container = {key = "Earth", placetype = "planet"}, keydesc = "[[America]], in the sense of [[North America]] and [[South America]] combined", wp = "Americas"}, ["Americas"] = {alias_of = "America", the = true}, ["North America"] = {placetype = "continent", container = {key = "America", placetype = "supercontinent"}}, ["Caribbean"] = {the = true, placetype = {"continental region", "region"}, container = {key = "North America", placetype = "continent"}}, ["Central America"] = {placetype = {"continental region", "region"}, container = {key = "North America", placetype = "continent"}}, ["South America"] = {placetype = "continent", container = {key = "America", placetype = "supercontinent"}}, ["Antarctica"] = {placetype = "continent", container = {key = "Earth", placetype = "planet"}, fulldesc = "=the territory of [[Antarctica]]"}, ["Eurasia"] = {placetype = {"supercontinent", "continent"}, container = {key = "Earth", placetype = "planet"}, keydesc = "[[Eurasia]], i.e. [[Europe]] and [[Asia]] together"}, ["Asia"] = {placetype = "continent", container = {key = "Eurasia", placetype = "supercontinent"}}, ["Europe"] = {placetype = "continent", container = {key = "Eurasia", placetype = "supercontinent"}}, ["Oceania"] = {placetype = "continent", container = {key = "Earth", placetype = "planet"}}, ["Melanesia"] = {placetype = {"continental region", "region"}, container = {key = "Oceania", placetype = "continent"}}, ["Micronesia"] = {placetype = {"continental region", "region"}, container = {key = "Oceania", placetype = "continent"}}, ["Polynesia"] = {placetype = {"continental region", "region"}, container = {key = "Oceania", placetype = "continent"}}, } export.continents_group = { default_overriding_bare_label_parents = {}, -- container parents should be used default_divs = {{type = "countries", prep = "in"}}, -- 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 = "Asia", divs = {"provinces", "districts"}}, ["Albania"] = {container = "Europe", divs = {"counties", "municipalities", "communes", {type = "administrative units", cat_as = "communes"}, }, british_spelling = true}, ["Algeria"] = {container = "Africa", divs = {"provinces", "communes", "districts", "municipalities"}}, ["Andorra"] = {container = "Europe", divs = {"parishes"}, british_spelling = true}, ["Angola"] = {container = "Africa", divs = {"provinces", "municipalities"}}, ["Antigua and Barbuda"] = {container = "Caribbean", divs = {"provinces"}, british_spelling = true}, ["Argentina"] = {container = "South America", divs = {"provinces", "departments", "municipalities"}}, ["Armenia"] = {container = {"Europe", "Asia"}, divs = {"provinces", "districts", "municipalities"}, british_spelling = true}, ["Republic of Armenia"] = {alias_of = "Armenia", the = true}, -- differs in "the" -- Both a country and continent ["Australia"] = {container = "Oceania", 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}, ["Austria"] = {container = "Europe", divs = {"states", "districts", "municipalities"}, british_spelling = true}, ["Azerbaijan"] = {container = {"Europe", "Asia"}, divs = {"districts", "municipalities"}, british_spelling = true}, ["Bahamas"] = {the = true, container = "Caribbean", divs = {"districts"}, british_spelling = true, wp = "The %l"}, ["Bahrain"] = {container = "Asia", divs = {"governorates"}}, ["Bangladesh"] = {container = "Asia", divs = {"divisions", "districts", "municipalities"}, british_spelling = true}, ["Barbados"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true}, ["Belarus"] = {container = "Europe", divs = {"regions", "districts"}, british_spelling = true}, ["Belgium"] = {container = "Europe", divs = {"regions", "provinces", "municipalities"}, british_spelling = true}, ["Belize"] = {container = "Central America", divs = {"districts"}, british_spelling = true}, ["Benin"] = {container = "Africa", divs = {"departments", "communes"}}, ["Bhutan"] = {container = "Asia", divs = {"districts", "gewogs", "chiwogs"}}, ["Bolivia"] = {container = "South America", divs = {"provinces", "departments", "municipalities"}}, ["Bosnia and Herzegovina"] = {container = "Europe", divs = {"entities", "cantons", "municipalities"}, british_spelling = true}, ["Bosnia and Hercegovina"] = {alias_of = "Bosnia and Herzegovina", display = true}, ["Bosnia-Herzegovina"] = {alias_of = "Bosnia and Herzegovina", display = true}, ["Bosnia-Hercegovina"] = {alias_of = "Bosnia and Herzegovina", display = true}, ["Bosnia"] = {alias_of = "Bosnia and Herzegovina", display = true}, ["Botswana"] = {container = "Africa", divs = {"districts", "subdistricts"}, british_spelling = true}, ["Brazil"] = {container = "South America", divs = { "states", "municipalities", "macroregions", {type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"}, }}, ["Brunei"] = {container = "Asia", divs = {"districts", "mukims"}, british_spelling = true}, ["Bulgaria"] = {container = "Europe", divs = {"provinces", "municipalities"}, british_spelling = true}, ["Burkina Faso"] = {container = "Africa", divs = {"regions", "departments", "provinces"}}, ["Burundi"] = {container = "Africa", divs = {"provinces", "communes"}}, ["Cambodia"] = {container = "Asia", divs = {"provinces", "districts"}}, ["Cameroon"] = {container = "Africa", divs = {"regions", "departments"}}, ["Canada"] = {container = "North America", 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 = "Africa", divs = {"municipalities", "parishes"}}, ["Cabo Verde"] = {alias_of = "Cape Verde", display = true}, ["Central African Republic"] = {the = true, container = "Africa", divs = {"prefectures", "subprefectures"}}, ["CAR"] = {alias_of = "Central African Republic", display = true, the = true}, ["C.A.R"] = {alias_of = "Central African Republic", display = true, the = true}, ["Chad"] = {container = "Africa", divs = {"regions", "departments"}}, ["Chile"] = {container = "South America", divs = {"regions", "provinces", "communes"}}, ["China"] = {container = "Asia", divs = { {type = "provinces", cat_as = "provinces and autonomous regions"}, {type = "autonomous regions", cat_as = "provinces and autonomous regions"}, {type = "FORMER provinces", cat_as = "former provinces"}, "special administrative regions", "prefectures", {type = "FORMER prefectures", cat_as = "former prefectures"}, "prefecture-level cities", {type = "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 = "China", the = true}, -- differs in "the" ["Colombia"] = {container = "South America", divs = {"departments", "municipalities"}}, ["Comoros"] = {the = true, container = "Africa", divs = {"autonomous islands"}}, ["Costa Rica"] = {container = "Central America", divs = {"provinces", "cantons"}}, ["Croatia"] = {container = "Europe", divs = {"counties", "municipalities"}, british_spelling = true}, ["Cuba"] = {container = "Caribbean", divs = {"provinces", "municipalities"}}, ["Cyprus"] = {container = {"Europe", "Asia"}, divs = {"districts"}, british_spelling = true}, ["Czech Republic"] = {the = true, container = "Europe", divs = {"regions", "districts", "municipalities"}, british_spelling = true}, ["Czechia"] = {alias_of = "Czech Republic"}, -- differs in "the" ["Democratic Republic of the Congo"] = {the = true, container = "Africa", 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}, ["Denmark"] = {container = "Europe", divs = {"regions", "municipalities", "dependent territories"}, british_spelling = true, -- Wikipedia separates [[w:Denmark]] (constituent country) from [[w:Danish Realm]] (country) }, ["Djibouti"] = {container = "Africa", divs = {"regions", "districts"}}, ["Dominica"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true}, ["Dominican Republic"] = {the = true, container = "Caribbean", divs = {"provinces", "municipalities"}, keydesc = "the [[Dominican Republic]], the country that shares the [[Caribbean]] island of [[Hispaniola]] with [[Haiti]]"}, ["East Timor"] = {container = "Asia", divs = {"municipalities"}, wp = "Timor-Leste"}, ["Timor-Leste"] = {alias_of = "East Timor", display = true}, ["Ecuador"] = {container = "South America", divs = {"provinces", "cantons"}}, ["Egypt"] = {container = "Africa", divs = {"governorates", "regions"}, british_spelling = true}, ["El Salvador"] = {container = "Central America", divs = {"departments", "municipalities"}}, ["Equatorial Guinea"] = {container = "Africa", divs = {"provinces"}}, ["Eritrea"] = {container = "Africa", divs = {"regions", "subregions"}}, ["Estonia"] = {container = "Europe", divs = {"counties", "municipalities"}, british_spelling = true}, ["Eswatini"] = {container = "Africa", british_spelling = true}, ["Swaziland"] = {alias_of = "Eswatini", display = true}, ["Ethiopia"] = {container = "Africa", 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}, ["Finland"] = {container = "Europe", divs = {"regions", "municipalities"}, british_spelling = true}, ["France"] = {container = "Europe", 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 = "Africa", divs = {"provinces", "departments"}}, ["Gambia"] = {the = true, container = "Africa", divs = {"divisions", "districts"}, british_spelling = true, wp = "The %l"}, ["Georgia"] = {container = {"Europe", "Asia"}, divs = {"regions", "districts"}, keydesc = "the country of [[Georgia]], in [[Eurasia]]", british_spelling = true, wp = "%l (country)"}, ["Germany"] = {container = "Europe", 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 = "Africa", divs = {"regions", "districts"}, british_spelling = true}, ["Greece"] = {container = "Europe", divs = {"regions", "regional units", "municipalities", {type = "peripheries", cat_as = {"regions"}}, }, british_spelling = true}, ["Grenada"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true}, ["Guatemala"] = {container = "Central America", divs = {"departments", "municipalities"}}, ["Guinea"] = {container = "Africa", divs = {"regions", "prefectures"}}, ["Guinea-Bissau"] = {container = "Africa", divs = {"regions"}}, ["Guyana"] = {container = "South America", divs = {"regions"}, british_spelling = true}, ["Haiti"] = {container = "Caribbean", divs = {"departments", "arrondissements"}}, ["Honduras"] = {container = "Central America", divs = {"departments", "municipalities"}}, ["Hungary"] = {container = "Europe", divs = {"counties", "districts"}, british_spelling = true}, ["Iceland"] = {container = "Europe", divs = {"regions", "municipalities", "counties"}, british_spelling = true}, ["India"] = {container = "Asia", 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 = "Asia", divs = {"regencies", "provinces", {type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"}, }}, ["Iran"] = {container = "Asia", divs = {"provinces", "counties"}}, ["Iraq"] = {container = "Asia", divs = {"governorates", "districts"}}, ["Ireland"] = {container = "Europe", addl_parents = {"British Isles"}, divs = {"counties", "districts", "provinces"}, british_spelling = true, wp = "Republic of %l"}, ["Republic of Ireland"] = {alias_of = "Ireland", the = true}, -- differs in "the" ["Israel"] = {container = "Asia", divs = {"districts"}}, ["Italy"] = {container = "Europe", divs = { "regions", "provinces", "metropolitan cities", "municipalities", {type = "autonomous regions", cat_as = "regions"}, }, british_spelling = true}, ["Ivory Coast"] = {container = "Africa", 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 = "Ivory Coast"}, ["Jamaica"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true}, ["Japan"] = {container = "Asia", divs = {"prefectures", "subprefectures", "municipalities"}}, ["Jordan"] = {container = "Asia", divs = {"governorates"}}, ["Kazakhstan"] = {container = {"Asia", "Europe"}, divs = {"regions", "districts"}}, ["Kenya"] = {container = "Africa", divs = {"counties"}, british_spelling = true}, ["Kiribati"] = {container = "Micronesia", british_spelling = true}, ["Kosovo"] = {container = "Europe", divs = {"districts", "municipalities"}, british_spelling = true}, ["Kuwait"] = {container = "Asia", divs = {"governorates", "areas"}}, ["Kyrgyzstan"] = {container = "Asia", divs = {"regions", "districts"}}, ["Laos"] = {container = "Asia", divs = {"provinces", "districts"}}, ["Latvia"] = {container = "Europe", divs = {"municipalities"}, british_spelling = true}, ["Lebanon"] = {container = "Asia", divs = {"governorates", "districts"}}, ["Lesotho"] = {container = "Africa", divs = {"districts"}, british_spelling = true}, ["Liberia"] = {container = "Africa", divs = {"counties", "districts"}}, ["Libya"] = {container = "Africa", divs = {"districts", "municipalities"}}, ["Liechtenstein"] = {container = "Europe", divs = {"municipalities"}, british_spelling = true}, ["Lithuania"] = {container = "Europe", divs = {"counties", "municipalities"}, british_spelling = true}, ["Luxembourg"] = {container = "Europe", divs = {"cantons", "districts"}, british_spelling = true}, ["Madagascar"] = {container = "Africa", divs = {"regions", "districts"}}, ["Malawi"] = {container = "Africa", divs = {"regions", "districts"}, british_spelling = true}, ["Malaysia"] = {container = "Asia", divs = {"states", "federal territories", "districts"}, british_spelling = true}, ["Maldives"] = {the = true, container = "Asia", divs = {"provinces", "administrative atolls"}, british_spelling = true}, ["Mali"] = {container = "Africa", divs = {"regions", "cercles"}}, ["Malta"] = {container = "Europe", divs = {"regions", "local councils"}, british_spelling = true}, ["Marshall Islands"] = {the = true, container = "Micronesia", divs = {"municipalities"}}, ["Mauritania"] = {container = "Africa", divs = {"regions", "departments"}}, ["Mauritius"] = {container = "Africa", divs = {"districts"}, british_spelling = true}, ["Mexico"] = {container = "North America", addl_parents = {"Central America"}, divs = { "states", "municipalities", {type = "ABBREVIATION_OF states", cat_as = "abbreviations of states"}, }}, ["Moldova"] = {container = "Europe", 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", "country"}, container = "Europe", -- 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 = "countries", prep = "in"}, is_city = true, british_spelling = true}, ["Mongolia"] = {container = "Asia", divs = {"provinces", "districts"}}, ["Montenegro"] = {container = "Europe", divs = {"municipalities"}}, ["Morocco"] = {container = "Africa", divs = {"regions", "prefectures", "provinces"}}, ["Mozambique"] = {container = "Africa", divs = {"provinces", "districts"}}, ["Myanmar"] = {container = "Asia", 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 = "Africa", divs = {"regions", "constituencies"}, british_spelling = true}, ["Nauru"] = {container = "Micronesia", divs = {"districts"}, british_spelling = true}, ["Nepal"] = {container = "Asia", divs = {"provinces", "districts"}}, ["Netherlands"] = {the = true, placetype = {"country", "constituent country"}, container = "Europe", 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 = "Central America", divs = {"departments", "municipalities"}}, ["Niger"] = {container = "Africa", divs = {"regions", "departments"}}, ["Nigeria"] = {container = "Africa", 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}, ["North Korea"] = {container = "Asia", addl_parents = {"Korea"}, divs = {"provinces", "counties"}}, ["North Macedonia"] = {container = "Europe", divs = {"regions", "municipalities"}, british_spelling = true}, ["Macedonia"] = {alias_of = "North Macedonia", display = true}, ["Republic of North Macedonia"] = {alias_of = "North Macedonia", the = true}, -- differs in "the" ["Republic of Macedonia"] = {alias_of = "North Macedonia", the = true}, -- differs in "the" ["Norway"] = {container = "Europe", divs = {"counties", "municipalities", "dependent territories", "districts", "unincorporated areas"}, british_spelling = true}, ["Oman"] = {container = "Asia", divs = {"governorates", "provinces"}}, ["Pakistan"] = {container = "Asia", 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 = "Asia", divs = {"governorates"}}, ["State of Palestine"] = {alias_of = "Palestine", the = true}, -- differs in "the" ["Panama"] = {container = "Central America", divs = {"provinces", "districts"}}, ["Papua New Guinea"] = {container = "Melanesia", divs = {"provinces", "districts"}, british_spelling = true}, ["Paraguay"] = {container = "South America", divs = {"departments", "districts"}}, ["Peru"] = {container = "South America", divs = {"regions", "provinces", "districts"}}, ["Philippines"] = {the = true, container = "Asia", divs = { "regions", "provinces", "districts", "municipalities", "barangays", {type = "ABBREVIATION_OF provinces", cat_as = "abbreviations of provinces"}, {type = "ABBREVIATION_OF barangays", cat_as = "abbreviations of barangays"}, }}, ["Poland"] = {divs = {"voivodeships", "counties", {type = "Polish colonies", cat_as = {{type = "villages", prep = "in"}}}, }, container = "Europe", british_spelling = true}, ["Portugal"] = {container = "Europe", 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 = "Asia", divs = {"municipalities", "zones"}}, ["Republic of the Congo"] = {the = true, container = "Africa", divs = {"departments", "districts"}}, ["Congo Republic"] = {alias_of = "Republic of the Congo", display = true, the = true}, ["Romania"] = {container = "Europe", divs = { "regions", "counties", "communes", {type = "ABBREVIATION_OF counties", cat_as = "abbreviations of counties"}, }, british_spelling = true}, ["Russia"] = {container = {"Europe", "Asia"}, divs = { "federal subjects", "republics", "autonomous oblasts", "autonomous okrugs", "oblasts", "krais", "federal cities", "districts", "federal districts"}, british_spelling = true}, ["Rwanda"] = {container = "Africa", divs = {"provinces", "districts"}}, ["Saint Kitts and Nevis"] = {container = "Caribbean", divs = {"parishes"}, british_spelling = true}, ["Saint Kitts"] = {alias_of = "Saint Kitts and Nevis", display = true}, ["Saint Lucia"] = {container = "Caribbean", divs = {"districts"}, british_spelling = true}, ["Saint Vincent and the Grenadines"] = {container = "Caribbean", 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 = "Europe", divs = {"municipalities"}, british_spelling = true}, ["São Tomé and Príncipe"] = {container = "Africa", 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}, ["Saudi Arabia"] = {container = "Asia", divs = {"provinces", "governorates"}}, ["Senegal"] = {container = "Africa", divs = {"regions", "departments"}}, ["Serbia"] = {container = "Europe", divs = {"districts", "municipalities", "autonomous provinces"}}, ["Seychelles"] = {container = "Africa", divs = {"districts"}, british_spelling = true}, ["Sierra Leone"] = {container = "Africa", divs = {"provinces", "districts"}, british_spelling = true}, ["Singapore"] = {container = "Asia", divs = {"districts", "regions"}, british_spelling = true}, ["Slovakia"] = {container = "Europe", divs = {"regions", "districts"}, british_spelling = true}, ["Slovenia"] = {container = "Europe", 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 = "Africa", divs = {"regions", "districts"}}, ["South Africa"] = {container = "Africa", divs = { "provinces", "districts", {type = "district municipalities", cat_as = "districts"}, {type = "metropolitan municipalities", cat_as = "districts"}, "municipalities", }, british_spelling = true}, ["South Korea"] = {container = "Asia", addl_parents = {"Korea"}, divs = {"provinces", "counties", "districts"}}, ["South Sudan"] = {container = "Africa", divs = {"regions", "states", "counties"}, british_spelling = true}, ["Spain"] = {container = "Europe", divs = {"autonomous communities", "provinces", "municipalities", "comarcas", "autonomous cities"}, british_spelling = true}, ["Sri Lanka"] = {container = "Asia", divs = {"provinces", "districts"}, british_spelling = true}, ["Sudan"] = {container = "Africa", divs = {"states", "districts"}, british_spelling = true}, ["Suriname"] = {container = "South America", divs = {"districts"}}, ["Sweden"] = {container = "Europe", divs = {"provinces", "counties", "municipalities"}, british_spelling = true}, ["Switzerland"] = {container = "Europe", divs = {"cantons", "municipalities", "districts"}, british_spelling = true}, ["Syria"] = {container = "Asia", divs = {"governorates", "districts"}}, ["Taiwan"] = {container = "Asia", divs = {"counties", "districts", "townships", "special municipalities"}}, ["Republic of China"] = {alias_of = "Taiwan", the = true}, -- differs in "the", different political connotations ["Tajikistan"] = {container = "Asia", divs = {"regions", "districts"}}, ["Tanzania"] = {container = "Africa", divs = {"regions", "districts"}, british_spelling = true}, ["Thailand"] = {container = "Asia", divs = {"provinces", "districts", "subdistricts"}}, ["Togo"] = {container = "Africa", divs = {"provinces", "prefectures"}}, ["Tonga"] = {container = "Polynesia", divs = {"divisions"}, british_spelling = true}, ["Trinidad and Tobago"] = {container = "Caribbean", divs = {"regions", "municipalities"}, british_spelling = true}, ["Tunisia"] = {container = "Africa", divs = {"governorates", "delegations"}}, ["Turkey"] = {container = {"Europe", "Asia"}, divs = {"provinces", "districts"}}, -- Foreign names generally get display-canonicalized. ["Türkiye"] = {alias_of = "Turkey", display = true}, ["Turkmenistan"] = {container = "Asia", divs = { -- The 5 regions are often also called provinces "regions", {type = "provinces", cat_as = "regions"}, "districts"}, }, ["Tuvalu"] = {container = "Polynesia", divs = {"atolls"}, british_spelling = true}, ["Uganda"] = {container = "Africa", divs = {"districts", "counties"}, british_spelling = true}, ["Ukraine"] = {container = "Europe", divs = { {type = "oblasts", cat_as = "oblasts and autonomous republics"}, {type = "autonomous republics", cat_as = "oblasts and autonomous republics"}, "raions", "hromadas", }, british_spelling = true}, ["United Arab Emirates"] = {the = true, container = "Asia", divs = {"emirates"}}, -- Abbreviations get display-canonicalized. ["UAE"] = {alias_of = "United Arab Emirates", display = true, the = true}, ["U.A.E."] = {alias_of = "United Arab Emirates", display = true, the = true}, ["United Kingdom"] = {the = true, container = "Europe", 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}, ["United States"] = {the = true, container = "North America", 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 = "United States", display = true, the = true}, ["U.S."] = {alias_of = "United States", display = true, the = true}, ["USA"] = {alias_of = "United States", display = true, the = true}, ["U.S.A."] = {alias_of = "United States", display = true, the = true}, ["United States of America"] = {alias_of = "United States", display = true, the = true}, ["Uruguay"] = {container = "South America", divs = {"departments", "municipalities"}}, ["Uzbekistan"] = {container = "Asia", divs = {"regions", "districts"}}, ["Vanuatu"] = {container = "Melanesia", divs = {"provinces"}, british_spelling = true}, ["Vatican City"] = {placetype = {"city-state", "country"}, container = "Europe", -- 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 = "countries", prep = "in"}, addl_parents = {"Rome"}, is_city = true, british_spelling = true}, ["Vatican"] = {alias_of = "Vatican City", the = true}, -- differs in "the" ["Venezuela"] = {container = "South America", divs = {"states", "municipalities"}}, ["Vietnam"] = {container = "Asia", divs = {"provinces", "districts", "municipalities"}}, ["Western Sahara"] = {placetype = {"territory", "country"}, container = "Africa", bare_category_parent_type = {type = "countries", prep = "in"}, }, -- Not display-canonicalizable both due to differences in 'the' and the sovereignty dispute over Western Sahara ["Sahrawi Arab Democratic Republic"] = {alias_of = "Western Sahara", the = true}, ["SADR"] = {alias_of = "Sahrawi Arab Democratic Republic", display = true, the = true}, ["Yemen"] = {container = "Asia", divs = {"governorates", "districts"}}, ["Zambia"] = {container = "Africa", divs = {"provinces", "districts"}, british_spelling = true}, ["Zimbabwe"] = {container = "Africa", 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 = {"+++", "countries"}, default_placetype = "country", 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", "Europe", "Asia"}, british_spelling = true, }, -- Åland: Listed as a region of Finland. Wikipedia lists this under "dependent territories" in -- [[w:List of sovereign states and dependent territories by continent]]. -- unincorporated territory of the United States ["American Samoa"] = { placetype = {"unincorporated territory", "overseas territory", "territory"}, container = "United States", addl_parents = {"Polynesia"}, }, -- British Overseas Territory ["Anguilla"] = { placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Caribbean"}, british_spelling = true, }, -- de-facto independent state, internationally recognized as part of Georgia ["Abkhazia"] = { placetype = {"unrecognized country", "country"}, addl_parents = {"Georgia", "Europe", "Asia"}, 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 = "Australia", addl_parents = {"Asia"}, }, -- constituent country of the Netherlands ["Aruba"] = { placetype = {"constituent country", "country"}, container = "Netherlands", addl_parents = {"Caribbean"}, british_spelling = true, }, -- British Overseas Territory ["Bermuda"] = { placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"North America"}, british_spelling = true, }, -- special municipality of the Netherlands ["Bonaire"] = { placetype = {"special municipality", "municipality", "overseas territory", "territory"}, container = "Netherlands", addl_parents = {"Caribbean"}, is_city = true, british_spelling = true, }, -- British Overseas Territory ["British Indian Ocean Territory"] = { the = true, placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Asia"}, british_spelling = true, }, -- British Overseas Territory ["British Virgin Islands"] = { the = true, placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Caribbean"}, british_spelling = true, }, -- Norwegian dependent territory ["Bouvet Island"] = { placetype = {"dependent territory", "territory"}, container = "Norway", addl_parents = {"Africa"}, british_spelling = true, }, -- British Overseas Territory ["Cayman Islands"] = { the = true, placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Caribbean"}, british_spelling = true, }, -- Australian external territory ["Christmas Island"] = { placetype = {"external territory", "territory"}, container = "Australia", addl_parents = {"Asia"}, british_spelling = true, }, -- Sui generis French "state private property" per Wikipedia; classify as overseas territory like the -- French Southern and Antarctic Lands. ["Clipperton Island"] = { placetype = {"overseas territory", "territory"}, container = "France", addl_parents = {"North America"}, }, -- Australian external territory; also called the Keeling Islands or (officially) the Cocos (Keeling) Islands ["Cocos Islands"] = { the = true, placetype = {"external territory", "territory"}, container = "Australia", addl_parents = {"Asia"}, wp = "Cocos (Keeling) Islands", british_spelling = true, }, ["Cocos (Keeling) Islands"] = {alias_of = "Cocos Islands", display = true, the = true}, ["Keeling Islands"] = {alias_of = "Cocos Islands", display = true, the = true}, -- self-governing but in free association with New Zealand ["Cook Islands"] = { the = true, placetype = {"country"}, container = "New Zealand", addl_parents = {"Polynesia"}, british_spelling = true, }, -- constituent country of the Netherlands ["Curaçao"] = { placetype = {"constituent country", "country"}, container = "Netherlands", addl_parents = {"Caribbean"}, 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 = {"South America"}, british_spelling = true, }, -- autonomous territory of Denmark ["Faroe Islands"] = { the = true, placetype = {"autonomous territory", "territory"}, container = "Denmark", addl_parents = {"Europe"}, british_spelling = true, }, -- overseas department and region of France ["French Guiana"] = { placetype = {"overseas department", "department", "administrative region", "region"}, container = "France", divs = {"communes"}, addl_parents = {"South America"}, british_spelling = true, }, -- overseas collectivity of France ["French Polynesia"] = { placetype = {"overseas collectivity", "collectivity"}, container = "France", addl_parents = {"Polynesia"}, british_spelling = true, }, -- French overseas territory ["French Southern and Antarctic Lands"] = { the = true, placetype = {"overseas territory", "territory"}, container = "France", addl_parents = {"Africa"}, }, -- British Overseas Territory ["Gibraltar"] = { placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Europe"}, is_city = true, british_spelling = true, }, -- autonomous territory of Denmark ["Greenland"] = { placetype = {"autonomous territory", "territory"}, container = "Denmark", addl_parents = {"North America"}, divs = {"municipalities"}, british_spelling = true, }, -- overseas department and region of France ["Guadeloupe"] = { placetype = {"overseas department", "department", "administrative region", "region"}, container = "France", addl_parents = {"Caribbean"}, divs = {"communes"}, british_spelling = true, }, -- unincorporated territory of the United States ["Guam"] = { placetype = {"unincorporated territory", "overseas territory", "territory"}, container = "United States", 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", "Europe"}, british_spelling = true, wp = "Bailiwick of %l", }, ["Bailiwick of Guernsey"] = {alias_of = "Guernsey", the = true}, -- Australian external territory ["Heard Island and McDonald Islands"] = { the = true, placetype = {"external territory", "territory"}, container = "Australia", addl_parents = {"Africa"}, }, -- special administrative region of China ["Hong Kong"] = { placetype = {"special administrative region", "city"}, container = "China", is_city = true, british_spelling = true, }, -- self-governing British Crown dependency ["Isle of Man"] = { the = true, placetype = {"crown dependency", "dependency", "dependent territory", "territory"}, container = "United Kingdom", addl_parents = {"British Isles", "Europe"}, british_spelling = true, }, -- Norwegian unincorporated area ["Jan Mayen"] = { placetype = {"unincorporated area", "dependent territory", "territory", "island"}, container = "Norway", addl_parents = {"Europe"}, 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", "Europe"}, british_spelling = true, }, ["Bailiwick of Jersey"] = {alias_of = "Jersey", the = true}, -- special administrative region of China ["Macau"] = { placetype = {"special administrative region", "city"}, container = "China", is_city = true, british_spelling = true, }, -- overseas department and region of France ["Martinique"] = { placetype = {"overseas department", "department", "administrative region", "region"}, container = "France", divs = {"communes"}, addl_parents = {"Caribbean"}, british_spelling = true, }, -- overseas department and region of France ["Mayotte"] = { placetype = {"overseas department", "department", "administrative region", "region"}, container = "France", divs = {"communes"}, addl_parents = {"Africa"}, british_spelling = true, }, -- British Overseas Territory ["Montserrat"] = { placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Caribbean"}, british_spelling = true, }, -- special collectivity of France ["New Caledonia"] = { placetype = {"special collectivity", "collectivity"}, container = "France", addl_parents = {"Melanesia"}, british_spelling = true, }, -- dependent territory of New Zealand ["New Zealand Subantarctic Islands"] = { the = true, placetype = {"dependent territory", "territory"}, container = "New Zealand", addl_parents = {"Antarctica"}, british_spelling = true, }, -- self-governing but in free association with New Zealand ["Niue"] = { placetype = {"country"}, container = "New Zealand", addl_parents = {"Polynesia"}, british_spelling = true, }, -- Australian external territory ["Norfolk Island"] = { placetype = {"external territory", "territory"}, container = "Australia", addl_parents = {"Polynesia"}, british_spelling = true, }, -- de-facto independent state, internationally recognized as part of Cyprus ["Northern Cyprus"] = { placetype = {"unrecognized country", "country"}, addl_parents = {"Cyprus", "Turkey", "Europe", "Asia"}, 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 = "United States", 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 = "United States", addl_parents = {"Caribbean"}, divs = {"municipalities"}, }, -- overseas department and region of France ["Réunion"] = { placetype = {"overseas department", "department", "administrative region", "region"}, container = "France", divs = {"communes"}, addl_parents = {"Africa"}, british_spelling = true, }, -- special municipality of the Netherlands ["Saba"] = { placetype = {"special municipality", "municipality", "overseas territory", "territory"}, container = "Netherlands", addl_parents = {"Caribbean"}, is_city = true, british_spelling = true, }, -- overseas collectivity of France ["Saint Barthélemy"] = { placetype = {"overseas collectivity", "collectivity"}, container = "France", addl_parents = {"Caribbean"}, british_spelling = true, }, -- British Overseas Territory ["Saint Helena, Ascension and Tristan da Cunha"] = { placetype = {"overseas territory", "territory"}, container = "United Kingdom", divs = {{type = "constituent parts", container_parent_type = false}}, addl_parents = {"Atlantic Ocean", "Africa"}, 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 = "France", addl_parents = {"Caribbean"}, british_spelling = true, }, -- overseas collectivity of France ["Saint Pierre and Miquelon"] = { placetype = {"overseas collectivity", "collectivity"}, container = "France", divs = {"communes"}, addl_parents = {"North America"}, british_spelling = true, }, -- special municipality of the Netherlands ["Sint Eustatius"] = { placetype = {"special municipality", "municipality", "overseas territory", "territory"}, container = "Netherlands", addl_parents = {"Caribbean"}, is_city = true, british_spelling = true, }, -- constituent country of the Netherlands ["Sint Maarten"] = { placetype = {"constituent country", "country"}, container = "Netherlands", addl_parents = {"Caribbean"}, british_spelling = true, }, -- de-facto independent state, internationally recognized as part of Somalia ["Somaliland"] = { placetype = {"unrecognized country", "country"}, addl_parents = {"Somalia", "Africa"}, 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", "country", "geographic region", "region"}, addl_parents = {"Georgia", "Europe", "Asia"}, keydesc = "the geographic region and 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 = "Norway", addl_parents = {"Europe"}, 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", "country"}, addl_parents = {"Moldova", "Europe"}, keydesc = "the de-facto independent state of [[Transnistria]], internationally recognized as part of [[Moldova]]", british_spelling = true, }, -- British Overseas Territory ["Turks and Caicos Islands"] = { the = true, placetype = {"overseas territory", "territory"}, container = "United Kingdom", addl_parents = {"Caribbean"}, british_spelling = true, }, -- unincorporated territory of the United States ["United States Minor Outlying Islands"] = { the = true, placetype = {"unincorporated territory", "overseas territory", "territory"}, container = "United States", addl_parents = {"Islands", "Micronesia", "Polynesia", "Caribbean"}, }, -- FIXME: We should add entries for the other minor outlying islands. -- Baker Island (Oceania) -- Howland Island (Oceania) -- Jarvis Island (Oceania) -- Johnston Atoll (Oceania) -- Kingman Reef (Oceania) -- Midway Atoll (Oceania) -- Navassa Island (Caribbean) -- Palmyra Atoll (Oceania) -- Wake Island (Oceania) ["Wake Island"] = { placetype = {"unincorporated territory", "overseas territory", "territory"}, container = "United States", addl_parents = {"Micronesia"}, }, -- unincorporated territory of the United States ["United States Virgin Islands"] = { the = true, placetype = {"unincorporated territory", "overseas territory", "territory"}, container = "United States", addl_parents = {"Caribbean"}, }, ["U.S. Virgin Islands"] = {alias_of = "United States Virgin Islands", display = true, the = true}, ["US Virgin Islands"] = {alias_of = "United States Virgin Islands", display = true, the = true}, -- overseas collectivity of France ["Wallis and Futuna"] = { placetype = {"overseas collectivity", "collectivity"}, container = "France", 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, "country"), 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", "country"}, addl_parents = {"Azerbaijan", "Europe", "Asia"}, keydesc = "the former de-facto independent state of [[Artsakh]], internationally recognized as part of [[Azerbaijan]]", british_spelling = true, }, ["Nagorno-Karabakh"] = {alias_of = "Artsakh"}, ["Czechoslovakia"] = {container = "Europe", british_spelling = true}, ["East Germany"] = {container = "Europe", addl_parents = {"Germany"}, british_spelling = true}, ["North Vietnam"] = {container = "Asia", addl_parents = {"Vietnam"}}, ["Persia"] = {placetype = {"empire", "country"}, container = "Asia", divs = {"provinces"}}, ["Byzantine Empire"] = { the = true, placetype = {"empire", "country"}, container = {"Europe", "Africa", "Asia"}, addl_parents = {"Ancient Europe", "Ancient Near East"}, divs = { "provinces", "themes", }}, ["Roman Empire"] = { the = true, placetype = {"empire", "country"}, container = {"Europe", "Africa", "Asia"}, addl_parents = {"Rome"}, divs = { "provinces", {type = "FORMER provinces", cat_as = "provinces"}, }}, ["South Vietnam"] = {container = "Asia", addl_parents = {"Vietnam"}}, ["Soviet Union"] = { the = true, container = {"Europe", "Asia"}, divs = {"republics", "autonomous republics"}, british_spelling = true}, ["West Germany"] = {container = "Europe", addl_parents = {"Germany"}, british_spelling = true}, ["Yugoslavia"] = {container = "Europe", 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 = "country", default_no_container_cat = true, default_no_container_parent = true, -- No need to augment country holonyms with continents; not needed for disambiguation. default_no_auto_augment_container = true, data = export.former_countries, } ----------------------------------------------------------------------------------- -- Subpolity tables -- ----------------------------------------------------------------------------------- export.australia_states_and_territories = { ["Australian Capital Territory, Australia"] = {the = true, placetype = "territory"}, ["Jervis Bay Territory, Australia"] = {the = true, placetype = "territory"}, ["New South Wales, Australia"] = {}, ["Northern Territory, Australia"] = {the = true, placetype = "territory"}, ["Queensland, Australia"] = {}, ["South Australia, Australia"] = {}, ["Tasmania, Australia"] = {}, ["Victoria, Australia"] = {}, ["Western Australia, Australia"] = {}, } -- states and territories of Australia export.australia_group = { default_container = "Australia", default_placetype = "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 = "Austria", 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", the = true}, } -- provinces and territories of Canada export.canada_group = { default_container = "Canada", default_placetype = "province", data = export.canada_provinces_and_territories, } export.china_provinces_and_autonomous_regions = { -- direct-administered municipalities are not here but below under prefecture-level cities ["Anhui, China"] = {}, ["Fujian, China"] = {}, ["Fuchien, China"] = {alias_of = "Fujian, China", display = true}, ["Gansu, China"] = {}, ["Guangdong, China"] = {}, ["Guangxi, China"] = {placetype = "autonomous region"}, ["Guizhou, China"] = {}, ["Hainan, China"] = {}, ["Hebei, China"] = {}, ["Heilongjiang, China"] = {}, ["Henan, China"] = {}, ["Hubei, China"] = {}, ["Hunan, China"] = {}, ["Inner Mongolia, China"] = {placetype = "autonomous region"}, ["Jiangsu, China"] = {}, ["Jiangxi, China"] = {}, ["Jilin, China"] = {}, ["Liaoning, China"] = {}, ["Ningxia, China"] = {placetype = "autonomous region"}, ["Qinghai, China"] = {}, ["Shaanxi, China"] = {}, ["Shandong, China"] = {}, ["Shanxi, China"] = {}, ["Sichuan, China"] = {}, ["Tibet, China"] = {placetype = "autonomous region", wp = "Tibet Autonomous Region"}, ["Xinjiang, China"] = {placetype = "autonomous region"}, ["Yunnan, China"] = {}, ["Zhejiang, China"] = {}, } -- provinces and autonomous regions of China export.china_group = { default_container = "China", default_placetype = "province", default_divs = { "prefectures", "prefecture-level cities", "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", "city"}}, -- 24.9 prefectural, 29.9 urban; 21.910 urban (41.600 adm-urb including Changshu, Changzhou, Suzhou, Wuxi) per citypopulation.de ["Changshu"] = { placetype = "county-level city", container = {key = "Suzhou", placetype = "prefecture-level city"}, divs = {"subdistricts"} }, -- 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", "city"}}, -- 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", "city"}}, -- 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", "city"}}, -- 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"] = {placetype = "county-level city", container = {key = "Wuxi", placetype = "prefecture-level city"}, divs = {"subdistricts", "townships"}}, -- 1.331 urban (3.200 adm-urb including Zhangjiagang) per citypopulation.de ["Zhangjiagang"] = {container = "Jiangsu"}, -- 1.056 urban per citypopulation.de; included in Jiangyin figures ["Xuzhou"] = {container = "Jiangsu"}, -- 9.1 prefectural, 2.6 urban; 2.846 urban (3.150 adm-urb) per citypopulation.de ["Handan"] = {container = "Hebei"}, -- 9.4 prefectural, 2.8 urban; 2.095 urban (2.925 adm-urb) per citypopulation.de ["Hohhot"] = {container = {key = "Inner Mongolia, China", placetype = "autonomous region"}}, -- 3.446 prefectural, 2.7 urban; 2.373 urban (2.850 adm-urb) per citypopulation.de ["Haikou"] = {container = "Hainan"}, -- 2.873 prefectural, 2.3 urban; 2.349 urban (2.800 adm-urb) per citypopulation.de ["Tangshan"] = {container = "Hebei"}, -- 7.7 prefectural, 3.4 urban; 2.550 urban (2.750 adm-urb) per citypopulation.de ["Xinxiang"] = {container = "Henan"}, -- 6.3 prefectural, 1.2 urban, 2.7 metro; 1.271 urban (2.700 adm-urb) per citypopulation.de ["Yiwu"] = {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 = "China", canonicalize_key_container = make_canonicalize_key_container(", China", "province"), -- Prefecture-level cities aren't really cities but allow them to be identified that way, as many people -- don't understand how Chinese administrative divisions work. default_placetype = {"prefecture-level city", "city"}, 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 = "China", canonicalize_key_container = make_canonicalize_key_container(", China", "province"), -- Prefecture-level cities aren't really cities but allow them to be identified that way, as many people -- don't understand how Chinese administrative divisions work. default_placetype = {"prefecture-level city", "city"}, 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 = "Finland", 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 = "France", -- 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", the = true}, -- 69M ["Lyon Metropolis, France"] = {alias_of = "Metropolis of Lyon, France"}, ["Lyon, France"] = {alias_of = "Metropolis of Lyon, France"}, ["Haute-Saône, France"] = {container = "Bourgogne-Franche-Comté"}, -- 70 ["Saône-et-Loire, France"] = {container = "Bourgogne-Franche-Comté"}, -- 71 ["Sarthe, France"] = {container = "Pays de la Loire"}, -- 72 ["Savoie, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 73 ["Haute-Savoie, France"] = {container = "Auvergne-Rhône-Alpes"}, -- 74 ["Paris, France"] = {container = "Île-de-France"}, -- 75 ["Seine-Maritime, France"] = {container = "Normandy"}, -- 76 ["Seine-et-Marne, France"] = {container = "Île-de-France"}, -- 77 ["Yvelines, France"] = {container = "Île-de-France"}, -- 78 ["Deux-Sèvres, France"] = {container = "Nouvelle-Aquitaine"}, -- 79 ["Somme, France"] = {container = "Hauts-de-France", wp = "%l (department)"}, -- 80 ["Tarn, France"] = {container = "Occitania", wp = "%l (department)"}, -- 81 ["Tarn-et-Garonne, France"] = {container = "Occitania"}, -- 82 ["Var, France"] = {container = "Provence-Alpes-Côte d'Azur", wp = "%l (department)"}, -- 83 ["Vaucluse, France"] = {container = "Provence-Alpes-Côte d'Azur"}, -- 84 ["Vendée, France"] = {container = "Pays de la Loire"}, -- 85 ["Vienne, France"] = {container = "Nouvelle-Aquitaine", wp = "%l (department)"}, -- 86 ["Haute-Vienne, France"] = {container = "Nouvelle-Aquitaine"}, -- 87 ["Vosges, France"] = {container = "Grand Est", wp = "%l (department)"}, -- 88 ["Yonne, France"] = {container = "Bourgogne-Franche-Comté"}, -- 89 ["Territoire de Belfort, France"] = {container = "Bourgogne-Franche-Comté"}, -- 90 ["Essonne, France"] = {container = "Île-de-France"}, -- 91 ["Hauts-de-Seine, France"] = {container = "Île-de-France"}, -- 92 ["Seine-Saint-Denis, France"] = {container = "Île-de-France"}, -- 93 ["Val-de-Marne, France"] = {container = "Île-de-France"}, -- 94 ["Val-d'Oise, France"] = {container = "Île-de-France"}, -- 95 --["Guadeloupe"] = {container = "Guadeloupe"}, -- 971 --["Martinique"] = {container = "Martinique"}, -- 972 --["Guyane"] = {container = "French Guiana", wp = "French Guiana"}, -- 973 --["La Réunion"] = {container = "Réunion", wp = "Réunion"}, -- 974 --["Mayotte"] = {container = "Mayotte"}, -- 976 } export.france_departments_group = { placename_to_key = make_placename_to_key(", France"), canonicalize_key_container = make_canonicalize_key_container(", France", "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 = "Germany", 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 = "Greece", 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 = "India", 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 = "Italy", 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 Prefecture, Japan"] = {}, ["Akita Prefecture, Japan"] = {}, ["Aomori Prefecture, Japan"] = {}, ["Chiba Prefecture, Japan"] = {}, ["Ehime Prefecture, Japan"] = {}, ["Fukui Prefecture, Japan"] = {}, ["Fukuoka Prefecture, Japan"] = {}, ["Fukushima Prefecture, Japan"] = {}, ["Gifu Prefecture, Japan"] = {}, ["Gunma Prefecture, Japan"] = {}, ["Hiroshima Prefecture, Japan"] = {}, ["Hokkaido Prefecture, Japan"] = {divs = "subprefectures", wp = "Hokkaido"}, ["Hyōgo Prefecture, Japan"] = {}, ["Hyogo Prefecture, Japan"] = {alias_of = "Hyōgo Prefecture, Japan", display = true}, ["Ibaraki Prefecture, Japan"] = {}, ["Ishikawa Prefecture, Japan"] = {}, ["Iwate Prefecture, Japan"] = {}, ["Kagawa Prefecture, Japan"] = {}, ["Kagoshima Prefecture, Japan"] = {}, ["Kanagawa Prefecture, Japan"] = {}, ["Kōchi Prefecture, Japan"] = {}, ["Kochi Prefecture, Japan"] = {alias_of = "Kōchi Prefecture, Japan", display = true}, ["Kumamoto Prefecture, Japan"] = {}, ["Kyoto Prefecture, Japan"] = {}, ["Mie Prefecture, Japan"] = {}, ["Miyagi Prefecture, Japan"] = {}, ["Miyazaki Prefecture, Japan"] = {}, ["Nagano Prefecture, Japan"] = {}, ["Nagasaki Prefecture, Japan"] = {}, ["Nara Prefecture, Japan"] = {}, ["Niigata Prefecture, Japan"] = {}, ["Ōita Prefecture, Japan"] = {}, ["Oita Prefecture, Japan"] = {alias_of = "Ōita Prefecture, Japan", display = true}, ["Okayama Prefecture, Japan"] = {}, ["Okinawa Prefecture, Japan"] = {}, ["Osaka Prefecture, Japan"] = {}, ["Saga Prefecture, Japan"] = {}, ["Saitama Prefecture, Japan"] = {}, ["Shiga Prefecture, Japan"] = {}, ["Shimane Prefecture, Japan"] = {}, ["Shizuoka Prefecture, Japan"] = {}, ["Tochigi Prefecture, Japan"] = {}, ["Tokushima Prefecture, Japan"] = {}, ["Tottori Prefecture, Japan"] = {}, ["Toyama Prefecture, Japan"] = {}, ["Wakayama Prefecture, Japan"] = {}, ["Yamagata Prefecture, Japan"] = {}, ["Yamaguchi Prefecture, Japan"] = {}, ["Yamanashi Prefecture, Japan"] = {}, } -- prefectures of Japan export.japan_group = { key_to_placename = make_key_to_placename(", Japan$", " Prefecture$"), placename_to_key = make_placename_to_key(", Japan", " Prefecture"), default_container = "Japan", default_placetype = "prefecture", data = export.japan_prefectures, } export.laos_provinces = { ["Attapeu Province, Laos"] = {}, ["Bokeo Province, Laos"] = {}, ["Bolikhamxai Province, Laos"] = {}, ["Champasak Province, Laos"] = {}, ["Houaphanh Province, Laos"] = {}, ["Khammouane Province, Laos"] = {}, ["Luang Namtha Province, Laos"] = {}, ["Luang Prabang Province, Laos"] = {}, ["Oudomxay Province, Laos"] = {}, ["Phongsaly Province, Laos"] = {}, ["Salavan Province, Laos"] = {}, ["Savannakhet Province, Laos"] = {}, ["Vientiane Province, Laos"] = {}, ["Vientiane Prefecture, Laos"] = {placetype = "prefecture", wp = "%l"}, ["Sainyabuli Province, Laos"] = {}, ["Sekong Province, Laos"] = {}, ["Xaisomboun Province, Laos"] = {}, ["Xiangkhouang Province, Laos"] = {}, } local function laos_placename_to_key(placename) if placename == "Vientiane Prefecture" then return placename .. ", Laos" end if placename:find(" Province$") then return placename .. ", Laos" end return placename .. " Province, Laos" end -- provinces of Laos export.laos_group = { key_to_placename = make_key_to_placename(", Laos$", {" Province$", " Prefecture$"}), placename_to_key = laos_placename_to_key, default_container = "Laos", default_placetype = "province", -- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province' default_wp = "%e province", data = export.laos_provinces, } export.lebanon_governorates = { ["Akkar Governorate, Lebanon"] = {}, ["Baalbek-Hermel Governorate, Lebanon"] = {}, ["Beirut Governorate, Lebanon"] = {}, ["Beqaa Governorate, Lebanon"] = {}, ["Keserwan-Jbeil Governorate, Lebanon"] = {}, ["Mount Lebanon Governorate, Lebanon"] = {}, ["Nabatieh Governorate, Lebanon"] = {}, -- These two are generic enough that we don't want to automatically augment a use of `gov/North Governorate` or -- `gov/South Governorate` with `c/Lebanon`. ["North Governorate, Lebanon"] = {no_auto_augment_container = true}, ["South Governorate, Lebanon"] = {no_auto_augment_container = true}, } -- governorates of Lebanon export.lebanon_group = { key_to_placename = make_key_to_placename(", Lebanon$", " Governorate$"), placename_to_key = make_placename_to_key(", Lebanon", " Governorate"), default_container = "Lebanon", default_placetype = "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", the = true}, ["Administrative-Territorial Units of the Left Bank of the Dniester, Moldova"] = {alias_of = "Transnistria, Moldova", the = true}, } local function moldova_placename_to_key(placename) local elliptical_key = placename .. ", Moldova" if export.moldova_districts_and_autonomous_territorial_units[elliptical_key] then return elliptical_key end if placename:find(" District$") then return placename .. ", Moldova" end return placename .. " District, Moldova" end -- Moldovan districts (raions) and autonomous territorial units export.moldova_group = { key_to_placename = make_key_to_placename(", Moldova$", " District"), placename_to_key = moldova_placename_to_key, default_container = "Moldova", default_placetype = {"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 = "Morocco", 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 = "Egypt", 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", "city"}, 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 = "North Korea", default_placetype = "province", data = export.north_korea_provinces, } export.norwegian_counties = { ["Oslo, Norway"] = {}, ["Rogaland, Norway"] = {}, ["Møre og Romsdal, Norway"] = {}, ["Nordland, Norway"] = {}, ["Østfold, Norway"] = {}, ["Akershus, Norway"] = {}, ["Buskerud, Norway"] = {}, -- the following two were merged into Innlandet -- ["Hedmark, Norway"] = {}, -- ["Oppland, Norway"] = {}, ["Innlandet, Norway"] = {}, ["Vestfold, Norway"] = {}, ["Telemark, Norway"] = {}, -- the following two were merged into Agder -- ["Aust-Agder, Norway"] = {}, -- ["Vest-Agder, Norway"] = {}, ["Agder, Norway"] = {}, -- the following two were merged into Vestland -- ["Hordaland, Norway"] = {}, -- ["Sogn og Fjordane, Norway"] = {}, ["Vestland, Norway"] = {}, ["Trøndelag, Norway"] = {}, ["Troms, Norway"] = {}, ["Finnmark, Norway"] = {}, } -- counties of Norway export.norway_group = { default_container = "Norway", default_placetype = "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 = "Poland", 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", the = true}, ["Bashkortostan, Russia"] = russia_republic_no_the, ["Republic of Bashkortostan, Russia"] = {alias_of = "Bashkortostan, Russia", the = true}, ["Bashkiria, Russia"] = {alias_of = "Bashkortostan, Russia"}, ["Buryatia, Russia"] = russia_republic_no_the, ["Republic of Buryatia, Russia"] = {alias_of = "Buryatia, Russia", the = true}, ["Dagestan, Russia"] = russia_republic_no_the, ["Republic of Dagestan, Russia"] = {alias_of = "Dagestan, Russia", the = true}, ["Ingushetia, Russia"] = russia_republic_no_the, ["Republic of Ingushetia, Russia"] = {alias_of = "Ingushetia, Russia", the = true}, ["Kalmykia, Russia"] = russia_republic_no_the, ["Republic of Kalmykia, Russia"] = {alias_of = "Kalmykia, Russia", the = true}, ["Karelia, Russia"] = make_russia_federal_subject_spec("republic", nil, "Republic of Karelia"), ["Republic of Karelia, Russia"] = {alias_of = "Karelia, Russia", the = true}, ["Khakassia, Russia"] = russia_republic_no_the, ["Republic of Khakassia, Russia"] = {alias_of = "Khakassia, Russia", the = true}, ["Mordovia, Russia"] = russia_republic_no_the, ["Republic of Mordovia, Russia"] = {alias_of = "Mordovia, Russia", the = true}, ["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", the = true}, ["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", the = true}, ["Altai Republic, Russia"] = russia_republic_the, ["Chechnya, Russia"] = russia_republic_no_the, ["Chechen Republic, Russia"] = {alias_of = "Chechnya, Russia", the = true}, ["Chuvashia, Russia"] = russia_republic_no_the, ["Chuvash Republic, Russia"] = {alias_of = "Chuvashia, Russia", the = true}, ["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", the = true}, ["Kabardino-Balkar Republic, Russia"] = {alias_of = "Kabardino-Balkaria, Russia", display = "Kabardino-Balkarian Republic, Russia", the = true}, ["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", the = true}, ["Mari El, Russia"] = russia_republic_no_the, ["Mari El Republic, Russia"] = {alias_of = "Mari El, Russia", the = true}, ["Sakha, Russia"] = make_russia_federal_subject_spec("republic", nil, "Sakha Republic"), ["Sakha Republic, Russia"] = {alias_of = "Sakha, Russia", the = true}, ["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", the = true}, ["Tyva Republic, Russia"] = {alias_of = "Tuva, Russia", display= "Tuva Republic, Russia", the = true}, ["Udmurtia, Russia"] = russia_republic_no_the, ["Udmurt Republic, Russia"] = {alias_of = "Udmurtia, Russia", the = true}, -- 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 = "Russia", default_keydesc = construct_russia_federal_subject_keydesc, default_overriding_bare_label_parents = {"federal subjects of Russia", "+++"}, data = export.russia_federal_subjects, } export.saudi_arabia_provinces = { ["Riyadh Province, 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 = "Saudi Arabia", 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 = "South Korea", default_placetype = "province", data = export.south_korea_provinces, } export.spain_autonomous_communities = { ["Andalusia, Spain"] = {}, ["Aragon, Spain"] = {}, ["Asturias, Spain"] = {}, ["Balearic Islands, Spain"] = {the = true}, ["Basque Country, Spain"] = {the = true, wp = "%l (autonomous community)"}, ["Canary Islands, Spain"] = {the = true}, ["Cantabria, Spain"] = {}, ["Castile and León, Spain"] = {}, ["Castilla-La Mancha, Spain"] = {wp = "Castilla–La Mancha"}, -- with en-dash ["Catalonia, Spain"] = {}, ["Community of Madrid, Spain"] = {the = true}, ["Extremadura, Spain"] = {}, ["Galicia, Spain"] = {wp = "%l (Spain)"}, ["La Rioja, Spain"] = {}, ["Murcia, Spain"] = {wp = "Region of %l"}, ["Navarre, Spain"] = {}, ["Valencia, Spain"] = {wp = "Valencian Community"}, ["Valencian Community, Spain"] = {alias_of = "Valencia, Spain", the = true}, } -- autonomous communities of Spain export.spain_group = { default_container = "Spain", default_placetype = "autonomous community", default_divs = {"municipalities", "comarcas"}, data = export.spain_autonomous_communities, } export.taiwan_counties = { ["Changhua County, Taiwan"] = {}, ["Chiayi County, Taiwan"] = {}, ["Hsinchu County, Taiwan"] = {}, ["Hualien County, Taiwan"] = {}, ["Kinmen County, Taiwan"] = {wp = "Kinmen"}, ["Lienchiang County, Taiwan"] = {wp = "Matsu Islands"}, ["Miaoli County, Taiwan"] = {}, ["Nantou County, Taiwan"] = {}, ["Penghu County, Taiwan"] = {wp = "Penghu"}, ["Pingtung County, Taiwan"] = {}, ["Taitung County, Taiwan"] = {}, ["Yilan County, Taiwan"] = {wp = "%l, %c"}, ["Yunlin County, Taiwan"] = {}, } -- counties of Taiwan export.taiwan_group = { key_to_placename = make_key_to_placename(", Taiwan$", " County$"), placename_to_key = make_placename_to_key(", Taiwan", " County"), default_container = "Taiwan", default_placetype = "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 = "Thailand", 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 = "Turkey", 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 = "Ukraine", 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", "country"}, 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", "country"}, 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 = "city"}, ["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 = "city", wp = "%l, %c"}, ["Pembrokeshire, Wales"] = {placetype = "county"}, ["Powys, Wales"] = {placetype = "county"}, ["Rhondda Cynon Taf, Wales"] = {}, -- ["Swansea, Wales"] = {placetype = "city"}, ["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 = "United States", 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 Province, Vietnam"] = {}, -- capital [[Bắc Giang]] ["Bắc Kạn Province, Vietnam"] = {}, -- capital [[Bắc Kạn]] ["Cao Bằng Province, Vietnam"] = {}, -- capital [[Cao Bằng]] ["Hà Giang Province, Vietnam"] = {}, -- capital [[Hà Giang]] ["Lạng Sơn Province, Vietnam"] = {}, -- capital [[Lạng Sơn]] ["Phú Thọ Province, Vietnam"] = {}, -- capital [[Việt Trì]] ["Quảng Ninh Province, Vietnam"] = {}, -- capital [[Hạ Long]] ["Thái Nguyên Province, Vietnam"] = {}, -- capital [[Thái Nguyên]] ["Tuyên Quang Province, Vietnam"] = {}, -- capital [[Tuyên Quang]] -- [[Northwest (Vietnam)|Northwest]] region ["Lào Cai Province, Vietnam"] = {}, -- capital [[Lào Cai]] ["Yên Bái Province, Vietnam"] = {}, -- capital [[Yên Bái]] ["Điện Biên Province, Vietnam"] = {}, -- capital [[Điện Biên Phủ]] ["Hoà Bình Province, Vietnam"] = {}, -- capital [[Hoà Bình City|Hoà Bình]] ["Hòa Bình Province, Vietnam"] = {alias_of = "Hoà Bình Province, Vietnam", display = true}, ["Lai Châu Province, Vietnam"] = {}, -- capital [[Lai Châu]] ["Sơn La Province, Vietnam"] = {}, -- capital [[Sơn La]] -- [[Red River Delta]] region ["Bắc Ninh Province, Vietnam"] = {}, -- capital [[Bắc Ninh]] ["Hà Nam Province, Vietnam"] = {}, -- capital [[Phủ Lý]] ["Hải Dương Province, Vietnam"] = {}, -- capital [[Hải Dương]] ["Hưng Yên Province, Vietnam"] = {}, -- capital [[Hưng Yên]] ["Nam Định Province, Vietnam"] = {}, -- capital [[Nam Định]] ["Ninh Bình Province, Vietnam"] = {}, -- capital [[Ninh Bình|Hoa Lư]] ["Thái Bình Province, Vietnam"] = {}, -- capital [[Thái Bình]] ["Vĩnh Phúc Province, Vietnam"] = {}, -- capital [[Vĩnh Yên]] -- ["Hanoi"] = {placetype = {"municipality", "city"}}, -- capital [[Hoàn Kiếm district]] -- ["Haiphong"] = {placetype = {"municipality", "city"}}, -- capital [[Hồng Bàng district]] -- [[North Central Coast]] region ["Hà Tĩnh Province, Vietnam"] = {}, -- capital [[Hà Tĩnh]] ["Nghệ An Province, Vietnam"] = {}, -- capital [[Vinh]] ["Quảng Bình Province, Vietnam"] = {}, -- capital [[Đồng Hới]] ["Quảng Trị Province, Vietnam"] = {}, -- capital [[Đông Hà]] ["Thanh Hoá Province, Vietnam"] = {}, -- capital [[Thanh Hoá]] ["Thanh Hóa Province, Vietnam"] = {alias_of = "Thanh Hoá Province, Vietnam", display = true}, -- ["Hue"] = {placetype = {"municipality", "city"}, wp = "Huế"}, -- capital [[Thuận Hoá district]] -- [[Central Highlands (Vietnam)|Central Highlands]] region ["Đắk Lắk Province, Vietnam"] = {}, -- capital [[Buôn Ma Thuột]] ["Đăk Nông Province, Vietnam"] = {}, -- capital [[Gia Nghĩa]] ["Gia Lai Province, Vietnam"] = {}, -- capital [[Pleiku]] ["Kon Tum Province, Vietnam"] = {}, -- capital [[Kon Tum]] ["Lâm Đồng Province, Vietnam"] = {}, -- capital [[Đà Lạt]] -- [[South Central Coast]] region ["Bình Định Province, Vietnam"] = {}, -- capital [[Quy Nhon]] ["Bình Thuận Province, Vietnam"] = {}, -- capital [[Phan Thiết]] ["Khánh Hoà Province, Vietnam"] = {}, -- capital [[Nha Trang]] ["Khánh Hòa Province, Vietnam"] = {alias_of = "Khánh Hoà Province, Vietnam", display = true}, ["Ninh Thuận Province, Vietnam"] = {}, -- capital [[Phan Rang–Tháp Chàm]] ["Phú Yên Province, Vietnam"] = {}, -- capital [[Tuy Hoà]] ["Quảng Nam Province, Vietnam"] = {}, -- capital [[Tam Kỳ]] ["Quảng Ngãi Province, Vietnam"] = {}, -- capital [[Quảng Ngãi]] -- ["Da Nang"] = {placetype = {"municipality", "city"}}, -- capital [[Hải Châu district]] -- [[Southeast (Vietnam)|Southeast]] region ["Bà Rịa–Vũng Tàu Province, Vietnam"] = {}, -- capital [[Bà Rịa]] ["Bình Dương Province, Vietnam"] = {}, -- capital [[Thủ Dầu Một]] ["Bình Phước Province, Vietnam"] = {}, -- capital [[Đồng Xoài]] ["Đồng Nai Province, Vietnam"] = {}, -- capital [[Biên Hoà]] ["Tây Ninh Province, Vietnam"] = {}, -- capital [[Tây Ninh]] -- ["Ho Chi Minh City"] = {placetype = {"municipality", "city"}}, -- capital [[District 1, Ho Chi Minh City|'''District 1''']] -- [[Mekong Delta]] region ["An Giang Province, Vietnam"] = {}, -- capital [[Long Xuyên]] ["Bạc Liêu Province, Vietnam"] = {}, -- capital [[Bạc Liêu]] ["Bến Tre Province, Vietnam"] = {}, -- capital [[Bến Tre]] ["Cà Mau Province, Vietnam"] = {}, -- capital [[Cà Mau]] ["Đồng Tháp Province, Vietnam"] = {}, -- capital [[Cao Lãnh City|Cao Lãnh]] ["Hậu Giang Province, Vietnam"] = {}, -- capital [[Vị Thanh]] ["Kiên Giang Province, Vietnam"] = {}, -- capital [[Rạch Giá]] ["Long An Province, Vietnam"] = {}, -- capital [[Tân An]] ["Sóc Trăng Province, Vietnam"] = {}, -- capital [[Sóc Trăng]] ["Tiền Giang Province, Vietnam"] = {}, -- capital [[Mỹ Tho]] ["Trà Vinh Province, Vietnam"] = {}, -- capital [[Trà Vinh]] ["Vĩnh Long Province, Vietnam"] = {}, -- capital [[Vĩnh Long]] -- ["Can Tho"] = {placetype = {"municipality", "city"}, wp = "Cần Thơ"}, -- capital [[Ninh Kiều district]] } -- provinces of Vietnam export.vietnam_group = { key_to_placename = make_key_to_placename(", Vietnam$", " Province$"), placename_to_key = make_placename_to_key(", Vietnam", " Province"), default_container = "Vietnam", default_placetype = "province", -- There may not be enough districts to subcategorize like this. -- default_divs = "districts", -- For obscure reasons, provinces of Iran, Laos, Thailand and Vietnam use lowercase 'province' default_wp = "%e province", data = export.vietnam_provinces, } ----------------------------------------------------------------------------------- -- City data -- ----------------------------------------------------------------------------------- export.australia_cities = { ["Adelaide"] = {container = "South Australia"}, -- 1,450,000 (Agglomeration) ["Brisbane"] = {container = "Queensland"}, -- 3,450,000 (Conglomeration; including the Gold Coast [750,997 2024 estiamte]) ["Canberra"] = {container = {key = "Australian Capital Territory, Australia", placetype = "territory"}}, -- 510,641 (2024 estimate) ["Melbourne"] = {container = "Victoria"}, -- 5,200,000 (Agglomeration) ["Newcastle, New South Wales"] = {container = "New South Wales", wp = "%l, %c"}, -- 534,033 (2024 estimate) ["Newcastle"] = {alias_of = "Newcastle, New South Wales"}, ["Perth"] = {container = "Western Australia"}, -- 2,350,000 (Agglomeration) ["Sydney"] = {container = "New South Wales"}, -- 5,100,000 (Agglomeration) } export.australia_cities_group = { canonicalize_key_container = make_canonicalize_key_container(", Australia", "state"), default_placetype = "city", 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 = "city", 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 = "city", 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 = "city", data = export.france_cities, } export.germany_cities = { -- Figures from citypopulation.de unless otherwise indicated; retrieved 2025-04-26; reference date 2025-01-01. -- listed under Rhein-Ruhr Area, total population 10,900,000 (Consolidated Urban Area) ["Cologne"] = {container = "North Rhine-Westphalia"}, ["Köln"] = {alias_of = "Cologne", display = true}, ["Düsseldorf"] = {container = "North Rhine-Westphalia"}, ["Dusseldorf"] = {alias_of = "Düsseldorf", display = true}, ["Dortmund"] = {container = "North Rhine-Westphalia"}, ["Essen"] = {container = "North Rhine-Westphalia"}, ["Duisberg"] = {container = "North Rhine-Westphalia"}, ["Berlin"] = {}, -- 4,700,000 ["Frankfurt"] = {container = "Hesse"}, -- 3,225,000 ["Frankfurt am Main"] = {alias_of = "Frankfurt"}, -- not a display alias as it's longer ["Hamburg"] = {}, -- 2,900,000 ["Munich"] = {container = "Bavaria"}, -- 2,300,000 ["Stuttgart"] = {container = "Baden-Württemberg"}, -- 2,300,000 ["Mannheim"] = {container = "Baden-Württemberg"}, -- 1,550,000 ["Nuremberg"] = {container = "Bavaria"}, -- 1,120,000 ["Hanover"] = {"Lower Saxony"}, -- 1,090,000 ["Bielefeld"] = {container = "North Rhine-Westphalia"}, -- 1,080,000 ["Leipzig"] = {container = "Saxony"}, -- 1,080,000 ["Aachen"] = {container = "North Rhine-Westphalia"}, -- 1,000,000 ["Aix-la-Chapelle"] = {alias_of = "Aachen"}, -- historical; not a display alias ["Bremen"] = {}, } export.germany_cities_group = { default_container = "Germany", canonicalize_key_container = make_canonicalize_key_container(", Germany", "state"), default_placetype = "city", 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 = "city", 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 = "city", 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 = "city", 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 = {"city", "prefecture"}, divs = { {type = "special wards", container_parent_type = false}, {type = "cities", prep = "in"}, }, }, ["Yokohama"] = {container = "Kanagawa"}, -- 3,697,894 ["Osaka"] = {container = "Osaka"}, -- 2,668,586 ["Nagoya"] = {container = "Aichi"}, -- 2,283,289 -- FIXME, Hokkaido is handled specially. ["Sapporo"] = {container = "Hokkaido"}, -- 1,918,096 ["Fukuoka"] = {container = "Fukuoka"}, -- 1,581,527 ["Kobe"] = {container = "Hyōgo"}, -- 1,530,847 ["Kyoto"] = {container = "Kyoto"}, -- 1,474,570 ["Kawasaki"] = {container = "Kanagawa", wp = "%l, Kanagawa"}, -- 1,373,630 ["Saitama"] = {container = "Saitama", wp = "%l (city)", commonscat = "%l, %c"}, -- 1,192,418 ["Hiroshima"] = {container = "Hiroshima"}, -- 1,163,806 ["Sendai"] = {container = "Miyagi"}, -- 1,029,552 -- the remaining cities are considered "central cities" in a 1,000,000+ metro area -- (sometimes there is more than one central city in the area). ["Kitakyushu"] = {container = "Fukuoka"}, -- 986,998 ["Chiba"] = {container = "Chiba", wp = "%l (city)", commonscat = "%l, %c"}, -- 938,695 ["Sakai"] = {container = "Osaka"}, -- 835,333 ["Niigata"] = {container = "Niigata", wp = "%l (city)", commonscat = "%l, %c"}, -- 813,053 ["Hamamatsu"] = {container = "Shizuoka"}, -- 811,431 ["Shizuoka"] = {container = "Shizuoka", wp = "%l (city)", commonscat = "%l, %c"}, -- 710,944 ["Sagamihara"] = {container = "Kanagawa"}, -- 706,342 ["Okayama"] = {container = "Okayama"}, -- 701,293 ["Kumamoto"] = {container = "Kumamoto"}, -- 670,348 ["Kagoshima"] = {container = "Kagoshima"}, -- 605,196 -- skipped 6 cities (Funabashi, Hachiōji, Kawaguchi, Himeji, Matsuyama, Higashiōsaka) -- with population in the range 509k - 587k because not central cities in any -- 1,000,000+ metro area. ["Utsunomiya"] = {container = "Tochigi"}, -- 507,833 } export.japan_cities_group = { default_container = "Japan", canonicalize_key_container = make_canonicalize_key_container(" Prefecture, Japan", "prefecture"), default_placetype = "city", 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 = "city", 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 = "city", 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 = "city", 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 = "city", data = export.philippines_cities, } export.russia_cities = { -- Figures from citypopulation.de; retrieved 2025-04-26; reference date 2025-01-01. ["Moscow"] = {}, -- 18,800,000 (Agglomeration) ["Saint Petersburg"] = {}, -- 6,350,000 (Agglomeration) ["Novosibirsk"] = {container = "Novosibirsk Oblast"}, -- 1,820,000 (Agglomeration) ["Yekaterinburg"] = {container = "Sverdlovsk Oblast"}, -- 1,810,000 (Agglomeration) ["Nizhny Novgorod"] = {container = "Nizhny Novgorod Oblast"}, -- 1,620,000 (Agglomeration) ["Kazan"] = {container = {key = "Tatarstan, Russia", placetype = "republic"}}, -- 1,560,000 (Agglomeration) ["Chelyabinsk"] = {container = "Chelyabinsk Oblast"}, -- 1,430,000 (Agglomeration) ["Rostov-on-Don"] = {container = "Rostov Oblast"}, -- 1,390,000 (Agglomeration) ["Rostov-na-Donu"] = {alias_of = "Rostov-on-Don", display = true}, ["Krasnodar"] = {container = {key = "Krasnodar Krai, Russia", placetype = "krai"}}, -- 1,370,000 (Agglomeration) ["Samara"] = {container = "Samara Oblast"}, -- 1,350,000 (Agglomeration) ["Krasnoyarsk"] = {container = {key = "Krasnoyarsk Krai, Russia", placetype = "krai"}}, -- 1,270,000 (Agglomeration) ["Ufa"] = {container = {key = "Bashkortostan, Russia", placetype = "republic"}}, -- 1,230,000 (Agglomeration) ["Saratov"] = {container = "Saratov Oblast"}, -- 1,170,000 (Agglomeration) ["Omsk"] = {container = "Omsk Oblast"}, -- 1,140,000 (Agglomeration) ["Voronezh"] = {container = "Voronezh Oblast"}, -- 1,130,000 (Agglomeration) ["Volgograd"] = {container = "Volgograd Oblast"}, -- 1,080,000 (Agglomeration) ["Perm"] = {container = {key = "Perm Krai, Russia", placetype = "krai"}, wp = "%l, Russia"}, -- 1,070,000 (Agglomeration) } export.russia_cities_group = { canonicalize_key_container = make_canonicalize_key_container(", Russia", "oblast"), default_container = "Russia", default_placetype = "city", 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 = "city", data = export.saudi_arabia_cities, } export.south_korea_cities = { -- All cities listed are not associated with any county. ["Seoul"] = {}, ["Busan"] = {}, ["Incheon"] = {}, ["Daegu"] = {}, ["Daejeon"] = {}, ["Gwangju"] = {}, ["Ulsan"] = {}, } export.south_korea_cities_group = { default_container = "South Korea", canonicalize_key_container = make_canonicalize_key_container(" County, South Korea", "province"), default_placetype = "city", 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 = "city", data = export.spain_cities, } export.taiwan_cities = { ["New Taipei City"] = {}, ["New Taipei"] = {alias_of = "New Taipei City", display = true}, ["Taichung"] = {}, ["Kaohsiung"] = {wp = "%l, Taiwan"}, ["Taipei"] = {}, ["Taoyuan"] = {}, ["Tainan"] = {}, -- these last three are not special municipalities ["Chiayi"] = {placetype = "city"}, ["Hsinchu"] = {placetype = "city"}, ["Keelung"] = {placetype = "city"}, } 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 = "Taiwan", default_placetype = {"special municipality", "municipality", "city"}, 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 = "city", 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 = "United States", canonicalize_key_container = make_canonicalize_key_container(", USA", "state"), default_placetype = "city", 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 = "city"}, default_placetype = "borough", default_is_city = true, data = export.new_york_boroughs, } export.vietnam_cities = { -- Figures from citypopulation.de (retrieved 2025-04-26; reference date 2025-01-01) unless otherwise indicated. ["Ho Chi Minh City"] = {}, -- 14,300,000 (Agglomeration; inclunding Bien Hoa) ["Saigon"] = {alias_of = "Ho Chi Minh City"}, ["Hanoi"] = {}, -- 7,350,000 (Agglomeration) ["Da Nang"] = {}, -- 1,500,000 (Agglomeration) ["Danang"] = {alias_of = "Da Nang", display = true}, ["Haiphong"] = {}, -- 1,450,000 (Agglomeration) ["Hai Phong"] = {alias_of = "Haiphong", display = true}, -- This is the one entry in this list that is not a province-level municipality; instead it's a "provincial city" -- meaning it is directly under its province as opposed to being contained in a district. ["Bien Hoa"] = {placetype = "city", container = "Đồng Nai", wp = "Biên Hòa"}, -- 1,272,235 (2022 city population per Wikipedia) ["Biên Hòa"] = {alias_of = "Bien Hoa", display = true}, ["Biên Hoà"] = {alias_of = "Bien Hoa", display = true}, -- These two not in citypopulation.de because the urban population may be slightly under 1,000,000, but they are -- both province-level municipalities and close to the 1,000,000 mark. ["Can Tho"] = {wp = "Cần Thơ"}, -- 1,456,000 municipality (2019 census), 994,704 urban (2022 General Statistics Office of Vietnam estimate); capital [[Ninh Kiều district]] ["Cần Thơ"] = {alias_of = "Can Tho", display = true}, ["Hue"] = {wp = "Huế"}, -- 1,257,000 municipality (2019 census), 840,000 urban (2022 General Statistics Office of Vietnam estimate); -- capital [[Thuận Hóa district]] ["Huế"] = {alias_of = "Hue", display = true}, } export.vietnam_cities_group = { placename_to_key = false, -- don't add ", Vietnam" to make the key default_container = "Vietnam", canonicalize_key_container = make_canonicalize_key_container(" Province, Vietnam", "province"), -- Most of the cities listed are province-level municipalities in addition, which contain a certain amount of -- rural territory surrounding the city, but not enough to separate the municipality from the city as distinct -- known locations. default_placetype = {"municipality", "city"}, 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 = "Egypt"}, -- 22,800,000 (Agglomeration, including Giza and Subhra El Kheima) ["Alexandria"] = {container = "Egypt"}, -- 6,250,000 (Agglomeration) ["Giza"] = {container = "Egypt"}, -- 4,458,135 (2023 from citypopulation.de) ["Shubra El Kheima"] = {container = "Egypt"}, -- 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 = "Ivory Coast"}, -- 7,050,000 (Agglomeration) ["Nairobi"] = {container = "Kenya"}, -- 6,900,000 (unindicated) ["Mombasa"] = {container = "Kenya"}, -- 1,370,000 (City) ["Monrovia"] = {container = "Liberia"}, -- 1,940,000 (Urban Area) ["Tripoli"] = {container = "Libya", wp = "%l, %c"}, -- 1,870,000 (unindicated) ["Antananarivo"] = {container = "Madagascar"}, -- 3,150,000 (Agglomeration) ["Lilongwe"] = {container = "Malawi"}, -- 1,210,000 (City) ["Bamako"] = {container = "Mali"}, -- 5,700,000 (Agglomeration) ["Nouakchott"] = {container = "Mauritania"}, -- 1,500,000 (City) ["Casablanca"] = {container = {key = "Casablanca-Settat, Morocco", placetype = "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 = "Cambodia"}, -- 2,925,000 (Agglomeration) ["Tehran"] = {container = {key = "Tehran Province, Iran", placetype = "province"}}, -- 16,800,000 (Agglomeration) ["Teheran"] = {alias_of = "Tehran", display = true}, ["Mashhad"] = {container = {key = "Razavi Khorasan Province, Iran", placetype = "province"}}, -- 3,475,000 (Agglomeration) ["Mashad"] = {alias_of = "Mashhad", display = true}, ["Meshhed"] = {alias_of = "Mashhad", display = true}, ["Meshed"] = {alias_of = "Mashhad", display = true}, ["Isfahan"] = {container = {key = "Isfahan Province, Iran", placetype = "province"}}, -- 3,425,000 (Agglomeration) ["Esfahan"] = {alias_of = "Isfahan", display = true}, ["Tabriz"] = {container = {key = "East Azerbaijan Province, Iran", placetype = "province"}}, -- 1,970,000 (Agglomeration) ["Shiraz"] = {container = {key = "Fars Province, Iran", placetype = "province"}}, -- 1,950,000 (Agglomeration) ["Ahvaz"] = {container = {key = "Khuzestan Province, Iran", placetype = "province"}}, -- 1,550,000 (Agglomeration) ["Qom"] = {container = {key = "Qom Province, Iran", placetype = "province"}}, -- 1,450,000 (City) ["Kermanshah"] = {container = {key = "Kermanshah Province, Iran", placetype = "province"}}, -- 1,130,000 (City) ["Baghdad"] = {container = "Iraq"}, -- 7,800,000 (Administrative Area (urban population)) ["Basra"] = {container = "Iraq"}, -- 1,710,000 (Administrative Area (urban population)) ["Mosul"] = {container = "Iraq"}, -- 1,550,000 (Administrative Area (urban population)) ["Erbil"] = {container = "Iraq"}, -- 1,220,000 (Administrative Area (urban population)) ["Kirkuk"] = {container = "Iraq"}, -- 1,160,000 (Administrative Area (urban population)) ["Najaf"] = {container = "Iraq"}, -- 1,050,000 (Administrative Area (urban population)) ["Tel Aviv"] = {container = "Israel"}, -- 3,000,000 (Agglomeration) -- Jerusalem is not recognized internationally as part of either Israel or Palestine, but as a -- [[w:corpus separatum]], so put the container as "Asia" and list Israel and Palestine as additional parents for -- categorization purposes. ["Jerusalem"] = {container = {key = "Asia", placetype = "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 = "Mongolia"}, -- 1,610,000 (City) ["Ulan Bator"] = {alias_of = "Ulaanbaatar", display = true}, ["Yangon"] = {container = "Myanmar"}, -- 5,650,000 (Municipality (urban population)) ["Rangoon"] = {alias_of = "Yangon", display = true}, ["Mandalay"] = {container = "Myanmar"}, -- 1,600,000 (Municipality (urban population)) ["Kathmandu"] = {container = "Nepal"}, -- 3,175,000 (Agglomeration) -- Pyongyang is a directly governed city, not in any province ["Pyongyang"] = {container = "North Korea"}, -- 3,025,000 (Administrative Area (urban population)) ["Muscat"] = {container = "Oman"}, -- 1,620,000 (Agglomeration) ["Gaza"] = {container = "Palestine", wp = "Gaza City"}, -- 2,275,000 (unindicated) ["Gaza City"] = {alias_of = "Gaza"}, ["Doha"] = {container = "Qatar"}, -- 2,650,000 (Agglomeration) ["Colombo"] = {container = "Sri Lanka"}, -- 4,975,000 (unindicated) ["Damascus"] = {container = "Syria"}, -- 3,975,000 (unindicated; population of low reliability) ["Aleppo"] = {container = "Syria"}, -- 1,980,000 (unindicated; population of low reliability) ["Dushanbe"] = {container = "Tajikistan"}, -- 1,270,000 (City) ["Bangkok"] = {container = "Thailand"}, -- 21,800,000 (Agglomeration) -- Chiang Mai not in citypopulation.de, but 1,198,000 urban population in 2021 per Wikipedia -- [[w:List_of_municipalities_in_Thailand#Largest_cities_by_urban_population]] ["Chiang Mai"] = {container = {key = "Chiang Mai Province, Thailand", placetype = "province"}}, ["Chonburi"] = {container = {key = "Chonburi Province, Thailand", placetype = "province"}}, -- 1,570,000 (Agglomeration; including Pattaya) -- metro area population stats from https://www.statista.com/statistics/255483/biggest-cities-in-turkey/ as of 2021; -- second source is citypopulation.de reference date 2025-01-01. ["Istanbul"] = {placetype = {"city", "province"}, divs = {"districts"}, container = "Turkey"}, -- 15.2 million; 16,000,000 (Agglomeration) ["İstanbul"] = {alias_of = "Istanbul", display = true}, ["Ankara"] = {container = {key = "Ankara Province, Turkey", placetype = "province"}}, -- 5.15 million; 5,200,000 (Agglomeration) ["Izmir"] = {container = {key = "İzmir Province, Turkey", placetype = "province"}, wp = "İzmir"}, -- 2.95 million; 3,025,000 (Agglomeration) ["İzmir"] = {alias_of = "Izmir", display = true}, ["Bursa"] = {container = {key = "Bursa Province, Turkey", placetype = "province"}}, -- 2.02 million; 2,200,000 (Agglomeration) ["Adana"] = {container = {key = "Adana Province, Turkey", placetype = "province"}}, -- 1.77 million; 1,780,000 (Agglomeration) ["Gaziantep"] = {container = {key = "Gaziantep Province, Turkey", placetype = "province"}}, -- 1.71 million; 1,750,000 (Agglomeration) ["Antalya"] = {container = {key = "Antalya Province, Turkey", placetype = "province"}}, -- 1.3 million; 1,400,000 (Agglomeration) ["Konya"] = {container = {key = "Konya Province, Turkey", placetype = "province"}}, -- 1.35 million; 1,390,000 (Agglomeration) ["Diyarbakır"] = {container = {key = "Diyarbakır Province, Turkey", placetype = "province"}}, -- 1.07 million; 1,100,000 (Agglomeration) -- Diyarbakır is more common per Ngrams and Google Scholar, but Diyarbakir is the Kurdish form, so we should not -- display-canonicalize to the Turkish form Diyarbakır. ["Diyarbakir"] = {alias_of = "Diyarbakır"}, ["Mersin"] = {container = {key = "Mersin Province, Turkey", placetype = "province"}}, -- 1.03 million; 1,060,000 (Agglomeration) ["Ashgabat"] = {container = "Turkmenistan"}, -- 1,150,000 (Agglomeration) ["Dubai"] = {container = "United Arab Emirates"}, -- 6,050,000 (Agglomeration; including Sharjah) ["Abu Dhabi"] = {container = "United Arab Emirates"}, -- 1,850,000 (City) ["Sharjah"] = {container = "United Arab Emirates"}, -- 1,800,000 (Metro area 2022-2023 per Wikipedia; separate from Dubai) ["Tashkent"] = {container = "Uzbekistan"}, -- 3,850,000 (unindicated) ["Sanaa"] = {container = "Yemen"}, -- 3,275,000 (City; population of low reliability) ["Sana'a"] = {alias_of = "Sanaa", display = true}, ["Aden"] = {container = "Yemen"}, -- 1,079,060 (?; 2023 estimate from World Population Review per Wikipedia) ------------------ Europe or Europe-like (Caucasus etc.) --------------------- ["Yerevan"] = {container = "Armenia"}, -- 1,520,000 (Agglomeration) ["Vienna"] = {container = "Austria"}, -- 2,375,000 (Agglomeration) ["Minsk"] = {container = "Belarus"}, -- 2,100,000 (unindicated) ["Brussels"] = {container = "Belgium"}, -- 2,800,000 (Consolidated Urban Area) ["Antwerp"] = {container = "Belgium"}, -- 1,270,000 (Consolidated Urban Area) ["Sofia"] = {container = "Bulgaria"}, -- 1,260,000 (Agglomeration) ["Zagreb"] = {container = "Croatia"}, ["Prague"] = {container = "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 = "Denmark"}, -- 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 = "Greece"}, ["Thessaloniki"] = {container = "Greece"}, ["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 = "Sweden"}, ["Zurich"] = {container = "Switzerland"}, --- Ngrams (up through 2022) and Google Scholar (>= 2024) confirms the common form "Zurich" without umlaut. --- Even Wikipedia uses the form without umlaut. ["Zürich"] = {alias_of = "Zurich", display = true}, ["Kyiv"] = {container = "Ukraine"}, -- not in Kyiv Oblast -- Don't display-canonicalize Kiev -> Kyiv because in ancient contexts, Kiev is still more common. ["Kiev"] = {alias_of = "Kyiv"}, ["Kharkiv"] = {container = {key = "Kharkiv Oblast, Ukraine", placetype = "oblast"}}, ["Odessa"] = {container = {key = "Odesa Oblast, Ukraine", placetype = "oblast"}, wp = "Odesa"}, -- Don't display-canonicalize Odesa -> Odessa because it may be interpreted as a political statement. ["Odesa"] = {alias_of = "Odessa"}, ------------------ North America, South America --------------------- -- Primary figures from citypopulation.de retrieved on 2025-04-26 (reference date 2025-01-01); -- Wikipedia metropolitan figures from [[w:List of metropolitan areas in the Americas]] based on per-country data; -- Wikipedia city limits figures from [[w:List of largest cities in the Americas]]. ["Buenos Aires"] = {container = "Argentina"}, -- 16,800,000 (Consolidated Urban Area; 13,985,794 metropolitan area per Wikipedia) ["Córdoba, Argentina"] = {container = "Argentina", wp = "%l, %c"}, -- 1,810,000 (Consolidated Urban Area; 1,505,25 city limits per Wikipedia) -- to avoid confusion with Córdoba in Spain ["Córdoba"] = {alias_of = "Córdoba, Argentina"}, ["Cordoba"] = {alias_of = "Córdoba, Argentina", display = "Córdoba"}, ["Rosario"] = {container = "Argentina", wp = "%l, Santa Fe"}, -- 1,510,000 (Consolidated Urban Area; 1,348,725 metropolitan area per Wikipedia) ["Mendoza"] = {container = "Argentina", wp = "%l, %c"}, -- 1,180,000 (Consolidated Urban Area) ["San Miguel de Tucumán"] = {container = "Argentina"}, -- 1,110,000 (Consolidated Urban Area) ["Tucumán"] = {alias_of = "San Miguel de Tucumán"}, ["Tucuman"] = {alias_of = "San Miguel de Tucumán", display = "Tucumán"}, ["Santa Cruz de la Sierra"] = {container = "Bolivia"}, -- 1,960,000 (Consolidated Urban Area); 1,606,671 (city limits per Wikipedia) ["Santa Cruz"] = {alias_of = "Santa Cruz de la Sierra"}, ["La Paz"] = {container = "Bolivia"}, -- 1,870,000 (Consolidated Urban Area; composed of El Alto, now slightly larger, and La Paz) ["El Alto"] = {container = "Bolivia"}, ["Cochabamba"] = {container = "Bolivia"}, -- 1,280,000 (Consolidated Urban Area) ["Santiago"] = {container = "Chile"}, -- 8,400,000 (Consolidated Urban Area; 6,903,479 city limits? per Wikipedia) ["Valparaíso"] = {container = "Chile"}, -- 1,060,000 (Consolidated Urban Area) ["Valparaiso"] = {alias_of = "Valparaíso"}, -- 1,060,000 (Consolidated Urban Area) ["Bogotá"] = {container = "Colombia"}, -- 10,600,000 (Agglomeration; 12,772,828 metropolitan area per Wikipedia) ["Bogota"] = {alias_of = "Bogotá", display = true}, ["Medellín"] = {container = "Colombia"}, -- 4,350,000 (Agglomeration; 4,068,000 metropolitan area per Wikipedia) ["Medellin"] = {alias_of = "Medellín", display = true}, ["Cali"] = {container = "Colombia"}, -- 2,975,000 (Agglomeration; 2,837,000 metropolitan area per Wikipedia) ["Barranquilla"] = {container = "Colombia"}, -- 2,375,000 (Agglomeration; 1,341,160 city limits per Wikipedia) ["Bucaramanga"] = {container = "Colombia"}, -- 1,380,000 (Agglomeration) ["Cartagena, Colombia"] = {container = "Colombia", wp = "%l, %c"}, -- 1,250,000 (Agglomeration) -- to avoid confusion with Cartagena, Spain ["Cartagena"] = {alias_of = "Cartagena, Colombia"}, ["Cúcuta"] = {container = "Colombia"}, -- 1,130,000 (Agglomeration) ["Cucuta"] = {alias_of = "Cúcuta", display = true}, -- to avoid conflict with San Jose, California ["San José, Costa Rica"] = {container = "Costa Rica", wp = "%l, %c"}, -- 2,450,000 (Municipality (urban population); 3,160,000 metropolitan area per Wikipedia) ["San José"] = {alias_of = "San José, Costa Rica"}, ["San Jose"] = {alias_of = "San José, Costa Rica"}, -- display = "San José"; causes error due to San Jose alias for California city; FIXME ["Havana"] = {container = "Cuba"}, -- 2,150,000 (City; 2,137,847 city limits? per Wikipedia) ["Santo Domingo"] = {container = "Dominican Republic"}, -- 3,900,000 (Municipality (urban population); 4,274,651 ??? per Wikipedia) ["Guayaquil"] = {container = "Ecuador"}, -- 3,350,000 (Agglomeration; 3,092,000 metro area? per Wikipedia) ["Quito"] = {container = "Ecuador"}, -- 2,875,000 (Agglomeration; 2,889,703 metro area? per Wikipedia) ["San Salvador"] = {container = "El Salvador"}, -- 1,580,000 (Municipality (urban population)) ["Guatemala City"] = {container = "Guatemala"}, -- 3,375,000 (Municipality (urban population); 3,160,000 metro area? per Wikipedia) ["Port-au-Prince"] = {container = "Haiti"}, -- 3,050,000 (Agglomeration; population of low reliability; 2,915,000 metro area? per Wikipedia) ["San Pedro Sula"] = {container = "Honduras"}, -- 1,330,000 (Consolidated Urban Area) ["Tegucigalpa"] = {container = "Honduras"}, -- 1,220,000 (Urban Area) ["Managua"] = {container = "Nicaragua"}, -- 1,400,000 (Consolidated Urban Area) ["Panama City"] = {container = "Panama"}, -- 1,430,000 (Urban Area) ["Asunción"] = {container = "Paraguay"}, -- 2,350,000 (Municipality (urban population)) ["Lima"] = {container = "Peru"}, -- 12,000,000 (Agglomeration; 11,283,787 ??? per Wikipedia) ["Arequipa"] = {container = "Peru"}, -- 1,210,000 (Agglomeration) ["San Juan"] = {container = {key = "Puerto Rico", placetype = "commonwealth"}, wp = "%l, %c"}, -- 1,910,000 (Consolidated Urban Area) ["Montevideo"] = {container = "Uruguay"}, -- 1,810,000 (Agglomeration; 1,302,954 ??? per Wikipedia) ["Caracas"] = {container = "Venezuela"}, -- 3,850,000 (Consolidated Urban Area; 5,243,301 ??? per Wikipedia) ["Maracaibo"] = {container = "Venezuela"}, -- 2,825,000 (Consolidated Urban Area; 5,278,448 ??? per Wikipedia) -- to avoid confusion with Valencia (city and autonomous community of Spain) ["Valencia, Venezuela"] = {container = "Venezuela", wp = "%l, %c"}, -- 2,100,000 (Consolidated Urban Area) ["Valencia"] = {alias_of = "Valencia, Venezuela"}, ["Maracay"] = {container = "Venezuela"}, -- 1,480,000 (Consolidated Urban Area) ["Barquisimeto"] = {container = "Venezuela"}, -- 1,360,000 (Consolidated Urban Area) } export.misc_cities_group = { canonicalize_key_container = make_canonicalize_key_container(nil, "country"), default_placetype = "city", 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 klivwtskw7tsfcunbpukjvezmlt60dn साँचा:place/documentation 10 307484 489348 2026-09-22T18:38:35Z SM7 6218 निर्मित / अंग्रेजी अनुसार++ 489348 wikitext text/x-wiki {{documentation subpage}} {{hatnote|For a list of types of place name of each country, see '''[[Wiktionary:Place names]]''' .}} {{uses lua|Module:place}} This template generates definition lines and categories for [[placename]]s. ==Usage== The basic usage is as follows (e.g. for {{m|en|Germany}}): <syntaxhighlight lang="wikitext"> # {{place|en|country|cont/Europe}}. </syntaxhighlight> which generates: # {{place|en|country|cont/Europe}}. and places the page in [[:Category:en:Countries in Europe]]. The second parameter is the type of the place, while the third and further parameters are ''holonyms'', indicating the larger entities that the place is contained within. Each holonym is of the form <code>TYPE/NAME</code>. The type can be spelled out in full, e.g. <code>continent</code>; common types can also be abbreviated, e.g. <code>cont</code> for <code>continent</code> (as above), <code>s</code> for <code>state</code>, <code>p</code> for <code>province</code>, <code>c</code> for <code>country</code>, etc. The full list of abbreviations is given below. More than one holonym can be given, e.g. for {{m|en|Toronto}}: <syntaxhighlight lang="wikitext"> # {{place|en|city|p/Ontario|c/Canada}}. </syntaxhighlight> which generates: # {{place|en|city|p/Ontario|c/Canada}}. and places the page in [[:Category:en:Cities in Ontario, Canada]]. The categorization system automatically generates the correct-format definition and category/categories, even when that requires computing a variant name, e.g. for {{m|en|Amsterdam}}: <syntaxhighlight lang="wikitext"> # {{place|en|city|c/Netherlands}}. </syntaxhighlight> which generates: # {{place|en|city|c/Netherlands}}. and places the page in [[:Category:en:Cities in the Netherlands]]. In this case, both the definition and category need to have "the" prefixed to the country name, which automatically happens. As another example, for {{m|en|Pittsburgh}}: <syntaxhighlight lang="wikitext"> # {{place|en|city|s/Pennsylvania|c/United States}}. </syntaxhighlight> which generates: # {{place|en|city|s/Pennsylvania|c/United States}}. and places the page in [[:Category:en:Cities in Pennsylvania, USA]]. (States of the United States are suffixed with <code>, USA</code> in some categories, to aid in distinguishing the US state of Georgia from the country of Georgia.) For place names in foreign languages, a translation in English can be given, which changes the definition format, e.g. for {{m|fr|Allemagne}} (the French term for Germany): <syntaxhighlight lang="wikitext"> # {{place|fr|country|cont/Europe|t1=Germany}} </syntaxhighlight> which generates: # {{place|fr|country|cont/Europe|t1=Germany}} and places the page in [[:Category:fr:Countries in Europe]]. (Note that this category has language code <code>fr</code>, which contains ''French'' terms for countries in Europe, rather than English terms.) Some place types use "of" instead of "in" in the definition and category, e.g. for {{m|en|Fairfax County}}: <syntaxhighlight lang="wikitext"> # {{place|en|county|s/Virginia|c/United States}}. </syntaxhighlight> which generates: # {{place|en|county|s/Virginia|c/United States}}. and places the page in [[:Category:en:Counties of Virginia, USA]]. Additional descriptive text can be present among the holonyms, and will be formatted correctly in the definition, e.g. for {{m|en|Germany}}: <syntaxhighlight lang="wikitext"> # {{place|en|country|in central|cont/Europe}}. </syntaxhighlight> which generates: # {{place|en|country|in central|cont/Europe}}. and places the page in [[:Category:en:Countries in Europe]], as above. ==Single-spec format== For complex cases, an alternative format can be used, known as ''single spec'', which freely allows for placetypes and holonyms to be interspersed among raw text, e.g. as follows (for {{m|en|Fener}}): <syntaxhighlight lang="wikitext"># {{place|en|A <<neighborhood>> midway up the <<inlet/Golden Horn>> within <<dist/Fatih>> in <<city/Istanbul>>, <<c/Turkey>>}}.</syntaxhighlight> which generates # {{place|en|A <<neighborhood>> midway up the <<inlet/Golden Horn>> within <<dist/Fatih>> in <<city/Istanbul>>, <<c/Turkey>>}}. and places the page in [[:Category:en:Neighborhoods in Turkey]]. In this format, placetypes and holonyms are surrounded by <code><<...>></code>. The presence of a slash indicates a holonym; no slash indicates a placetype. There is no requirement that placetypes precede holonyms. In this format, it is possible to break up a multiword placetype if the initial word or words are recognized qualifiers (see below), such as "former" or "ancient". Example: <syntaxhighlight lang="wikitext"># {{lb|en|now|historical}} {{place|en|A <<former>> French <<colony>> on the <<isl:pref/Hispaniola>> from 1659 to 1809, roughly equivalent to modern-day <<c/Haiti>>}}.</syntaxhighlight> which generates # {{lb|en|now|historical}} {{place|en|A <<former>> French <<colony>> on the <<isl:pref/Hispaniola>> from 1659 to 1809, roughly equivalent to modern-day <<c/Haiti>>}}. and places the page in [[:Category:en:Former dependent territories]] (as <code><<former colony>></code> would do), rather than in [[:Category:en:Dependent territories]] (as <code><<colony>></code> would normally do). ==Mixed format== You can also mix the separate-parameter and single-spec formats, as long as the single spec precedes the separate parameters. For example, for {{m|en|Kodungallur}}: <syntaxhighlight lang="wikitext"># {{place|en|A historically significant <<town>> in|dist/Thrissur|s/Kerala|in southwestern|c/India}}.</syntaxhighlight> which generates # {{place|en|A historically significant <<town>> in|dist/Thrissur|s/Kerala|in southwestern|c/India}}. In this format, no text (e.g. {{cd|the}}, {{cd|in}}, {{cd|of}}) is added prior to the first holonym; thus you must include it in the single spec parameter, as follows: <syntaxhighlight lang="wikitext"># {{place|yo|t={{w|Isin, Kwara|Owu}}|an {{l|yo|Ìgbómìnà}} [[Yoruba]] <<town>> in the|lgarea:pref/Isin|s/Kwara|c/Nigeria}}</syntaxhighlight> which generates # {{place|yo|t={{w|Isin, Kwara|Owu}}|an {{l|yo|Ìgbómìnà}} [[Yoruba]] <<town>> in the|lgarea:pref/Isin|s/Kwara|c/Nigeria}} ==Parameters== Primary parameters: ; {{para|1}}: the language code of the entry ; {{para|2}}: ''see [[#Placetype parameter]]'' ; {{para|3}}, {{para|4}}, {{para|5}}, ...: ''see [[#Holonym parameters]]'' ; {{para|t1}}, {{para|t2}}, {{para|t3}}, ...: English translation(s) of the place ; {{para|tid1}}, {{para|tid2}}, {{para|tid3}}, ...: sense ID's for the English translation(s) of the place; see {{temp|senseid}} ; {{para|cat}}, {{para|cat2}}, ...: extra categories to add to the page; automatically prefixed by the language code, e.g. {{para|cat|Towns in England}} will add the page to [[:Category:fr:Towns in England]] if the specified language code is <code>fr</code> ; {{para|sort}}: the sort key for the categories generated by the template; rarely needs to be specified, except perhaps for Japanese Suppression and text parameters: ; {{para|def}}: replaces the entire definition without affecting the categorization ; {{para|addl}}: adds further text to the end of the definition without affecting categorization ; {{para|a}}: replaces the indefinite article at the beginning of the definition Extra information parameters: ; {{para|modern}}, {{para|modern2}}, ...: the modern name(s) or location(s) of the place ; {{para|official}}, {{para|official2}}, ...: the official name(s) of the place (e.g. [[People's Republic of China]] for [[China]]) ; {{para|capital}}, {{para|capital2}}, ...: the capital city/cities of the place ; {{para|largest city}}, {{para|largest city2}}, ...: the largest city/cities of the place ; {{para|caplc}}: the capital and largest city of the place ; {{para|seat}}, {{para|seat2}}, ...: the [[seat]](s) of the place, particularly for counties and equivalents; displays "county seat", "parish seat" or "borough seat" for counties, parishes and boroughs respectively; otherwise, displays just "seat" ; {{para|shire town}}, {{para|shire town2}}, ...: the [[shire town]] (similar to a county [[seat]]) of the place, particularly for counties in [[Vermont]] As with holonym parameters (see below), all of these parameters can be prefixed with a language code such as <code>fr:</code>, and prefixing just with <code>:</code> suppresses automatic linking. ===Placetype parameter=== The type(s) of place of the entry, such as <code>city</code>, <code>country</code> or <code>lake</code>. Multiple values are separated by a slash (<code>/</code>). The special value <code>and</code> suppresses the comma and doesn’t affect categorization. The placetype parameter can be pluralized and will be handled correctly. For example: <syntaxhighlight lang="wikitext"># {{place|en|Two <<former unincorporated communities>> in <<co/Williamson County>>, <<s/Illinois>>, <<c/USA>>}}.</syntaxhighlight> displays as # {{place|en|Two <<former unincorporated communities>> in <<co/Williamson County>>, <<s/Illinois>>, <<c/USA>>}}. and places the page in [[:Category:en:Unincorporated communities in Illinois, USA]] and [[:Category:en:Unincorporated communities in the United States]]. The aliases that are recognized for holonym placetypes (see below) can also be used here and will automatically be expanded, but as a matter of style it is recommended to spell out the placetype in full except for generally-recognized aliases such as <code>CDP</code> for ''[[census-designated place]]''. ===Holonym parameters=== A holonym parameter has the following format: ''placetype''/''placename''. The format ''placetype''/''langcode'':''placename'' can be used to specify a non-English placename. Normally, the placename will automatically be linked; using <code>:</code> with no langcode suppresses automatic linking. Automatic linking is done exactly as if {{temp|l}} were being used, which means that square brackets can be used inside it to link to individual parts, and {{temp|w}} can be used to link to Wikipedia. If the ''placetype'' and following slash are omitted, the parameter is displayed as regular text. If there are multiple holonyms, commas are placed before all holonyms except the first, according to the following algorithm: # No comma is placed before the first holonym (whether a placename or raw text). # No comma is placed before a holonym (whether a placename or raw text) preceded by raw text. # No comma is placed before the special raw-text values <code>and</code> and <code>in</code>. # No comma is placed before raw text beginning with {{cd|*}}. # A comma is placed before all other holonyms. This does not apply to the [[#Alternative format|alternative format]] described above, where raw text, placetypes and placenames are freely interspersed and no extra commas are added unless multiple placenames are grouped together (see below). ====Grouped holonyms==== Multiple comma-separated placenames can be given, and are formatted correctly and individually linked. For example: # <code><nowiki>{{place|en|river|c/Ukraine,Belarus,Poland}}.</nowiki></code> #: {{place|en|river|c/Ukraine,Belarus,Poland}}. # <code><nowiki>{{place|en|several cities|c/Argentina,Chile,Philippines,Spain,United States}}.</nowiki></code> #: {{place|en|several cities|c/Argentina,Chile,Philippines,Spain,United States}}. ====Holonyms that take "the"==== Some holonyms are normally preceded by "the", as in "the United States", while others aren't, e.g. "France". Holonyms that are normally preceded by "the" will have this added if they occur either as (1) the first-specified holonym parameter; (2) the non-first holonym in a multi-holonym list (for this, see the example just above); (3) when accompanied by the <code>:pref</code> or <code>:Pref</code> modifiers (see below). In other positions, they will not be preceded by "the", e.g.: # <code><nowiki>{{place|en|city|in the southern|c/United States}}.</nowiki></code> #: {{place|en|city|in the southern|c/United States}}. # <code><nowiki>{{place|en|city|s/Georgia|c/United States}}.</nowiki></code> #: {{place|en|city|s/Georgia|c/United States}}. ====Holonym placetype aliases==== Several aliases are recognized for ''placetype'': * <code>c</code> → <code>country</code> * <code>r</code> → <code>region</code> * <code>p</code> → <code>province</code> * <code>s</code> → <code>state</code> * <code>cc</code> → <code>constituent country</code> (should be used for England, Scotland, and Wales) * <code>cont</code> → <code>continent</code> * <code>dept</code> → <code>department</code> * <code>dist</code> → <code>district</code> * <code>riv</code> → <code>river</code> * <code>carea</code> → <code>council area</code> * <code>cdp</code>, <code>CDP</code> → <code>census-designated place</code> [etc.] The full list can be found below under [[#Recognized placetypes|Recognized placetypes]], which lists all recognized placetypes along with the aliases (if any) of each placetype. ====Holonym placetype modifiers==== Following the holonym placetype can be a colon followed by one or more comma-separated modifiers, e.g. <code>s:suf/New York</code>. Currently, the following modifiers are recognized: * {{cd|suf}}: Display the full placetype as a lowercase suffix, e.g. <code>s:suf/New York</code> → <code>New York state</code>. * {{cd|Suf}}: Display the full placetype as a capitalized suffix, e.g. <code>s:Suf/New York</code> → <code>New York State</code>. * {{cd|pref}}: Display the full placetype as a lowercase prefix, e.g. <code>s:pref/New York</code> → <code>(the) state of New York</code> (the initial "the" is displayed in the same circumstances as when it is displayed before a holonym like "United States"; see above). * {{cd|Pref}}: Display the full placetype as a capitalized prefix, e.g. <code>s:Pref/New York</code> → <code>(the) State of New York</code> (the initial "the" is displayed in the same circumstances as when it is displayed before a holonym like "United States"; see above). * {{cd|noaff}}: Suppress the default display of a prefix or suffix (see below). * {{cd|also}}: Specify that categorization should happen with this holonym as well as any previous holonyms. See [[#Multiple holonyms of different types]] below for examples. * {{cd|the}}: Force insertion of {{cd|the}} before the holonym. The reasons for using such a modifier are that (a) category recognition code is based off the full holonym placename, and hence won't work properly if a holonym like <code><nowiki>s/[[New York]] State</nowiki></code> is used; and (b) the bare holonym without the prefix or suffix will be autolinked, without the need to explicitly inserted brackets around the bare holonym. Note that some holonym placetypes have prefixes or suffixes attached by default, e.g.: * "canton", "civil parish", "community development block", "council area", "county borough", "department", "district", "district municipality", "local government district" (suffixed with "district"), "London borough" (suffixed with "borough"), "parish", "peninsula", "subdivision", "tehsil" (<code>suf</code>) * "autonomous oblast", "autonomous okrug", "census area", "krai", "oblast", "okrug", "regional county municipality" (<code>Suf</code>) * "metropolitan borough", "municipal district", "regional district", "regional municipality", "rural municipality" (<code>Pref</code>) This affixing does not happen if the holonym placename already has the placetype or a part of it in it, if an explicit prefixing or suffixing modifier is used, or if the modifier <code>noaff</code> is used. Examples: # <code><nowiki>{{place|en|city|carea/Highland|cc/Scotland}}.</nowiki></code> #: {{place|en|city|carea/Highland|cc/Scotland}}. # <code><nowiki>{{place|en|capital city|c:pref/Georgia}}.</nowiki></code> #: {{place|en|capital city|c:pref/Georgia}}. ====Multiple holonyms of different types==== Normally, when categorizing a place in a given holonym, all other holonyms of the same type also get categorized. For example, the following description of the [[Columbia River]]: {{demo|<nowiki># {{place|en|river|c/USA|and|c/Canada}}.</nowiki>|sep=produces}} and categorizes into [[:Category:Rivers in the United States]] and [[:Category:Rivers in Canada]]. However, once a holonym and other holonyms of the same type are categorized, no further categorization normally happens for the placetype in question. For example, the following: {{demo|<nowiki># {{place|en|river|p/British Columbia|c/Canada|and|s/Washington,Oregon|c/USA}}.</nowiki>|sep=produces}} but categorizes only into [[:Category:Rivers in British Columbia, Canada]] and [[:Category:Rivers in Canada]] and does not include categorizes the the states of the United States. To fix this, use the {{cd|:also}} modifier: {{demo|<nowiki># {{place|en|river|p/British Columbia|c/Canada|and|s:also/Washington,Oregon|c/USA}}.</nowiki>}} and categorizes into [[:Category:Rivers in British Columbia, Canada]], [[:Category:Rivers in Canada]], [[:Category:Rivers in Washington, USA]], [[:Category:Rivers in Oregon, USA]] and [[:Category:Rivers in the United States]]. Another common use of {{cd|:also}} is when describing a city that is the capital of several administrative divisions at different levels. An example is the city of [[Trento]] in [[Italy]], which is the capital both of the surrounding province of [[Trentino]] and the larger region of [[Trentino-Alto Adige]]. This could be specified as follows: {{demo|<nowiki># {{place|en|city/capital|p:pref/Trentino|*and the|r:pref:also/Trentino-Alto Adige|c/Italy}}.</nowiki>}} and categorizes both into [[:Category:Provincial capitals]] as well as [[:Category:Regional capitals of Italy]] (among other categories). As shown in this example, modifiers can be stacked one on another. This also uses {{cd|*}} to suppress the comma that would normally be added before the text {{cd|and the}}. ===Multiple descriptions=== The special value <code>;</code> restarts the description and categorization (except for the language code), and joins the two descriptions with a semicolon. For example: # {{m|en|Rio de Janeiro}} #: {{temp demo|place|pt|city/state capital|s/Rio de Janeiro|c/Brazil|;|former capital city|of|c/Brazil}} The main reason to use this format, as opposed to simply stringing the entire description together, is that categorization is restarted. This allows for more flexible categorization of places that serve multiple functions than would otherwise be possible. More generally, any value beginning with a <code>;</code> and not immediately followed by a space has the same restarting behavior, and in addition the text after the semicolon serves as the joining text, in place of a semicolon. For example: # {{m|en|Vatican City}} #: {{temp demo|place|en|city-state|r/Southern Europe|;,|an <<enclave>> within the city of <<city/Rome>>, <<c/Italy>>}}. If the joining text begins with an ASCII or Unicode letter, a space is placed before the joining text, otherwise no space is added, as above. Finally, the special value <code>;;</code> joins the descriptions with only a space. ==More complex examples== # {{m|en|Scranton}} #: <code><nowiki>{{place|en|city|in northeastern|s/Pennsylvania|c/United States}}.</nowiki></code> #: {{place|en|city|in northeastern|s/Pennsylvania|c/United States}}. #:: {{i|adds [[:Category:en:Cities in Pennsylvania, USA]]}} # {{m|en|Italy}} #: <code><nowiki>{{place|en|country|in southern|cont/Europe|caplc=Rome}}.</nowiki></code> #: {{place|en|country|in southern|cont/Europe|caplc=Rome}}. #:: {{i|adds [[:Category:en:Countries in Europe]]}} # {{m|it|Roma}} #: <code><nowiki>{{place|it|capital city|c/Italy|t1=Rome}}</nowiki></code> #: {{place|it|capital city|c/Italy|t1=Rome}} #:: {{i|adds [[:Category:it:Capital cities]]}} # {{m|fr|Wavrin}} #: <code><nowiki>{{place|fr|town/and/municipality|dept/Nord|r:suf/Hauts-de-France|c/France}}</nowiki></code> #: {{place|fr|town/and/municipality|dept/Nord|r:suf/Hauts-de-France|c/France}} #:: {{i|adds [[:Category:fr:Towns in Nord, France]] and [[:Category:fr:Communes of Nord, France]]}} # {{m|en|Bernicia}} #: <code><nowiki>{{place|en|A <<medieval>> [[Anglo-Saxon]] <<kingdom>>|in northeastern|cc/England|and|southeastern|c/Scotland}}.</nowiki></code> #: {{place|en|A <<medieval>> [[Anglo-Saxon]] <<kingdom>>|in northeastern|cc/England|and|southeastern|c/Scotland}}. #:: {{i|adds [[:Category:en:Polities]], for lack of a more specific category}} #: <code><nowiki>{{place|en|A <<medieval>> [[Anglo-Saxon]] <<kingdom>> in northeastern <<c/England>> and southeastern <<c/Scotland>>.}}</nowiki></code> #: {{place|en|A <<medieval>> [[Anglo-Saxon]] <<kingdom>> in northeastern <<c/England>> and southeastern <<c/Scotland>>}}. #:: {{i|same as previous example, using the alternative format}} # {{m|en|Yuzhne}} #: <code><nowiki>{{place|en|@former name of:Pivdenne|city|raion/Odesa|oblast/Odesa|in southern|c/Ukraine|;|name used before November 2024}}.</nowiki></code> #: {{place|en|@former name of:Pivdenne|city|raion/Odesa|oblast/Odesa|in southern|c/Ukraine|;|name used before November 2024}}. #:: {{i|adds [[:Category:en:Former names of settlements]]}} # {{m|uk|Змії́вка}} #: <code><nowiki>{{place|uk|@former name of:uk:Кідьош|village|urban hromada:suf/Berehove|raion/Berehove|obl/Zakarpattia|c/Ukraine|;|name used from 1946 to 1991; first mentioned in 1332|t=Zmiivka}}.</nowiki></code> #: {{place|uk|@former name of:uk:Кідьош|village|urban hromada:suf/Berehove|raion/Berehove|obl/Zakarpattia|c/Ukraine|;|name used from 1946 to 1991; first mentioned in 1332|t=Zmiivka}}. #:: {{i|adds [[:Category:uk:Former names of settlements]]}} ==Recognized placetypes== The following placetypes are recognized by the module, and processed specially. This does not mean that other placetypes cannot be used, but they will not get special handling (e.g. their display form will not be linked and they will not trigger any categorization). {{#invoke:place doc|placetype_table}} ==Recognized placenames== The following place names are recognized by the module, and handled specially in some fashion. Note that there's nothing preventing any place name from being used. Note that items in the third and fourth columns are boldfaced if they are different from the placename in the first column. {{#invoke:place doc|placename_table}} ==Recognized qualifiers== The following qualifiers are recognized by the module. This means that if such a qualifier is used before a recognized placetype, the placetype will still be recognized and processed as normal. Note that items in the second column are boldfaced if they are different from the qualifier in the first column. {{#invoke:place doc|qualifier_table}} <includeonly> [[Category:Place name templates]] </includeonly> ripa74kmt1qv5dcn3yu610h5mz1v2d7