Wikipedia
tumwiki
https://tum.wikipedia.org/wiki/Jani_likulu
MediaWiki 1.48.0-wmf.3
first-letter
Media
Special
Talk
User
User talk
Wikipedia
Wikipedia talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
TimedText
TimedText talk
Module
Module talk
Event
Event talk
Chakulya
0
7998
124124
24601
2026-11-09T19:53:41Z
Tumbuka Arch
6863
124124
wikitext
text/x-wiki
{{Short description|Vinthu ivyo vyamoyo vikurya kuti visange nkhongono na vyakukhumbikwa pa umoyo}}
{{Infobox
| above = Chakulya
| label1 = Mtundu
| data1 = Vyakurya vya vyamoyo
| label2 = Mulimo
| data2 = Kupeleka nkhongono na vyakukhumbikwa ku thupi
| label3 = Vinthu vikuru ivyo vili mu chakulya
| data3 = Carbohydrates, proteins, fats, vitamins na minerals
| label4 = Kofuma
| data4 = Vyakumera, vinyama na vyamoyo vya mu maji
| label5 = Umo chingasangikira
| data5 = Chakurya chakufumila, chakuphika panji chakunozgeka
| label6 = Kukhumbikwa kwake
| data6 = Umoyo wa vyamoyo
}}
[[File:Picture of fruit and vegetables.jpg|thumb|right|Vipambi na vyakumera ivyo ni vyakurya vya ŵanthu.]]
[[File:Assortment of fruit.jpg|thumb|right|Vipambi vyakupambanapambana ivyo vingakurika nga ni chakulya.]]
[[File:Fruit and vegetables.gif|thumb|right|Vipambi na vyakumera vyakuguliskika pa msika.]]
'''Chakulya''' ni vinthu ivyo vyamoyo vikurya kuti visange nkhongono na vyakukhumbikwa kuti thupi ligwire ntchito zake. Chakulya chikuzirwa pa umoyo wa ŵanthu, vinyama na vyamoyo vinyake.
Chakulya chingafuma ku vyakumera, vinyama na vyamoyo vya mu maji. Chingaryeka chafiskika kufuma ku malo agho chikufuma panji chikanozgeka na kuphika pambere chindaryeke.
Vyakurya vili na vinthu vyakupambanapambana ivyo thupi likugwiliskira ntchito pakukura, kunozga minofu na kusanga nkhongono.<ref name="WHO">{{Cite web|url=https://www.who.int/en/news-room/fact-sheets/detail/healthy-diet|title=Healthy diet|website=World Health Organization|date=26 January 2026|access-date=9 November 2026}}</ref>
== Mitundu ya vyakurya ==
Vyakurya vili na mitundu yinandi chomene. Mitundu iyi yikupambana kuyana na uko vyakurya vikufuma na ntchito iyo vikugwira mu thupi.
=== Vyakurya vyakufuma ku vyakumera ===
Vyakurya vinandi vikufuma ku vyakumera. Vyakurya ivi vikuphatikizapo:
* [[Mpunga]].
* [[Chimanga]].
* [[Mcheŵa]].
* [[Mbatata]].
* [[Mihogo]].
* [[Vipambi]].
* [[Vyakumera vyamumunda]].
* [[Mabeya]].
Vyakurya ivi vili na vyakukhumbikwa vyakupambanapambana nga ni carbohydrates, vitamins, minerals na dietary fibre.
=== Vyakurya vyakufuma ku vinyama ===
Vyakurya vinyake vikufuma ku vinyama. Ivi vikuphatikizapo:
* [[Nyama]].
* [[Somba]].
* [[Mahe]].
* [[Mkaka]].
* [[Uchi]].
Vyakurya ivi vingapeleka vyakukhumbikwa nga ni protein, mafuta, vitamins na minerals.
=== Vyakurya vyakufuma mu nyanja ===
Nyanja, milonga na nyanja zichoko ni malo agho ŵanthu ŵakusangiramo vyakurya vinandi.
Vyakurya vya mu maji vikuphatikizapo:
* [[Somba]].
* [[Prawns]].
* [[Crabs]].
* Vyamoyo vinyake vya mu maji.
== Vinthu ivyo vikusangika mu vyakurya ==
Vyakurya vili na vinthu vyakukhumbikwa ivyo thupi likugwiliskira ntchito kuti liŵe na umoyo uwemi.
=== Carbohydrates ===
Carbohydrates ni vyakukhumbikwa ivyo vikovwira chomene kupeleka nkhongono ku thupi. Vikusangika mu vyakurya nga ni mpunga, chimanga, mbatata, mihogo na vinthu vinyake vyakufuma ku vyakumera.<ref name="WHO"/>
=== Proteins ===
Protein ni chakukhumbikwa icho chikovwira pa kuzenga na kunozga minofu na vigaŵa vinyake vya thupi.
Chikusangika mu vyakurya nga ni:
* Nyama.
* Somba.
* Mahe.
* Mkaka.
* Mbeu za nyemba.
* Mtedza.
=== Mafuta ===
Mafuta ghakovwira kupeleka nkhongono na kovwira thupi kugwiliskira ntchito mavitamini ghanyake.
Ghikusangika mu mafuta gha vyakumera, mtedza, mapeyara, nyama na vyakurya vinyake.
=== Mavitamini na minerals ===
Mavitamini na minerals ni vyakukhumbikwa ivyo thupi likugwiliskira ntchito pa ntchito zakupambanapambana.
Vikusangika mu vipambi, vyakumera vyamumunda, nyama, mkaka na vyakurya vinyake.<ref name="WHO"/>
== Kufunika kwa chakulya ==
Chakulya ntchakuzirwa chomene pa umoyo wa vyamoyo. Ŵanthu ŵakukhumbikwira chakulya kuti ŵasange nkhongono zakugwilira ntchito zawo za zuŵa na zuŵa.
Vinyama navyo vikukhumbikwira chakulya kuti vikure, vilutilire kukhala na umoyo na kubabana.
Chakulya chikovwira pa:
* Kupeleka nkhongono ku thupi.
* Kukura kwa thupi.
* Kunozga minofu.
* Kupwelelera viŵaro vya thupi.
* Kupeleka mavitamini na minerals.
* Kuthandazga ntchito za thupi.
== Chakulya na mitundu ya chikhalidwe ==
Chakurya ntchimoza mwa vinthu ivyo vikupangiska kuti mitundu ya ŵanthu yiŵe na chikhalidwe chakupambanapambana.
Mtundu uliwose wa ŵanthu ungaŵa na vyakurya vyake ivyo vikupangika kuyana na vyakurya ivyo vikusangika mu chigaŵa icho ŵanthu ŵakukhala.
Mu [[Malaŵi]], vyakurya vyakuzirwa chomene vikuphatikizapo:
* [[Nsima]].
* [[Chibwabwa]].
* [[Kondowole]].
* [[Nkhwani]].
* [[Nyemba]].
* [[Mpunga]].
* [[Nsomba za mu Malaŵi]].
* [[Mbatata]].
Vyakurya ivi vikulongora umo ulimi, nyengo na maluso gha ŵanthu vikukhwaskira vyakurya ivyo vikurya zuŵa na zuŵa.
== Kunozga na kusunga chakulya ==
Vyakurya vinganozgeka mu nthowa zakupambanapambana pambere vindaryeke. Nthowa izi zikuphatikizapo:
* [[Kuphika]].
* [[Kuwotcha]].
* [[Kucheta]].
* [[Kuwumiska]].
* Kusunga mu malo ghakuzizima.
* Kusunga mu vipangizo vyakwenelera.
Kunozga chakulya mwakwenelera kukovwira kuti chisangike makora kweniso kuchepeska kufumapo kwa vyamoyo vichoko ivyo vingapweteka chakulya.
== Chitetezo cha chakulya ==
Chakulya chikukhumbikwira kupwelereka mwakwenelera kuti chileke kuŵa na vyamoyo vichoko panji vinthu vyakofya ivyo vingapweteka umoyo wa ŵanthu.
World Health Organization yikulongosora kuti chakulya chiŵe chambura ukazuzi wa vyamoyo na wa vyakupangika na mankhwala. Kusunga chakulya makora, kunozga malo ghakuphikapo na kusamalira maji ghakugwiliskira ntchito ni vinthu vyakuzirwa pa chitetezo cha chakulya.<ref>{{Cite web|url=https://www.who.int/health-topics/healthy-diet|title=Healthy diet|website=World Health Organization|access-date=9 November 2026}}</ref>
== Chakulya na chitetezo cha umoyo wa ŵanthu ==
Chitetezo cha chakulya (food security) chikung'anamura kuti ŵanthu wose ŵaŵe na mwaŵi wakusanga chakulya chakukwana, chakupwelelekeka makora na chakwenerera pa vyakukhumbikwa vya thupi.
Bungwe la FAO likulongosora kuti chitetezo cha chakulya chikukhumbikwira kuti ŵanthu ŵaŵe na mwaŵi wakusanga chakulya mu nyengo zose, kweniso chiŵe chakukwana na chakwenelera pa umoyo uwemi.<ref>{{Cite web|url=https://www.fao.org/4/X8622E/x8622e04.htm|title=Definition of Food Security|website=Food and Agriculture Organization|access-date=9 November 2026}}</ref>
== Wonaniso ==
* [[Ulimi]]
* [[Vyakumera]]
* [[Vyakurya vya mu Malaŵi]]
* [[Umo thupi likugwilira ntchito]]
* [[Mavitamini]]
* [[Carbohydrates]]
* [[Protein]]
* [[Mafuta]]
* [[Chakumwa]]
* [[Chitetezo cha chakulya]]
* [[Chilengedwe]]
== Ukaboni ==
<references/>
[[Category:Vyakurya]]
[[Category:Umoyo wa ŵanthu]]
[[Category:Ulimi]]
[[Category:Vyakukhumbikwa pa umoyo]]
dyrhuuxkeujjlpy3qlbvb123fhpaprp
124128
124124
2026-11-09T19:55:43Z
Tumbuka Arch
6863
124128
wikitext
text/x-wiki
{{Short description|Vinthu ivyo vyamoyo vikurya kuti visange nkhongono na vyakukhumbikwa pa umoyo}}
{{Infobox
| above = Chakulya
| label1 = Mtundu
| data1 = Vyakurya vya vyamoyo
| label2 = Mulimo
| data2 = Kupeleka nkhongono na vyakukhumbikwa ku thupi
| label3 = Vinthu vikuru ivyo vili mu chakulya
| data3 = Carbohydrates, proteins, fats, vitamins na minerals
| label4 = Kofuma
| data4 = Vyakumera, vinyama na vyamoyo vya mu maji
| label5 = Umo chingasangikira
| data5 = Chakurya chakufumila, chakuphika panji chakunozgeka
| label6 = Kukhumbikwa kwake
| data6 = Umoyo wa vyamoyo
}}
[[File:Picture of fruit and vegetables.jpg|thumb|right|Vipambi na vyakumera ivyo ni vyakurya vya ŵanthu.]]
[[File:Assortment of fruit.jpg|thumb|right|Vipambi vyakupambanapambana ivyo vingakurika nga ni chakulya.]]
[[File:Fruit and vegetables.gif|thumb|right|Vipambi na vyakumera vyakuguliskika pa msika.]]
'''Chakulya''' ni vinthu ivyo vyamoyo vikurya kuti visange nkhongono na vyakukhumbikwa kuti thupi ligwire ntchito zake. Chakulya chikuzirwa pa umoyo wa ŵanthu, vinyama na vyamoyo vinyake.
Chakulya chingafuma ku vyakumera, vinyama na vyamoyo vya mu maji. Chingaryeka chafiskika kufuma ku malo agho chikufuma panji chikanozgeka na kuphika pambere chindaryeke.
Vyakurya vili na vinthu vyakupambanapambana ivyo thupi likugwiliskira ntchito pakukura, kunozga minofu na kusanga nkhongono.<ref name="WHO">{{Cite web|url=https://www.who.int/en/news-room/fact-sheets/detail/healthy-diet|title=Healthy diet|website=World Health Organization|date=26 January 2026|access-date=9 November 2026}}</ref>
== Mitundu ya vyakurya ==
Vyakurya vili na mitundu yinandi chomene. Mitundu iyi yikupambana kuyana na uko vyakurya vikufuma na ntchito iyo vikugwira mu thupi.
=== Vyakurya vyakufuma ku vyakumera ===
Vyakurya vinandi vikufuma ku vyakumera. Vyakurya ivi vikuphatikizapo:
* [[Mpunga]].
* [[Chimanga]].
* [[Mbatata]].
* [[Mihogo]].
* [[Vipambi]].
* [[Vyakumera vyamumunda]].
* [[Mabeya]].
Vyakurya ivi vili na vyakukhumbikwa vyakupambanapambana nga ni carbohydrates, vitamins, minerals na dietary fibre.
=== Vyakurya vyakufuma ku vinyama ===
Vyakurya vinyake vikufuma ku vinyama. Ivi vikuphatikizapo:
* [[Nyama]].
* [[Somba]].
* [[Mahe]].
* [[Mkaka]].
* [[Uchi]].
Vyakurya ivi vingapeleka vyakukhumbikwa nga ni protein, mafuta, vitamins na minerals.
=== Vyakurya vyakufuma mu nyanja ===
Nyanja, milonga na nyanja zichoko ni malo agho ŵanthu ŵakusangiramo vyakurya vinandi.
Vyakurya vya mu maji vikuphatikizapo:
* [[Somba]].
* [[Prawns]].
* [[Crabs]].
* Vyamoyo vinyake vya mu maji.
== Vinthu ivyo vikusangika mu vyakurya ==
Vyakurya vili na vinthu vyakukhumbikwa ivyo thupi likugwiliskira ntchito kuti liŵe na umoyo uwemi.
=== Carbohydrates ===
Carbohydrates ni vyakukhumbikwa ivyo vikovwira chomene kupeleka nkhongono ku thupi. Vikusangika mu vyakurya nga ni mpunga, chimanga, mbatata, mihogo na vinthu vinyake vyakufuma ku vyakumera.<ref name="WHO"/>
=== Proteins ===
Protein ni chakukhumbikwa icho chikovwira pa kuzenga na kunozga minofu na vigaŵa vinyake vya thupi.
Chikusangika mu vyakurya nga ni:
* Nyama.
* Somba.
* Mahe.
* Mkaka.
* Mbeu za nyemba.
* Mtedza.
=== Mafuta ===
Mafuta ghakovwira kupeleka nkhongono na kovwira thupi kugwiliskira ntchito mavitamini ghanyake.
Ghikusangika mu mafuta gha vyakumera, mtedza, mapeyara, nyama na vyakurya vinyake.
=== Mavitamini na minerals ===
Mavitamini na minerals ni vyakukhumbikwa ivyo thupi likugwiliskira ntchito pa ntchito zakupambanapambana.
Vikusangika mu vipambi, vyakumera vyamumunda, nyama, mkaka na vyakurya vinyake.<ref name="WHO"/>
== Kufunika kwa chakulya ==
Chakulya ntchakuzirwa chomene pa umoyo wa vyamoyo. Ŵanthu ŵakukhumbikwira chakulya kuti ŵasange nkhongono zakugwilira ntchito zawo za zuŵa na zuŵa.
Vinyama navyo vikukhumbikwira chakulya kuti vikure, vilutilire kukhala na umoyo na kubabana.
Chakulya chikovwira pa:
* Kupeleka nkhongono ku thupi.
* Kukura kwa thupi.
* Kunozga minofu.
* Kupwelelera viŵaro vya thupi.
* Kupeleka mavitamini na minerals.
* Kuthandazga ntchito za thupi.
== Chakulya na mitundu ya chikhalidwe ==
Chakurya ntchimoza mwa vinthu ivyo vikupangiska kuti mitundu ya ŵanthu yiŵe na chikhalidwe chakupambanapambana.
Mtundu uliwose wa ŵanthu ungaŵa na vyakurya vyake ivyo vikupangika kuyana na vyakurya ivyo vikusangika mu chigaŵa icho ŵanthu ŵakukhala.
Mu [[Malaŵi]], vyakurya vyakuzirwa chomene vikuphatikizapo:
* [[Nsima]].
* [[Chibwabwa]].
* [[Kondowole]].
* [[Nkhwani]].
* [[Nyemba]].
* [[Mpunga]].
* [[Nsomba za mu Malaŵi]].
* [[Mbatata]].
Vyakurya ivi vikulongora umo ulimi, nyengo na maluso gha ŵanthu vikukhwaskira vyakurya ivyo vikurya zuŵa na zuŵa.
== Kunozga na kusunga chakulya ==
Vyakurya vinganozgeka mu nthowa zakupambanapambana pambere vindaryeke. Nthowa izi zikuphatikizapo:
* [[Kuphika]].
* [[Kuwotcha]].
* [[Kucheta]].
* [[Kuwumiska]].
* Kusunga mu malo ghakuzizima.
* Kusunga mu vipangizo vyakwenelera.
Kunozga chakulya mwakwenelera kukovwira kuti chisangike makora kweniso kuchepeska kufumapo kwa vyamoyo vichoko ivyo vingapweteka chakulya.
== Chitetezo cha chakulya ==
Chakulya chikukhumbikwira kupwelereka mwakwenelera kuti chileke kuŵa na vyamoyo vichoko panji vinthu vyakofya ivyo vingapweteka umoyo wa ŵanthu.
World Health Organization yikulongosora kuti chakulya chiŵe chambura ukazuzi wa vyamoyo na wa vyakupangika na mankhwala. Kusunga chakulya makora, kunozga malo ghakuphikapo na kusamalira maji ghakugwiliskira ntchito ni vinthu vyakuzirwa pa chitetezo cha chakulya.<ref>{{Cite web|url=https://www.who.int/health-topics/healthy-diet|title=Healthy diet|website=World Health Organization|access-date=9 November 2026}}</ref>
== Chakulya na chitetezo cha umoyo wa ŵanthu ==
Chitetezo cha chakulya (food security) chikung'anamura kuti ŵanthu wose ŵaŵe na mwaŵi wakusanga chakulya chakukwana, chakupwelelekeka makora na chakwenerera pa vyakukhumbikwa vya thupi.
Bungwe la FAO likulongosora kuti chitetezo cha chakulya chikukhumbikwira kuti ŵanthu ŵaŵe na mwaŵi wakusanga chakulya mu nyengo zose, kweniso chiŵe chakukwana na chakwenelera pa umoyo uwemi.<ref>{{Cite web|url=https://www.fao.org/4/X8622E/x8622e04.htm|title=Definition of Food Security|website=Food and Agriculture Organization|access-date=9 November 2026}}</ref>
== Wonaniso ==
* [[Ulimi]]
* [[Vyakumera]]
* [[Vyakurya vya mu Malaŵi]]
* [[Umo thupi likugwilira ntchito]]
* [[Mavitamini]]
* [[Carbohydrates]]
* [[Protein]]
* [[Mafuta]]
* [[Chakumwa]]
* [[Chitetezo cha chakulya]]
* [[Chilengedwe]]
== Ukaboni ==
<references/>
[[Category:Vyakurya]]
[[Category:Umoyo wa ŵanthu]]
[[Category:Ulimi]]
[[Category:Vyakukhumbikwa pa umoyo]]
jq7rtghjgppn31jqn0y3fkujefnml4o
Module:Color contrast
828
9250
124185
118643
2026-11-08T01:35:37Z
en>Axolitl
0
Implement edit request, for real this time
124185
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB (v)
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum(R, G, B)
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum(h, s, l)
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum(c)
if (c == nil) then
return ''
end
-- html '#' entity
c = c:gsub("#", "#")
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- unstrip nowiki strip markers
c = mw.text.unstripNoWiki(c)
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl / hsla (accepts comma or space delimiters)
if mw.ustring.match(c,'^hsla?%([%s]*[0-9][0-9%.]*[%s]*[,%s][%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%.*%)$') then
local h, s, l = mw.ustring.match(c,'^hsla?%([%s]*([0-9][0-9%.]*)[%s]*[,%s][%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%.*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb / rgba (numeric values 0 to 255)
if mw.ustring.match(c,'^rgba?%([%s]*[0-9][0-9]*[%s]*[,%s][%s]*[0-9][0-9]*[%s]*[,%s][%s]*[0-9][0-9]*.*%)$') then
local R, G, B = mw.ustring.match(c,'^rgba?%([%s]*([0-9][0-9]*)[%s]*[,%s][%s]*([0-9][0-9]*)[%s]*[,%s][%s]*([0-9][0-9]*).*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb / rgba percent
if mw.ustring.match(c,'^rgba?%([%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%.*%)$') then
local R, G, B = mw.ustring.match(c,'^rgba?%([%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%.*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 or #cs == 8 ) then -- Accepts 6 digits (#RRGGBB) or 8 digits (#RRGGBBAA)
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 or #cs == 4 ) then -- Accepts 3 digits (#RGB) or 4 digits (#RGBA)
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
-- This exports the function for use in other modules.
-- The colour is passed as a string.
function p._lum(color)
return color2lum(color)
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local css = (args['css'] and args['css'] ~= '') and true or false
local v1 = color2lum(args[1] or '')
local c2 = args[2] or 'white'
local v2 = color2lum(c2)
local c3 = args[3] or 'black'
local v3 = color2lum(c3)
local ratio1 = -1;
local ratio2 = -1;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
if css then
local c1 = args[1] or ''
if string.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c1 = '#' .. c1
end
if string.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c2 = '#' .. c2
end
if string.match(c3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c3 = '#' .. c3
end
return 'background-color:' .. c1 .. '; color:' .. ((ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '') .. ';'
end
return (ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or ''
end
function p._ratio(args)
local v1 = color2lum(args[1])
local v2 = color2lum(args[2])
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local lum_bg, lum_fg = 1, 0
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then lum_bg = lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then lum_fg = lum end
end
local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&#[Xx]23;', '#'), '#', '#'), ';')
for k = 1,#slist do
local s = slist[k]
local prop, val = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
prop = prop or ''
val = val or ''
if (prop:match('^[%s]*(background)[%s]*$') or prop:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(val)
if( lum ~= '' ) then lum_bg = lum end
elseif (prop:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(val)
if( lum ~= '' ) then lum_fg = lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
--[[
Use {{#invoke:Color contrast|somecolor}} directly or
{{#invoke:Color contrast}} from a wrapper template.
Parameters:
-- |1= — required; A color to check.
--]]
function p.lum(frame)
local color = frame.args[1] or frame:getParent().args[1]
return p._lum(color)
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
jrev1t70buhql0oqscuor2vyuctzl7u
124186
124185
2026-11-09T20:20:40Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Color_contrast]]
124185
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB (v)
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum(R, G, B)
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum(h, s, l)
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum(c)
if (c == nil) then
return ''
end
-- html '#' entity
c = c:gsub("#", "#")
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- unstrip nowiki strip markers
c = mw.text.unstripNoWiki(c)
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl / hsla (accepts comma or space delimiters)
if mw.ustring.match(c,'^hsla?%([%s]*[0-9][0-9%.]*[%s]*[,%s][%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%.*%)$') then
local h, s, l = mw.ustring.match(c,'^hsla?%([%s]*([0-9][0-9%.]*)[%s]*[,%s][%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%.*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb / rgba (numeric values 0 to 255)
if mw.ustring.match(c,'^rgba?%([%s]*[0-9][0-9]*[%s]*[,%s][%s]*[0-9][0-9]*[%s]*[,%s][%s]*[0-9][0-9]*.*%)$') then
local R, G, B = mw.ustring.match(c,'^rgba?%([%s]*([0-9][0-9]*)[%s]*[,%s][%s]*([0-9][0-9]*)[%s]*[,%s][%s]*([0-9][0-9]*).*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb / rgba percent
if mw.ustring.match(c,'^rgba?%([%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%[%s]*[,%s][%s]*[0-9][0-9%.]*%%.*%)$') then
local R, G, B = mw.ustring.match(c,'^rgba?%([%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%[%s]*[,%s][%s]*([0-9][0-9%.]*)%%.*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 or #cs == 8 ) then -- Accepts 6 digits (#RRGGBB) or 8 digits (#RRGGBBAA)
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 or #cs == 4 ) then -- Accepts 3 digits (#RGB) or 4 digits (#RGBA)
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
-- This exports the function for use in other modules.
-- The colour is passed as a string.
function p._lum(color)
return color2lum(color)
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local css = (args['css'] and args['css'] ~= '') and true or false
local v1 = color2lum(args[1] or '')
local c2 = args[2] or 'white'
local v2 = color2lum(c2)
local c3 = args[3] or 'black'
local v3 = color2lum(c3)
local ratio1 = -1;
local ratio2 = -1;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
if css then
local c1 = args[1] or ''
if string.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c1, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c1 = '#' .. c1
end
if string.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c2, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c2 = '#' .. c2
end
if string.match(c3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?$') or
string.match(c3, '^[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?[A-Fa-f0-9]?$') then
c3 = '#' .. c3
end
return 'background-color:' .. c1 .. '; color:' .. ((ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or '') .. ';'
end
return (ratio1 > 0) and (ratio2 > 0) and ((ratio1 + bias > ratio2) and c2 or c3) or ''
end
function p._ratio(args)
local v1 = color2lum(args[1])
local v2 = color2lum(args[2])
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local lum_bg, lum_fg = 1, 0
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then lum_bg = lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then lum_fg = lum end
end
local slist = mw.text.split(mw.ustring.gsub(mw.ustring.gsub(style or '', '&#[Xx]23;', '#'), '#', '#'), ';')
for k = 1,#slist do
local s = slist[k]
local prop, val = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
prop = prop or ''
val = val or ''
if (prop:match('^[%s]*(background)[%s]*$') or prop:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(val)
if( lum ~= '' ) then lum_bg = lum end
elseif (prop:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(val)
if( lum ~= '' ) then lum_fg = lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
--[[
Use {{#invoke:Color contrast|somecolor}} directly or
{{#invoke:Color contrast}} from a wrapper template.
Parameters:
-- |1= — required; A color to check.
--]]
function p.lum(frame)
local color = frame.args[1] or frame:getParent().args[1]
return p._lum(color)
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
jrev1t70buhql0oqscuor2vyuctzl7u
Module:Citation/CS1
828
12881
124165
118666
2026-11-08T01:33:00Z
en>Trappist the monk
0
fix publisher initialization;
124165
Scribunto
text/plain
require ('strict');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z = {}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- boolean flag so that the category is added only once
local added_vanc_errs; -- boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local added_numeric_name_errs; -- boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered
local added_numeric_name_maint; -- boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
local url_was_archive_today; -- boolean flag set to true when has_archive_today_url() has unset |url= because it held a deprecated archive.today url
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit
(see http://tools.ietf.org/html/rfc952 §GRAMMATICAL HOST TABLE SPECIFICATION §§B. Lexical grammar <name>; see
http://tools.ietf.org/html/rfc1123#section-2). Between the first and last characters the name may use letters,
digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
local sl_domain = domain:match ('([^%.]+)%.[^%.]+$') or domain; -- test the second level domain name; ignore subdomains some (rarely) include chars not letter-digit-hyphen
if not (sl_domain:match ('^%w') and sl_domain:match ('%w$') and -- first and last characters must be letter or digit
sl_domain:match ('^[%w%-]+$')) then -- all other characters must be letters, digits, or hyphen-minus
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
'[%a%d]+%:?' -- IPv6 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('^//%S+') or value:match ('%s//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; authority indicator (//) must be be preceded nothing or by whitespace
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[--------------------------< I S _ A R C H I V E _ T O D A Y _ U R L >--------------------------------------
archive.today (and .ph, .is, .md, .li, .fo, .vn) are deprecated. See Wikipedia:Requests_for_comment/Archive.is_RFC_5
(Special:Permalink/1339352976)
<val> is a string that may or may not be a url
]]
local function is_archive_today_url (val)
if is_parameter_ext_wikilink (val) then -- is <val> a url?
local tld = val:match ('archive%.(%l+)/'); -- get the tld; real archive.today urls have a '/' after the tld
return tld and cfg.archive_today_tlds_t[tld]; -- return true if <tld> is one of the archive.today tlds; nil else
end
end
--[[--------------------------< H A S _ A R C H I V E _ T O D A Y _ U R L >------------------------------------
blank any parameter that holds one of the archive.today tlds (.today, .ph, .is, .md, .li, .fo, .vn) and also
blank parameters that are dependent on the offending parameter.
input <cite_args_t> is a table of all of this template's parameters This function modifies <cite_args_t>
when |url= or its alias |URL= hold an archive.today url, this function sets the flag <url_was_archive_today>
which is used later to suppress the missing url error message from {{citation}} when it has |website=<summat>
or from the templates {{cite web}}, {{cite podcast}}, {{cite mailing list}} which all require a url.
returns nothing
]]
local function has_archive_today_url (cite_args_t)
local unset_params_t = {}; -- to hold a sequence of parameters to unset from cite_args_t
for p, v in pairs (cite_args_t) do -- look at each parameter in the template
if is_archive_today_url (v:lower()) then -- if it has a parameter with an archive.today url
table.insert (unset_params_t, p); -- add the url-holding parameter name to our list of parameters to unset (may or may not be a legitimate url parameter)
if 'url' == p:lower() then -- if this parameter is |url= or |URL=
url_was_archive_today = true; -- set a flag so that cite web / podcast / mailinglist don't emit a missing url error message
end
if p:match ('archive%-?url') and ('usurped' == cite_args_t['url-status'] or 'unfit' == cite_args_t['url-status']) then -- if |archive-url=archive.today and |url-status=unfit/usurped
url_was_archive_today = true; -- set a flag so that cite web / podcast / mailinglist don't emit a missing url error message
table.insert (unset_params_t, 'url'); -- add the url parameter name to our list of parameters to unset (may or may not be a legitimate url parameter)
table.insert (unset_params_t, 'URL'); -- this one because both are possible
utilities.set_message ('err_url_suppressed'); -- emit supplemental error message
end
if cfg.dependencies_t[p] then -- if this url-holding parameter (<p>) has dependencies
for _, dependent in ipairs (cfg.dependencies_t[p]) do -- loop through the url-holding parameter's dependency sequence
table.insert (unset_params_t, dependent); -- add dependent parameter to the list to be unset
end
end
end
end
if 0 < #unset_params_t then -- when there are parameters to unset
if not is_preview_mode then -- when in preview mode do not suppress any parameters
for _, unset_param in ipairs (unset_params_t) do -- loop through the sequence
cite_args_t[unset_param] = nil; -- and unset the url-holding parameter and its dependent parameters to avoid parameter-requires-other-parameter errors
end
end
utilities.set_message ('maint_deprecated_archive'); -- add a maintenance message
end
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
local cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
utilities.set_message ('err_trans_missing_title', {trans_chapter_source:match ('trans%-?(.+)')}); -- when no chapter, get matching name from trans-<param>
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if utilities.in_array(capture, {'nowiki', 'math', 'templatestyles'}) then -- nowiki, math and templatestyles stripmarkers (not an error condition)
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset; for now, ignore linter warning
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = utilities.substitute (cfg.messages.invisible_1, {capture, char_name}); -- <capture> here is stripmarker name
else
err_msg = utilities.substitute (cfg.messages.invisible_2, char_name);
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded; for now, ignore linter warning
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local v;
local list = cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap;
local cap2;
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
local comp; -- what does 'comp' mean?
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
local trim = false;
local end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials (first, position)
if first:find (',', 1, true) then
return first; -- commas not allowed; abandon
end
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials_t = {}; -- table to hold initials
local i = 1; -- counter for number of initials
local names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
while names_t[i] do -- loop through the sequence
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
end
i = i + 1; -- bump the counter
end
return table.concat (initials_t); -- Vancouver format does not include spaces.
end
--[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >----------------------------------
extract interwiki prefixen from <value>. Returns two one or two values:
false – no prefixen
nil – prefix exists but not recognized
project prefix, language prefix – when value has either of:
:<project>:<language>:<article>
:<language>:<project>:<article>
project prefix, nil – when <value> has only a known single-letter prefix
nil, language prefix – when <value> has only a known language prefix
accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this
writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and
v (wikiversity)) are not supported.
]]
local function interwiki_prefixen_get (value, is_link)
if not value:find (':%l+:') then -- if no prefix
return false; -- abandon; boolean here to distinguish from nil fail returns later
end
local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen
'^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes
'^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes
'^%[%[:([dsw]):', -- wikilinked; project prefix
'^%[%[:(%l%l+):', -- wikilinked; language prefix
}
local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen
'^:([dsw]):(%l%l+):', -- project and language prefixes
'^:(%l%l+):([dsw]):', -- language and project prefixes
'^:([dsw]):', -- project prefix
'^:(%l%l+):', -- language prefix
}
local cap1, cap2;
for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do
cap1, cap2 = value:match (pattern);
if cap1 then
break; -- found a match so stop looking
end
end
if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed)
if 1 == #cap1 then -- length == 1 then :project:language:
if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map?
return cap1, cap2; -- return interwiki project and interwiki language
end
else -- here when :language:project:
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return cap2, cap1; -- return interwiki project and interwiki language
end
end
return nil; -- unknown interwiki language
elseif not (cap1 or cap2) then -- both are nil?
return nil; -- we got something that looks like a project prefix but isn't; return fail
elseif 1 == #cap1 then -- here when one capture
return cap1, nil; -- length is 1 so return project, nil language
else -- here when one capture and its length it more than 1
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return nil, cap1; -- return nil project, language
end
end
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present
if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then
proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat?
end
if proj then
local proj_name = ({['d'] = cfg.messages.wikidata, ['s'] = cfg.messages.wikisource, ['w'] = cfg.messages.wikipedia})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj_name then
one = one .. utilities.wrap_style ('interproj', proj_name); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interproj-linked-name', proj); -- categorize it; <proj> is sort key
tag = nil; -- unset; don't do both project and language
end
end
if tag == cfg.this_wiki_code then
tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat?
end
if tag then
local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag];
if lang then -- error messaging done in extract_names() where we know parameter names
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interwiki-linked-name', tag); -- categorize it; <tag> is sort key
end
end
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add an error message and category when <name> parameter value does not contain letters.
Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are
not numeric characters; could be letters and/or punctuation characters.
This function will only emit one error and one maint message for the current template. Does not emit both error
and maint messages/categories for the same parameter value.
returns nothing
]]
local function name_is_numeric (name, name_alias, list_name)
local patterns = {
'^%D+%d', -- <name> must have digits preceded by other characters
'^%D*%d+%D+', -- <name> must have digits followed by other characters
}
if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters
utilities.set_message ('err_numeric_names', name_alias); -- add an error message
added_numeric_name_errs = true; -- set the flag so we emit only one error message
return; -- when here no point in further testing; abandon
end
if not added_numeric_name_maint then -- if we have already set a maint message
for _, pattern in ipairs (patterns) do -- spin through list of patterns
if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
added_numeric_name_maint = true; -- set the flag so we emit only one maint message
return; -- when here no point in further testing; abandon
end
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
Same test for first except that commas should not appear in given names (MOS:JR says
that the generational suffix does not take a separator character). Titles, degrees,
postnominals, affiliations, all normally comma separated don't belong in a citation.
<name> – name parameter value
<list_name> – AuthorList, EditorList, etc
<limit> – number of allowed commas; 1 (default) for surnames; 0 for given names
returns nothing
]]
local function name_has_mult_names (name, list_name, limit)
local _, commas, semicolons, nbsps;
limit = limit and limit or 1;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if limit < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value)
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter
name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name
name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name
local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only
end
end
if link then -- error check |linkn= alias for unknown interwiki link prefix
local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
link = nil; -- unset so we don't link
link_alias = nil;
end
end
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_tag_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn
end
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags that MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag; for now, ignore linter warning
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
This function sets an error message when |display-xxxxors= value greater than or equal to number of names but
not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the
keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected
that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}.
]]
local function get_display_names (max, count, etal, param)
if utilities.is_set (max) then
if 'etal' == cfg.keywords_xlate[max:lower():gsub("[ '%.]", '')] then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
and |issue=.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
numero sign U+2116.
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
local accept_val; -- for now, ignore linter warning
val, accept_val = utilities.has_accept_as_written (val);
--if accept_val then -- if uncomment this, |volume=((vol. 1)) suppresses error
-- return;
--end
--val = mw.text.unstripNoWiki (val); -- if uncomment this, |volume=<nowiki>vol. 1</nowiki> shows error
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local _, accept = utilities.has_accept_as_written (vparam);
if accept then
utilities.add_prop_cat ('vanc-accept'); -- add properties category
end
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirst_t = mw.text.split(v_name, "%s+");
first = table.remove (lastfirst_t); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove (lastfirst_t); -- get what should be the initials from the table
end
last = table.concat (lastfirst_t, ' '); -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
utilities.set_message ('err_redundant_parameters',
utilities.substitute (cfg.special_case_translation.name_list_params,
('AuthorList' == list_name) and cfg.special_case_translation.author or cfg.special_case_translation.editor)); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >-----------------------------------------
returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single
string; or formatted volume or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, article, cite_class, origin, script_origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and ('journal' == origin or 'script-journal' == script_origin));
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '')
vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '')
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites
if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number
return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower);
elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below
return wrap_msg ('art', {sepc, article}, lower);
end
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, script_origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin or 'script-journal' == script_origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin or 'script-journal' == script_origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and ('journal' == origin or 'script-journal' == script_origin));
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
A secondary function is to return an archive-url timestamp from those archive urls that have them. The timestamp
is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the
archive url.
]=]
local function archive_url_check (url, date)
local err_msg; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
local function is_ts_date_valid (ts, origin_date) -- local function to validate archive url taimestamp date; time ignored
local y, m, d = ts:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- split into parts
if y and validation.is_valid_date (y, m, d) and (tonumber (y) >= 1996) then
return true, tonumber (y) >= origin_date; -- <origin_date> is 1996 for archive.org
end
end
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif not is_ts_date_valid (timestamp, 1996) then -- is ymd portion of timestamp a valid date?
err_msg = cfg.err_msg_supl.timestamp;
timestamp = nil; -- unset because invalid
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting.
When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string,
special handling is required.
When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND:
the number of names specified by <number_of_names> is:
greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>)
use global |display-<namelist>= parameter value
set overridden maint category
less than or equal to the number specified in the global |display-<namelist>= parameter
use local |display-<namelist>= parameter value
The purpose of this function is to prevent categorizing a template that has fewer names than the global setting
to keep the etal annotation specified by <local_display_names>.
]]
local function display_names_select (global_display_names, local_display_names, param_name, number_of_names)
if global_display_names and utilities.is_set (local_display_names) then -- when both
if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison
local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits
if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed?
utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control
end
end
-- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls
utilities.set_message ('maint_overridden_setting'); -- set a maint message
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
end
-- here when only one of <global_display_names> or <local_display_names> set
if global_display_names then
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local
end
end
--[[--------------------------< M O D E _ S E T >--------------------------------------------------------------
fetch global mode setting from {{cs1 config}} (if present) or from |mode= (if present); global setting overrides
local |mode= parameter value. When both are present, emit maintenance message
]]
local function mode_set (Mode, Mode_origin)
local mode;
if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}}; nil when empty or assigned value invalid
mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax
else
mode = is_valid_parameter_value (Mode, Mode_origin, cfg.keywords_lists['mode'], '');
end
if cfg.global_cs1_config_t['Mode'] and utilities.is_set (Mode) then -- when template has |mode=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
return mode;
end
--[[--------------------------< Q U O T E _ M A K E >----------------------------------------------------------
create quotation from |quote=, |trans-quote=, and/or script-quote= with or without |quote-page= or |quote-pages=
when any of those three quote parameters are set, this function unsets <PostScript>. When none of those parameters
are set, |quote-page= and |quote-pages= are unset to nil so that they are not included in the template's metadata
]]
local function quote_make (quote, trans_quote, script_quote, quote_page, quote_pages, nopp, sepc, postscript)
if utilities.is_set (quote) or utilities.is_set (trans_quote) or utilities.is_set (script_quote) then
if utilities.is_set (quote) then
if quote:sub(1, 1) == '"' and quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
quote = quote:sub(2, -2); -- strip them off
end
end
quote = kern_quotes (quote); -- kern if needed
quote = utilities.wrap_style ('quoted-text', quote ); -- wrap in <q>...</q> tags
if utilities.is_set (script_quote) then
quote = script_concatenate (quote, script_quote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (trans_quote) then
if trans_quote:sub(1, 1) == '"' and trans_quote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
trans_quote = trans_quote:sub(2, -2); -- strip them off
end
quote = quote .. " " .. utilities.wrap_style ('trans-quoted-title', trans_quote );
end
if utilities.is_set (quote_page) or utilities.is_set (quote_pages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (quote_page) then
extra_text_in_page_check (quote_page, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not nopp then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_page});
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_page});
end
elseif utilities.is_set (quote_pages) then
extra_text_in_page_check (quote_pages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(quote_pages) ~= nil and not nopp then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_pages});
elseif not nopp then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, quote_pages});
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_pages});
end
end
quote = quote_prefix .. ": " .. quote;
else
quote = sepc .. " " .. quote;
end
postscript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
elseif utilities.is_set (quote_page) or utilities.is_set (quote_pages) then
quote_page = nil; -- unset; these require |quote=; TODO: error message?
quote_pages = nil;
end
return quote, quote_page, quote_pages, postscript;
end
--[[--------------------------< C H E C K _ P U B L I S H E R _ N A M E >--------------------------------------
look for variations of '<text>: <text>' that might be '<location>: <publisher>' in |publisher= parameter value.
when found, emit a maintenance message; return nil else
<publisher> is the value assigned to |publisher= or |institution=
]]
local function check_publisher_name (publisher)
local patterns_t = {
'^[%w%s]+%s*:%s*[%w%s]+$', -- plain text <location>: <publisher>
'^%[+[%w%s:|]+%]+%s*:%s*[%w%s]+$', -- partially wikilinked [[<location>]]: <publisher>
'^[%w%s]+%s*:%s*%[+[%w%s:|]+%]+$', -- partially wikilinked <location>: [[<publisher>]]
'^%[+[%w%s:|]+%]+%s*:%s*%[+[%w%s:|]+%]+$', -- wikilinked [[<location>]]: [[<publisher>]]
}
for _, pattern in ipairs (patterns_t) do -- spin through the patterns_t sequence
if mw.ustring.match (publisher, pattern) then -- does this pattern match?
utilities.set_message ('maint_publisher_location'); -- set a maint message
return; -- and done
end
end
end
--[[--------------------------< I S _ P A G E _ A R T _ N U M >------------------------------------------------
compare the trailing (rightmost) characters of the |doi= value against the whole value assigned to |page(s)=.
return boolean true when:
|page(s)= has exactly 8 digits and a dot between the fourth and fifth digits matches the trailing 9 characters
of the |doi= value: |page=12345678 → |page=1234.5678 matches |doi=10.xxxx/yyyy1234.5678
|page(s)= is 5 or more characters and matches |doi= values's trailing characters
|page(s)= begins with a lowercase 'e' and |page(s)= without the 'e' matches |doi= values's trailing
characters: |page=e12345 → |page=12345 matches |doi=10.xxxx/yyyy12345
|page(s)= begins with a uppercase 'CD' followed by (typically) six digits matches |doi= values that ends with
'CDxxxxxx.pubx' (where 'x' is any single digit)
return nil when |page(s)= values:
are ranges separated by underscore, hyphen, emdash, endash, figure dash, or minus character
are comma- or semicolon-separated lists of pages
have external urls (has text 'http')
are digit-only values less than 10000
do not match |doi= values's trailing characters
]]
local function is_page_art_num (page, doi)
if not (utilities.is_set (page) and utilities.is_set (doi)) then -- both required
return; -- abandon; nothing to do
end
if page:match ('[,;_−–—‒%-]') then -- when |page(s)= might be a page range or a separated list of pages
return; -- abandon
end
page = page:lower(); -- because doi names are case insensitive
doi = doi:lower(); -- force these to lowercase for testing
if page:match ('http') then -- when |page(s)= appears to hold a url
return; -- abandon
end
if tonumber (page) then -- is |page(s)= digits only
if 10000 > tonumber (page) then -- when |page(s)= less than 10000
return; -- abandon
end
if doi:match (page .. '$') then -- digits only page number match the last digits in |doi=?
return true;
end
if 8 == page:len() then -- special case when |page(s)= is exactly 8 digits
local dot_page = page:gsub ('(%d%d%d%d)(%d%d%d%d)', '%1.%2'); -- make a |page=xxxx.yyyy version commonly used in |doi=
if doi:match (dot_page .. '$') then -- 8-digit dotted page number match the last characters in |doi=?
return true;
end
end
else -- here when |page(s)= is alpha-numeric
if 4 < page:len() then -- when |page(s)= is five or more characters
if doi:match (page .. '$') then -- alpha-numeric page match the last characters in |doi=?
return true;
end
local epage = page:match ('^e([%w]+)$'); -- if first character of |page= is 'e', remove it
if epage and doi:match (epage .. '$') then -- page number match the last characters in |doi=?
return true;
end
local cdpage = page:match ('^cd%d+$'); -- if first characters of |page= are 'CD' and last characters are digits (typically 6 digits)
if cdpage and doi:match (cdpage .. '%.pub%d$') then -- page number matches doi 'CDxxxxxx.pubx' where 'x' is a digit
return true;
end
end
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle;
if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid
NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax
else
NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
end
if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |people= or |credits=; |authors= is deprecated; TODO: constrain |people= and |credits= to cite av media, episode, serial?
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= and |script-chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then -- is there a |contribution= parameter?
Contribution = Chapter; -- get the name of the contribution
elseif 'script-contribution' == ScriptChapter_origin then -- no, so is there a |script-contribution= parameter?
Contribution = ScriptChapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not (utilities.is_set (A['Periodical']) or utilities.is_set (A['ScriptPeriodical'])) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = A:ORIGIN('Periodical');
local ScriptPeriodical = A['ScriptPeriodical'];
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
local TransEncyclopedia = A['TransEncyclopedia'];
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))))
and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
local param;
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = Periodical_origin -- get parameter name for error messaging
elseif utilities.is_set (TransPeriodical) then
TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = TransPeriodical_origin; -- get parameter name for error messaging
elseif utilities.is_set (ScriptPeriodical) then
ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = ScriptPeriodical_origin; -- get parameter name for error messaging
end
if utilities.is_set (param) then -- if we found one
utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message
end
end
if utilities.is_set (Periodical) then
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (A ['MailingList']) then
if utilities.is_set (Periodical) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
end
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = A['Issue'];
elseif utilities.is_set (ScriptPeriodical) and utilities.in_array (ScriptPeriodical_origin, cfg.citation_issue_t) then
Issue = A['Issue'];
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = A['Issue'];
end
end
local ArticleNumber;
if utilities.in_array (config.CitationClass, {'journal', 'conference'})
or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin)) then
ArticleNumber = A['ArticleNumber'];
else
local param_orig = A:ORIGIN ('ArticleNumber');
if utilities.is_set (param_orig) then -- when |article-number= set
utilities.set_message ('err_parameter_ignored', {param_orig}); -- emit an ignored parameter error message
end
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
Issue = utilities.hyphen_to_dash (Issue);
local Page;
local Pages;
local At;
local QuotePage;
local QuotePages;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
QuotePage = A['QuotePage'];
QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
else
local param_orig = first_set ({A:ORIGIN ('Page'), A:ORIGIN ('Pages'), A:ORIGIN ('At'), A:ORIGIN ('QuotePage'), A:ORIGIN ('QuotePages')}, 5);
if param_orig then -- when any of the in-source locator params are set
utilities.set_message ('err_parameter_ignored', {param_orig}); -- emit an ignored parameter error message
end
end
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
local Mode = mode_set (A['Mode'], A:ORIGIN('Mode'));
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
local Quote;
Quote, QuotePage, QuotePages, PostScript = quote_make (A['Quote'], A['TransQuote'], A['ScriptQuote'], QuotePage, QuotePages, NoPP, sepc, PostScript);
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then
local i;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i and (0 < i) then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then
utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'});
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
if 'book' == config.CitationClass or 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
local accept;
PublisherName, accept = utilities.has_accept_as_written (PublisherName); -- check for and remove accept-as-written markup from |publisher= wrapped
if not accept then -- when no accept-as-written markup
check_publisher_name (PublisherName); -- emit maint message when |publisher= might be prefixed with publisher's location
end
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids?
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn', -- if any of the 'periodical' cites except encyclopedia
'map', 'episode'}) or ('conference' == config.CitationClass and utilities.is_set (A['BookTitle'])) or -- {{cite map}} allows |section= but it is alias of |sections= ; {{cite episode}} uses |title= as chapter
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = ''; -- for now, ignore linter warnings
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
end
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering
|encyclopedia= and |article= then map |encyclopedia= to |title= for rendering
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
if utilities.is_set (Encyclopedia) then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
else
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
end
Encyclopedia = nil; -- unset these because not supported by this template
ScriptEncyclopedia = nil;
TransEncyclopedia = nil;
end
elseif utilities.is_set (TransEncyclopedia) then
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
ScriptPeriodical = ScriptEncyclopedia;
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not (utilities.is_set (Chapter) or utilities.is_set (ScriptChapter)) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
ChapterFormat = Format;
if utilities.is_set (TitleLink) then
if utilities.is_set (ChapterURL) then
utilities.set_message ('err_wikilink_in_url');
else
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
end
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
URL = '';
Format = '';
TitleLink = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
ScriptTitle = '';
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
local cs2_lower = function (text) -- if mode is cs2, use lower case
if (sepc ~= '.') then
return text:lower();
end
return text;
end
local use_lowercase = ( sepc == ',' ); -- controls capitalization of certain static text
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map'); -- for now, ignore linter warning
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) then
if not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (Series) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
else
utilities.set_message ('err_wikilink_in_url');
end
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local Year = A['Year'];
if utilities.is_set (Year) then
validation.year_check (Year); -- returns nothing; emits maint message when |year= doesn't hold a 'year' value
end
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
local archive_url_timestamp; -- timestamp from wayback machine url
ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables date_parameters_list, mismatch
local date_parameters_list = { -- AirDate has been promoted to Date so not necessary to check it
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
end
if archive_url_timestamp and utilities.is_set (ArchiveDate) then
validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others?
('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) or -- {{citation}} as an encylopedia citation
('citation' == config.CitationClass and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then -- {{citation}} as a book citation
if utilities.is_set (PublicationPlace) then
if not utilities.is_set (PublisherName) then
local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number
if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later
utilities.set_message ('maint_location_no_publisher'); -- add maint cat
end
else -- PublisherName has a value
if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations)
PublisherName = ''; -- unset
end
end
end
end
local ID_list_t; -- sequence table of rendered identifiers
local ID_list_coins_t; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list_t, ID_list_coins_t = identifiers.identifier_lists_get (args, {
DoiBroken = DoiBroken, -- for |doi=
ASINTLD = A['ASINTLD'], -- for |asin=
Embargo = Embargo, -- for |pmc=
Class = Class, -- for |arxiv=
CitationClass = config.CitationClass, -- for |arxiv=
Year=anchor_year, -- for |isbn=
}, ID_support);
for _, id in ipairs (ID_list_t) do -- search through the ID_list_t sequence looking for an ISBN identifier string
if id:find ('ISBN', 3, true) then -- plain find, start at index 3 ([[ISBN)
if 'citation' == config.CitationClass then -- catch ve/citoid malformed book cites in {{citation}} templates
if utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) then -- when a |work= alias is set
utilities.set_message ('maint_work_isbn'); -- add maint cat
break; -- and abandon
end
elseif ({['journal'] = true, ['magazine'] = true, ['news'] = true, ['web'] = true})[config.CitationClass] then
utilities.set_message ('maint_periodical_has_isbn'); -- add maint cat
break; -- and abandon
end
end
end
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates
if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins_t k/v table here because invalid parameters omitted
args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
if 'journal' == config.CitationClass
or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin)) then
if is_page_art_num (((utilities.is_set (Page) and Page) or (utilities.is_set (Pages) and Pages)) or nil, ID_list_coins_t['DOI']) then -- does |page(s)= look like it holds an article number
utilities.set_message ('maint_page_art_num'); -- add maint cat
end
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then -- should script-params be considered?
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron,
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['ArticleNumber'] = ArticleNumber,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins_t,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal = nil; -- must be intentionally initialized
local Translators; -- assembled translators name list
local translator_etal = nil; -- must be intentionally initialized
local t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal = nil; -- must be intentionally initialized
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e);
control.maximum, editor_etal = get_display_names (display_names, #e, editor_etal, param);
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list);
control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, interviewer_etal, param);
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t);
control.maximum, translator_etal = get_display_names (display_names, #t, translator_etal, param);
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c);
control.maximum, contributor_etal = get_display_names (display_names, #c, contributor_etal, param);
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal);
control.maximum, author_etal = get_display_names (display_names, #a, author_etal, param);
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = utilities.substitute (cfg.messages['collaboration'], {Authors, Collaboration}); -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for {{cite web}}, {{cite podcast}}, and {{cite mailing list}}
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
if not url_was_archive_today then -- is <URL> empty/missing because it was a deprecated archive.today url
utilities.set_message ('err_cite_web_url'); -- no; emit an error message for an empty/ missing |url=
end
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = ''; -- for now, ignore linter warning
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')});
end
Position = utilities.substitute (cfg.messages.minutes, Minutes);
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cs2_lower(cfg.messages['event']);
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, ScriptPeriodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
if utilities.is_set ( Section ) then
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'sections') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'section')});
end
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'] or ''; -- |agency= is supported by {{cite magazine}}, {{cite news}}, {{cite press release}}, {{cite web}}, and certain {{citation}} templates
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
if utilities.in_array (config.CitationClass, {'magazine', 'news', 'pressrelease', 'web'})
or ('citation' == config.CitationClass and (utilities.in_array (Periodical_origin, {"magazine", "newspaper", "work"}) or utilities.in_array (ScriptPeriodical_origin, {"script-magazine", "script-newspaper", "script-work"}))) then
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
else
Agency = ''; -- unset; not supported
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
end
end
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, ScriptPeriodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved'];
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
retrv_text = cs2_lower(retrv_text); -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set
utilities.set_message ('err_archive_missing_date'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
else
if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set
utilities.set_message ('err_archive_date_missing_url'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
end
if utilities.is_set (ArchiveURL) then
if "live" == UrlStatus then
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{ external_link( ArchiveURL, cs2_lower(cfg.messages['archived']), A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-unfit']), ArchiveDate);
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.add_prop_cat ('unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-dead']),
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } );
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher = ''; -- initialize to empty string for concatenation
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName;
else
Publisher = sepc .. " " .. PublisherName;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace;
end
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
else
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
else -- a sheet or stand-alone map
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
else -- all other CS1 templates
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
end
if #ID_list_t > 0 then
ID_list_t = safe_join( { sepc .. " ", table.concat( ID_list_t, sepc .. " " ), ID }, sepc );
else
ID_list_t = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list_t, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc );
else
idcommon = safe_join( { ID_list_t, URL, Archived, AccessDate, Via, Quote }, sepc );
end
local text;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = '';
local post_text;
if utilities.is_set (Chapter) and 0 == #c then
in_text = cfg.messages['in'] .. ' ';
in_text = cs2_lower(in_text); -- lowercase for cs2
end
if EditorCount <= 1 then
post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case
else
post_text = ' (' .. cfg.messages['editors'] .. ')';
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
by_text = cs2_lower(by_text); -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor'];
else
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
if '.' == sepc then -- remove final seperator if present
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
else
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
end
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
local citeref_id;
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
options_t.id = Ref or citeref_id;
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if is_preview_mode and (0 ~= #z.error_msgs_t or 0 ~= #z.maint_cats_t) then -- when in preview mode
if not utilities.is_set (options_t.id) then -- and when this template has not created an anchor ID
math.randomseed (tonumber (mw.getLanguage ('en'):formatDate ('U')) * 10000 + os.clock() * 10000);
options_t.id = 'CITEREF_temp_preview_id_' .. math.random (100000, 999999); -- create temporary anchor ID for preview mode
end
end
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
options_t.id = mw.uri.anchorEncode(options_t.id); -- do this here; also used when adding preview warning messages
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {options_t.id, mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = cfg.citation_class_map_t[config.CitationClass];
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, {template_link, options_t.id}));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, {template_link, options_t.id}));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
local sort_key;
local cat_wikilink = 'cat wikilink';
if cfg.enable_sort_keys then -- when namespace sort keys enabled
local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext
sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace
cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key
end
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
if cfg.id_limits_data_load_fail then -- boolean true when load failed
utilities.set_message ('maint_id_limit_load_fail'); -- done here because this maint cat emits no message
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local enum_name; -- parameter name with enumerator (if any) replaced with '#'
local state;
local function state_test () -- local function to do testing of state values; operates on the upvalues <state> and <name>
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if 'string' ~= type (name) or name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted; positional params are 'number' type; not supported
return nil;
end
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
if 'document' == cite_class then -- special case for {{cite document}}
state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
return false;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates
state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test () then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test () then return true; end
end -- if here, fall into general validation
state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ T W L _ U R L >--------------------------------------------------------
look for The Wikipedia Library urls in url-holding parameters. TWL urls are accessible only for readers who are
active extended confirmed Wikipedia editors. This function sets an error message when such urls are discovered
and when appropriate, sets the |<param>-url-access=subscription. returns nothing.
looks for: '.wikipedialibrary.idm.oclc.org'
]]
local function has_twl_url (url_params_t, cite_args_t)
local url_error_t = {}; -- sequence of url-holding parameters that have a TWL url
for param, value in pairs (url_params_t) do
if value:find ('%.wikipedialibrary%.idm%.oclc%.org') then -- has the TWL base url?
table.insert (url_error_t, param); -- add parameter name to the error list
end
end
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t); -- sor for error messaging
for i, param in ipairs (url_error_t) do
if cfg.url_access_map_t[param] then -- if <param> has a matching -access parameter
cite_args_t[cfg.url_access_map_t[param]] = cfg.keywords_xlate.subscription; -- set |<param>-url-access=subscription
end
url_error_t[i] = utilities.wrap_style ('parameter', param); -- make the parameter pretty for error message
end
utilities.set_message ('err_param_has_twl_url', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< M I S C _ U R L _ D E T E C T >------------------------------------------------
look for miscellaneous urls that might be converted to, or are duplicates of, identifiers.
]]
local misc_url_patterns_t = {
'idm%.oclc%.org', -- but not wikipedialibrary.idm.oclc.org; has_twl_url()
'https?://citeseerx?%.ist%.psu%.edu/', -- simplified so we catch all citeseer and citeseerx urls except ~/document/... (the 'new' form)
}
local ignore_patterns_t = {
'wikipedialibrary.idm.oclc.org', -- handled by has_twl_url()
'https?://citeseerx?%.ist%.psu%.edu/document', -- 'new'-form citeseerx urls that mostly work; ignore for now
}
local function misc_url_detect (url_params_t)
local ignore_flag = false;
for _, value in pairs (url_params_t) do
for _, ignore_pattern in ipairs (ignore_patterns_t) do
if value:find (ignore_pattern) then -- matches this ignore_pattern?
ignore_flag = true; -- found a pattern to ignore
break; --
end
end
if not ignore_flag then -- if ignore_flag is set then don't bother to test this url <value>
for _, misc_pattern in ipairs (misc_url_patterns_t) do
if value:find (misc_pattern) then -- matches this misc_pattern?
utilities.set_message ('maint_misc_url'); -- found one; set the message
return; -- and done; no need to test other <value>s
end
end
end
ignore_flag = false; -- reset
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (non_url_param_t)
local url_error_t = {};
check_for_url (non_url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< _ C I T A T I O N >------------------------------------------------------------
Module entry point
frame – from template call (citation()); may be nil when called from another module
args_t – table of all cs1|2 parameters in the template (the parent frame)
config_t – table of template-supplied parameter (the #invoke frame)
]]
local function _citation (frame, args_t, config_t) -- save a copy in case we need to display an error message in preview mode
if not frame then
frame = mw.getCurrentFrame(); -- if called from another module, get a frame for frame-provided functions
end
-- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here)
local sandbox = ((config_t.SandboxPath and '' ~= config_t.SandboxPath) and config_t.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}}
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
local cite_args_t = {}; -- because args_t is the parent (template) frame args (which cannot be modified); params and their values will be placed here
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs (args_t) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if cfg.enum_needs_xlation and 'string' == type (k) then -- for wikis that set date_names['local_digits'] to non-western digits
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- translate 'local' digits enumerators to Western 0-9
end
if not validate( k, config_t.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config_t.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config_t.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config_t.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
cite_args_t[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config_t.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and cfg.err_msg_supl.empty_str or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
end
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local non_url_param_t = {}; -- table of parameters and values that are not url-holding parameters
local url_param_t = {}; -- table of url-holding paramters and their values
for k, v in pairs (cite_args_t) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
cite_args_t[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) then -- when parameter k is not positional
if not cfg.url_skip[k] then -- and not in url skip table
non_url_param_t[k] = v; -- make a parameter/value list for extraneous url check
else -- and is in url skip table (a url-holding parameter)
url_param_t[k] = v; -- make a parameter/value list to check for values that are The Wikipedia Library url
end
end
end
if cfg.suppress_archive_today_urls then
has_archive_today_url (cite_args_t); -- look for and suppress archive.today urls and dependent parameters for all templates
end
has_extraneous_url (non_url_param_t); -- look for url in parameter values where a url does not belong
has_twl_url (url_param_t, cite_args_t); -- look for url-holding parameters that hold a The Wikipedia Library url
misc_url_detect (url_param_t); -- look for url-holding parameters that hold certain miscellaneous urls
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Citation/CS1' .. sandbox .. '/styles.css'}),
citation0 (config_t, cite_args_t)
});
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
Template entry point
]]
local function citation (frame)
local config_t = {}; -- table to store parameters from the module {{#invoke:}}
local args_t = frame:getParent().args; -- get template's preset parameters
for k, v in pairs (frame.args) do -- get parameters from the {{#invoke}} frame
config_t[k] = v;
-- args_t[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
return _citation (frame, args_t, config_t)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
citation = citation, -- template entry point
_citation = _citation, -- module entry point
}
3oosv6gdshi4e6cm8r0tq8pjoevqbo6
124166
124165
2026-11-09T20:20:37Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Citation/CS1]]
124165
Scribunto
text/plain
require ('strict');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z = {}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- boolean flag so that the category is added only once
local added_vanc_errs; -- boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local added_numeric_name_errs; -- boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered
local added_numeric_name_maint; -- boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
local url_was_archive_today; -- boolean flag set to true when has_archive_today_url() has unset |url= because it held a deprecated archive.today url
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit
(see http://tools.ietf.org/html/rfc952 §GRAMMATICAL HOST TABLE SPECIFICATION §§B. Lexical grammar <name>; see
http://tools.ietf.org/html/rfc1123#section-2). Between the first and last characters the name may use letters,
digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
local sl_domain = domain:match ('([^%.]+)%.[^%.]+$') or domain; -- test the second level domain name; ignore subdomains some (rarely) include chars not letter-digit-hyphen
if not (sl_domain:match ('^%w') and sl_domain:match ('%w$') and -- first and last characters must be letter or digit
sl_domain:match ('^[%w%-]+$')) then -- all other characters must be letters, digits, or hyphen-minus
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
'[%a%d]+%:?' -- IPv6 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('^//%S+') or value:match ('%s//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; authority indicator (//) must be be preceded nothing or by whitespace
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[--------------------------< I S _ A R C H I V E _ T O D A Y _ U R L >--------------------------------------
archive.today (and .ph, .is, .md, .li, .fo, .vn) are deprecated. See Wikipedia:Requests_for_comment/Archive.is_RFC_5
(Special:Permalink/1339352976)
<val> is a string that may or may not be a url
]]
local function is_archive_today_url (val)
if is_parameter_ext_wikilink (val) then -- is <val> a url?
local tld = val:match ('archive%.(%l+)/'); -- get the tld; real archive.today urls have a '/' after the tld
return tld and cfg.archive_today_tlds_t[tld]; -- return true if <tld> is one of the archive.today tlds; nil else
end
end
--[[--------------------------< H A S _ A R C H I V E _ T O D A Y _ U R L >------------------------------------
blank any parameter that holds one of the archive.today tlds (.today, .ph, .is, .md, .li, .fo, .vn) and also
blank parameters that are dependent on the offending parameter.
input <cite_args_t> is a table of all of this template's parameters This function modifies <cite_args_t>
when |url= or its alias |URL= hold an archive.today url, this function sets the flag <url_was_archive_today>
which is used later to suppress the missing url error message from {{citation}} when it has |website=<summat>
or from the templates {{cite web}}, {{cite podcast}}, {{cite mailing list}} which all require a url.
returns nothing
]]
local function has_archive_today_url (cite_args_t)
local unset_params_t = {}; -- to hold a sequence of parameters to unset from cite_args_t
for p, v in pairs (cite_args_t) do -- look at each parameter in the template
if is_archive_today_url (v:lower()) then -- if it has a parameter with an archive.today url
table.insert (unset_params_t, p); -- add the url-holding parameter name to our list of parameters to unset (may or may not be a legitimate url parameter)
if 'url' == p:lower() then -- if this parameter is |url= or |URL=
url_was_archive_today = true; -- set a flag so that cite web / podcast / mailinglist don't emit a missing url error message
end
if p:match ('archive%-?url') and ('usurped' == cite_args_t['url-status'] or 'unfit' == cite_args_t['url-status']) then -- if |archive-url=archive.today and |url-status=unfit/usurped
url_was_archive_today = true; -- set a flag so that cite web / podcast / mailinglist don't emit a missing url error message
table.insert (unset_params_t, 'url'); -- add the url parameter name to our list of parameters to unset (may or may not be a legitimate url parameter)
table.insert (unset_params_t, 'URL'); -- this one because both are possible
utilities.set_message ('err_url_suppressed'); -- emit supplemental error message
end
if cfg.dependencies_t[p] then -- if this url-holding parameter (<p>) has dependencies
for _, dependent in ipairs (cfg.dependencies_t[p]) do -- loop through the url-holding parameter's dependency sequence
table.insert (unset_params_t, dependent); -- add dependent parameter to the list to be unset
end
end
end
end
if 0 < #unset_params_t then -- when there are parameters to unset
if not is_preview_mode then -- when in preview mode do not suppress any parameters
for _, unset_param in ipairs (unset_params_t) do -- loop through the sequence
cite_args_t[unset_param] = nil; -- and unset the url-holding parameter and its dependent parameters to avoid parameter-requires-other-parameter errors
end
end
utilities.set_message ('maint_deprecated_archive'); -- add a maintenance message
end
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
local cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
utilities.set_message ('err_trans_missing_title', {trans_chapter_source:match ('trans%-?(.+)')}); -- when no chapter, get matching name from trans-<param>
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if utilities.in_array(capture, {'nowiki', 'math', 'templatestyles'}) then -- nowiki, math and templatestyles stripmarkers (not an error condition)
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset; for now, ignore linter warning
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = utilities.substitute (cfg.messages.invisible_1, {capture, char_name}); -- <capture> here is stripmarker name
else
err_msg = utilities.substitute (cfg.messages.invisible_2, char_name);
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded; for now, ignore linter warning
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local v;
local list = cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap;
local cap2;
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
local comp; -- what does 'comp' mean?
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
local trim = false;
local end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials (first, position)
if first:find (',', 1, true) then
return first; -- commas not allowed; abandon
end
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials_t = {}; -- table to hold initials
local i = 1; -- counter for number of initials
local names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
while names_t[i] do -- loop through the sequence
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
end
i = i + 1; -- bump the counter
end
return table.concat (initials_t); -- Vancouver format does not include spaces.
end
--[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >----------------------------------
extract interwiki prefixen from <value>. Returns two one or two values:
false – no prefixen
nil – prefix exists but not recognized
project prefix, language prefix – when value has either of:
:<project>:<language>:<article>
:<language>:<project>:<article>
project prefix, nil – when <value> has only a known single-letter prefix
nil, language prefix – when <value> has only a known language prefix
accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this
writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and
v (wikiversity)) are not supported.
]]
local function interwiki_prefixen_get (value, is_link)
if not value:find (':%l+:') then -- if no prefix
return false; -- abandon; boolean here to distinguish from nil fail returns later
end
local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen
'^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes
'^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes
'^%[%[:([dsw]):', -- wikilinked; project prefix
'^%[%[:(%l%l+):', -- wikilinked; language prefix
}
local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen
'^:([dsw]):(%l%l+):', -- project and language prefixes
'^:(%l%l+):([dsw]):', -- language and project prefixes
'^:([dsw]):', -- project prefix
'^:(%l%l+):', -- language prefix
}
local cap1, cap2;
for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do
cap1, cap2 = value:match (pattern);
if cap1 then
break; -- found a match so stop looking
end
end
if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed)
if 1 == #cap1 then -- length == 1 then :project:language:
if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map?
return cap1, cap2; -- return interwiki project and interwiki language
end
else -- here when :language:project:
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return cap2, cap1; -- return interwiki project and interwiki language
end
end
return nil; -- unknown interwiki language
elseif not (cap1 or cap2) then -- both are nil?
return nil; -- we got something that looks like a project prefix but isn't; return fail
elseif 1 == #cap1 then -- here when one capture
return cap1, nil; -- length is 1 so return project, nil language
else -- here when one capture and its length it more than 1
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return nil, cap1; -- return nil project, language
end
end
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present
if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then
proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat?
end
if proj then
local proj_name = ({['d'] = cfg.messages.wikidata, ['s'] = cfg.messages.wikisource, ['w'] = cfg.messages.wikipedia})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj_name then
one = one .. utilities.wrap_style ('interproj', proj_name); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interproj-linked-name', proj); -- categorize it; <proj> is sort key
tag = nil; -- unset; don't do both project and language
end
end
if tag == cfg.this_wiki_code then
tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat?
end
if tag then
local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag];
if lang then -- error messaging done in extract_names() where we know parameter names
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
utilities.add_prop_cat ('interwiki-linked-name', tag); -- categorize it; <tag> is sort key
end
end
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add an error message and category when <name> parameter value does not contain letters.
Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are
not numeric characters; could be letters and/or punctuation characters.
This function will only emit one error and one maint message for the current template. Does not emit both error
and maint messages/categories for the same parameter value.
returns nothing
]]
local function name_is_numeric (name, name_alias, list_name)
local patterns = {
'^%D+%d', -- <name> must have digits preceded by other characters
'^%D*%d+%D+', -- <name> must have digits followed by other characters
}
if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters
utilities.set_message ('err_numeric_names', name_alias); -- add an error message
added_numeric_name_errs = true; -- set the flag so we emit only one error message
return; -- when here no point in further testing; abandon
end
if not added_numeric_name_maint then -- if we have already set a maint message
for _, pattern in ipairs (patterns) do -- spin through list of patterns
if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
added_numeric_name_maint = true; -- set the flag so we emit only one maint message
return; -- when here no point in further testing; abandon
end
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
Same test for first except that commas should not appear in given names (MOS:JR says
that the generational suffix does not take a separator character). Titles, degrees,
postnominals, affiliations, all normally comma separated don't belong in a citation.
<name> – name parameter value
<list_name> – AuthorList, EditorList, etc
<limit> – number of allowed commas; 1 (default) for surnames; 0 for given names
returns nothing
]]
local function name_has_mult_names (name, list_name, limit)
local _, commas, semicolons, nbsps;
limit = limit and limit or 1;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if limit < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value)
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter
name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name
name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name
local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only
end
end
if link then -- error check |linkn= alias for unknown interwiki link prefix
local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
link = nil; -- unset so we don't link
link_alias = nil;
end
end
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_tag_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn
end
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags that MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag; for now, ignore linter warning
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (" " .. wrap_msg ('language', name)); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
This function sets an error message when |display-xxxxors= value greater than or equal to number of names but
not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the
keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected
that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}.
]]
local function get_display_names (max, count, etal, param)
if utilities.is_set (max) then
if 'etal' == cfg.keywords_xlate[max:lower():gsub("[ '%.]", '')] then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
and |issue=.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
numero sign U+2116.
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
local accept_val; -- for now, ignore linter warning
val, accept_val = utilities.has_accept_as_written (val);
--if accept_val then -- if uncomment this, |volume=((vol. 1)) suppresses error
-- return;
--end
--val = mw.text.unstripNoWiki (val); -- if uncomment this, |volume=<nowiki>vol. 1</nowiki> shows error
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local _, accept = utilities.has_accept_as_written (vparam);
if accept then
utilities.add_prop_cat ('vanc-accept'); -- add properties category
end
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirst_t = mw.text.split(v_name, "%s+");
first = table.remove (lastfirst_t); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove (lastfirst_t); -- get what should be the initials from the table
end
last = table.concat (lastfirst_t, ' '); -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
utilities.set_message ('err_redundant_parameters',
utilities.substitute (cfg.special_case_translation.name_list_params,
('AuthorList' == list_name) and cfg.special_case_translation.author or cfg.special_case_translation.editor)); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >-----------------------------------------
returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single
string; or formatted volume or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, article, cite_class, origin, script_origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and ('journal' == origin or 'script-journal' == script_origin));
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '')
vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '')
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites
if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number
return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower);
elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below
return wrap_msg ('art', {sepc, article}, lower);
end
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, script_origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin or 'script-journal' == script_origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin or 'script-journal' == script_origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and ('journal' == origin or 'script-journal' == script_origin));
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
A secondary function is to return an archive-url timestamp from those archive urls that have them. The timestamp
is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the
archive url.
]=]
local function archive_url_check (url, date)
local err_msg; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
local function is_ts_date_valid (ts, origin_date) -- local function to validate archive url taimestamp date; time ignored
local y, m, d = ts:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- split into parts
if y and validation.is_valid_date (y, m, d) and (tonumber (y) >= 1996) then
return true, tonumber (y) >= origin_date; -- <origin_date> is 1996 for archive.org
end
end
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif not is_ts_date_valid (timestamp, 1996) then -- is ymd portion of timestamp a valid date?
err_msg = cfg.err_msg_supl.timestamp;
timestamp = nil; -- unset because invalid
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting.
When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string,
special handling is required.
When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND:
the number of names specified by <number_of_names> is:
greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>)
use global |display-<namelist>= parameter value
set overridden maint category
less than or equal to the number specified in the global |display-<namelist>= parameter
use local |display-<namelist>= parameter value
The purpose of this function is to prevent categorizing a template that has fewer names than the global setting
to keep the etal annotation specified by <local_display_names>.
]]
local function display_names_select (global_display_names, local_display_names, param_name, number_of_names)
if global_display_names and utilities.is_set (local_display_names) then -- when both
if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison
local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits
if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed?
utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control
end
end
-- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls
utilities.set_message ('maint_overridden_setting'); -- set a maint message
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
end
-- here when only one of <global_display_names> or <local_display_names> set
if global_display_names then
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local
end
end
--[[--------------------------< M O D E _ S E T >--------------------------------------------------------------
fetch global mode setting from {{cs1 config}} (if present) or from |mode= (if present); global setting overrides
local |mode= parameter value. When both are present, emit maintenance message
]]
local function mode_set (Mode, Mode_origin)
local mode;
if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}}; nil when empty or assigned value invalid
mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax
else
mode = is_valid_parameter_value (Mode, Mode_origin, cfg.keywords_lists['mode'], '');
end
if cfg.global_cs1_config_t['Mode'] and utilities.is_set (Mode) then -- when template has |mode=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
return mode;
end
--[[--------------------------< Q U O T E _ M A K E >----------------------------------------------------------
create quotation from |quote=, |trans-quote=, and/or script-quote= with or without |quote-page= or |quote-pages=
when any of those three quote parameters are set, this function unsets <PostScript>. When none of those parameters
are set, |quote-page= and |quote-pages= are unset to nil so that they are not included in the template's metadata
]]
local function quote_make (quote, trans_quote, script_quote, quote_page, quote_pages, nopp, sepc, postscript)
if utilities.is_set (quote) or utilities.is_set (trans_quote) or utilities.is_set (script_quote) then
if utilities.is_set (quote) then
if quote:sub(1, 1) == '"' and quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
quote = quote:sub(2, -2); -- strip them off
end
end
quote = kern_quotes (quote); -- kern if needed
quote = utilities.wrap_style ('quoted-text', quote ); -- wrap in <q>...</q> tags
if utilities.is_set (script_quote) then
quote = script_concatenate (quote, script_quote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (trans_quote) then
if trans_quote:sub(1, 1) == '"' and trans_quote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
trans_quote = trans_quote:sub(2, -2); -- strip them off
end
quote = quote .. " " .. utilities.wrap_style ('trans-quoted-title', trans_quote );
end
if utilities.is_set (quote_page) or utilities.is_set (quote_pages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (quote_page) then
extra_text_in_page_check (quote_page, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not nopp then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_page});
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_page});
end
elseif utilities.is_set (quote_pages) then
extra_text_in_page_check (quote_pages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(quote_pages) ~= nil and not nopp then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, quote_pages});
elseif not nopp then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, quote_pages});
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, quote_pages});
end
end
quote = quote_prefix .. ": " .. quote;
else
quote = sepc .. " " .. quote;
end
postscript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
elseif utilities.is_set (quote_page) or utilities.is_set (quote_pages) then
quote_page = nil; -- unset; these require |quote=; TODO: error message?
quote_pages = nil;
end
return quote, quote_page, quote_pages, postscript;
end
--[[--------------------------< C H E C K _ P U B L I S H E R _ N A M E >--------------------------------------
look for variations of '<text>: <text>' that might be '<location>: <publisher>' in |publisher= parameter value.
when found, emit a maintenance message; return nil else
<publisher> is the value assigned to |publisher= or |institution=
]]
local function check_publisher_name (publisher)
local patterns_t = {
'^[%w%s]+%s*:%s*[%w%s]+$', -- plain text <location>: <publisher>
'^%[+[%w%s:|]+%]+%s*:%s*[%w%s]+$', -- partially wikilinked [[<location>]]: <publisher>
'^[%w%s]+%s*:%s*%[+[%w%s:|]+%]+$', -- partially wikilinked <location>: [[<publisher>]]
'^%[+[%w%s:|]+%]+%s*:%s*%[+[%w%s:|]+%]+$', -- wikilinked [[<location>]]: [[<publisher>]]
}
for _, pattern in ipairs (patterns_t) do -- spin through the patterns_t sequence
if mw.ustring.match (publisher, pattern) then -- does this pattern match?
utilities.set_message ('maint_publisher_location'); -- set a maint message
return; -- and done
end
end
end
--[[--------------------------< I S _ P A G E _ A R T _ N U M >------------------------------------------------
compare the trailing (rightmost) characters of the |doi= value against the whole value assigned to |page(s)=.
return boolean true when:
|page(s)= has exactly 8 digits and a dot between the fourth and fifth digits matches the trailing 9 characters
of the |doi= value: |page=12345678 → |page=1234.5678 matches |doi=10.xxxx/yyyy1234.5678
|page(s)= is 5 or more characters and matches |doi= values's trailing characters
|page(s)= begins with a lowercase 'e' and |page(s)= without the 'e' matches |doi= values's trailing
characters: |page=e12345 → |page=12345 matches |doi=10.xxxx/yyyy12345
|page(s)= begins with a uppercase 'CD' followed by (typically) six digits matches |doi= values that ends with
'CDxxxxxx.pubx' (where 'x' is any single digit)
return nil when |page(s)= values:
are ranges separated by underscore, hyphen, emdash, endash, figure dash, or minus character
are comma- or semicolon-separated lists of pages
have external urls (has text 'http')
are digit-only values less than 10000
do not match |doi= values's trailing characters
]]
local function is_page_art_num (page, doi)
if not (utilities.is_set (page) and utilities.is_set (doi)) then -- both required
return; -- abandon; nothing to do
end
if page:match ('[,;_−–—‒%-]') then -- when |page(s)= might be a page range or a separated list of pages
return; -- abandon
end
page = page:lower(); -- because doi names are case insensitive
doi = doi:lower(); -- force these to lowercase for testing
if page:match ('http') then -- when |page(s)= appears to hold a url
return; -- abandon
end
if tonumber (page) then -- is |page(s)= digits only
if 10000 > tonumber (page) then -- when |page(s)= less than 10000
return; -- abandon
end
if doi:match (page .. '$') then -- digits only page number match the last digits in |doi=?
return true;
end
if 8 == page:len() then -- special case when |page(s)= is exactly 8 digits
local dot_page = page:gsub ('(%d%d%d%d)(%d%d%d%d)', '%1.%2'); -- make a |page=xxxx.yyyy version commonly used in |doi=
if doi:match (dot_page .. '$') then -- 8-digit dotted page number match the last characters in |doi=?
return true;
end
end
else -- here when |page(s)= is alpha-numeric
if 4 < page:len() then -- when |page(s)= is five or more characters
if doi:match (page .. '$') then -- alpha-numeric page match the last characters in |doi=?
return true;
end
local epage = page:match ('^e([%w]+)$'); -- if first character of |page= is 'e', remove it
if epage and doi:match (epage .. '$') then -- page number match the last characters in |doi=?
return true;
end
local cdpage = page:match ('^cd%d+$'); -- if first characters of |page= are 'CD' and last characters are digits (typically 6 digits)
if cdpage and doi:match (cdpage .. '%.pub%d$') then -- page number matches doi 'CDxxxxxx.pubx' where 'x' is a digit
return true;
end
end
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle;
if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid
NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax
else
NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
end
if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |people= or |credits=; |authors= is deprecated; TODO: constrain |people= and |credits= to cite av media, episode, serial?
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= and |script-chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then -- is there a |contribution= parameter?
Contribution = Chapter; -- get the name of the contribution
elseif 'script-contribution' == ScriptChapter_origin then -- no, so is there a |script-contribution= parameter?
Contribution = ScriptChapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not (utilities.is_set (A['Periodical']) or utilities.is_set (A['ScriptPeriodical'])) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = A:ORIGIN('Periodical');
local ScriptPeriodical = A['ScriptPeriodical'];
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
local TransEncyclopedia = A['TransEncyclopedia'];
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))))
and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
local param;
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = Periodical_origin -- get parameter name for error messaging
elseif utilities.is_set (TransPeriodical) then
TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = TransPeriodical_origin; -- get parameter name for error messaging
elseif utilities.is_set (ScriptPeriodical) then
ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = ScriptPeriodical_origin; -- get parameter name for error messaging
end
if utilities.is_set (param) then -- if we found one
utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message
end
end
if utilities.is_set (Periodical) then
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (A ['MailingList']) then
if utilities.is_set (Periodical) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
end
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = A['Issue'];
elseif utilities.is_set (ScriptPeriodical) and utilities.in_array (ScriptPeriodical_origin, cfg.citation_issue_t) then
Issue = A['Issue'];
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = A['Issue'];
end
end
local ArticleNumber;
if utilities.in_array (config.CitationClass, {'journal', 'conference'})
or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin)) then
ArticleNumber = A['ArticleNumber'];
else
local param_orig = A:ORIGIN ('ArticleNumber');
if utilities.is_set (param_orig) then -- when |article-number= set
utilities.set_message ('err_parameter_ignored', {param_orig}); -- emit an ignored parameter error message
end
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
Issue = utilities.hyphen_to_dash (Issue);
local Page;
local Pages;
local At;
local QuotePage;
local QuotePages;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
QuotePage = A['QuotePage'];
QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
else
local param_orig = first_set ({A:ORIGIN ('Page'), A:ORIGIN ('Pages'), A:ORIGIN ('At'), A:ORIGIN ('QuotePage'), A:ORIGIN ('QuotePages')}, 5);
if param_orig then -- when any of the in-source locator params are set
utilities.set_message ('err_parameter_ignored', {param_orig}); -- emit an ignored parameter error message
end
end
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
local Mode = mode_set (A['Mode'], A:ORIGIN('Mode'));
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
local Quote;
Quote, QuotePage, QuotePages, PostScript = quote_make (A['Quote'], A['TransQuote'], A['ScriptQuote'], QuotePage, QuotePages, NoPP, sepc, PostScript);
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then
local i;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i and (0 < i) then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then
utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'});
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
if 'book' == config.CitationClass or 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
local accept;
PublisherName, accept = utilities.has_accept_as_written (PublisherName); -- check for and remove accept-as-written markup from |publisher= wrapped
if not accept then -- when no accept-as-written markup
check_publisher_name (PublisherName); -- emit maint message when |publisher= might be prefixed with publisher's location
end
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids?
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn', -- if any of the 'periodical' cites except encyclopedia
'map', 'episode'}) or ('conference' == config.CitationClass and utilities.is_set (A['BookTitle'])) or -- {{cite map}} allows |section= but it is alias of |sections= ; {{cite episode}} uses |title= as chapter
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = ''; -- for now, ignore linter warnings
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
end
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering
|encyclopedia= and |article= then map |encyclopedia= to |title= for rendering
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
if utilities.is_set (Encyclopedia) then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
else
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
end
Encyclopedia = nil; -- unset these because not supported by this template
ScriptEncyclopedia = nil;
TransEncyclopedia = nil;
end
elseif utilities.is_set (TransEncyclopedia) then
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
ScriptPeriodical = ScriptEncyclopedia;
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not (utilities.is_set (Chapter) or utilities.is_set (ScriptChapter)) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
ChapterFormat = Format;
if utilities.is_set (TitleLink) then
if utilities.is_set (ChapterURL) then
utilities.set_message ('err_wikilink_in_url');
else
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
end
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
URL = '';
Format = '';
TitleLink = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
ScriptTitle = '';
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
local cs2_lower = function (text) -- if mode is cs2, use lower case
if (sepc ~= '.') then
return text:lower();
end
return text;
end
local use_lowercase = ( sepc == ',' ); -- controls capitalization of certain static text
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map'); -- for now, ignore linter warning
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) then
if not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (Series) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
else
utilities.set_message ('err_wikilink_in_url');
end
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local Year = A['Year'];
if utilities.is_set (Year) then
validation.year_check (Year); -- returns nothing; emits maint message when |year= doesn't hold a 'year' value
end
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
local archive_url_timestamp; -- timestamp from wayback machine url
ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables date_parameters_list, mismatch
local date_parameters_list = { -- AirDate has been promoted to Date so not necessary to check it
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
end
if archive_url_timestamp and utilities.is_set (ArchiveDate) then
validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others?
('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) or -- {{citation}} as an encylopedia citation
('citation' == config.CitationClass and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then -- {{citation}} as a book citation
if utilities.is_set (PublicationPlace) then
if not utilities.is_set (PublisherName) then
local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number
if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later
utilities.set_message ('maint_location_no_publisher'); -- add maint cat
end
else -- PublisherName has a value
if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations)
PublisherName = ''; -- unset
end
end
end
end
local ID_list_t; -- sequence table of rendered identifiers
local ID_list_coins_t; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list_t, ID_list_coins_t = identifiers.identifier_lists_get (args, {
DoiBroken = DoiBroken, -- for |doi=
ASINTLD = A['ASINTLD'], -- for |asin=
Embargo = Embargo, -- for |pmc=
Class = Class, -- for |arxiv=
CitationClass = config.CitationClass, -- for |arxiv=
Year=anchor_year, -- for |isbn=
}, ID_support);
for _, id in ipairs (ID_list_t) do -- search through the ID_list_t sequence looking for an ISBN identifier string
if id:find ('ISBN', 3, true) then -- plain find, start at index 3 ([[ISBN)
if 'citation' == config.CitationClass then -- catch ve/citoid malformed book cites in {{citation}} templates
if utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) then -- when a |work= alias is set
utilities.set_message ('maint_work_isbn'); -- add maint cat
break; -- and abandon
end
elseif ({['journal'] = true, ['magazine'] = true, ['news'] = true, ['web'] = true})[config.CitationClass] then
utilities.set_message ('maint_periodical_has_isbn'); -- add maint cat
break; -- and abandon
end
end
end
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates
if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins_t k/v table here because invalid parameters omitted
args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
if 'journal' == config.CitationClass
or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin)) then
if is_page_art_num (((utilities.is_set (Page) and Page) or (utilities.is_set (Pages) and Pages)) or nil, ID_list_coins_t['DOI']) then -- does |page(s)= look like it holds an article number
utilities.set_message ('maint_page_art_num'); -- add maint cat
end
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then -- should script-params be considered?
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron,
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['ArticleNumber'] = ArticleNumber,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins_t,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal = nil; -- must be intentionally initialized
local Translators; -- assembled translators name list
local translator_etal = nil; -- must be intentionally initialized
local t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal = nil; -- must be intentionally initialized
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e);
control.maximum, editor_etal = get_display_names (display_names, #e, editor_etal, param);
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list);
control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, interviewer_etal, param);
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t);
control.maximum, translator_etal = get_display_names (display_names, #t, translator_etal, param);
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c);
control.maximum, contributor_etal = get_display_names (display_names, #c, contributor_etal, param);
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal);
control.maximum, author_etal = get_display_names (display_names, #a, author_etal, param);
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = utilities.substitute (cfg.messages['collaboration'], {Authors, Collaboration}); -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for {{cite web}}, {{cite podcast}}, and {{cite mailing list}}
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
if not url_was_archive_today then -- is <URL> empty/missing because it was a deprecated archive.today url
utilities.set_message ('err_cite_web_url'); -- no; emit an error message for an empty/ missing |url=
end
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if 'live' ~= UrlStatus then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if 'live' ~= UrlStatus then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) then
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not (utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia))) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = ''; -- for now, ignore linter warning
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')});
end
Position = utilities.substitute (cfg.messages.minutes, Minutes);
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cs2_lower(cfg.messages['event']);
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, ScriptPeriodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
if utilities.is_set ( Section ) then
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'sections') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'section')});
end
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'] or ''; -- |agency= is supported by {{cite magazine}}, {{cite news}}, {{cite press release}}, {{cite web}}, and certain {{citation}} templates
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
if utilities.in_array (config.CitationClass, {'magazine', 'news', 'pressrelease', 'web'})
or ('citation' == config.CitationClass and (utilities.in_array (Periodical_origin, {"magazine", "newspaper", "work"}) or utilities.in_array (ScriptPeriodical_origin, {"script-magazine", "script-newspaper", "script-work"}))) then
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
else
Agency = ''; -- unset; not supported
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
end
end
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, ScriptPeriodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved'];
AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
retrv_text = cs2_lower(retrv_text); -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set
utilities.set_message ('err_archive_missing_date'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
else
if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set
utilities.set_message ('err_archive_date_missing_url'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
end
if utilities.is_set (ArchiveURL) then
if "live" == UrlStatus then
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{ external_link( ArchiveURL, cs2_lower(cfg.messages['archived']), A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-unfit']), ArchiveDate);
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.add_prop_cat ('unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cs2_lower(cfg.messages['archived-dead']),
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } );
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher = ''; -- initialize to empty string for concatenation
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName;
else
Publisher = sepc .. " " .. PublisherName;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace;
end
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
else
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
else -- a sheet or stand-alone map
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
else -- all other CS1 templates
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
end
if #ID_list_t > 0 then
ID_list_t = safe_join( { sepc .. " ", table.concat( ID_list_t, sepc .. " " ), ID }, sepc );
else
ID_list_t = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list_t, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc );
else
idcommon = safe_join( { ID_list_t, URL, Archived, AccessDate, Via, Quote }, sepc );
end
local text;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = '';
local post_text;
if utilities.is_set (Chapter) and 0 == #c then
in_text = cfg.messages['in'] .. ' ';
in_text = cs2_lower(in_text); -- lowercase for cs2
end
if EditorCount <= 1 then
post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case
else
post_text = ' (' .. cfg.messages['editors'] .. ')';
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
by_text = cs2_lower(by_text); -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor'];
else
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
if '.' == sepc then -- remove final seperator if present
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
else
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
end
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local namelist_t = {}; -- holds selected contributor, author, editor name list
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
local citeref_id;
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
options_t.id = Ref or citeref_id;
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if is_preview_mode and (0 ~= #z.error_msgs_t or 0 ~= #z.maint_cats_t) then -- when in preview mode
if not utilities.is_set (options_t.id) then -- and when this template has not created an anchor ID
math.randomseed (tonumber (mw.getLanguage ('en'):formatDate ('U')) * 10000 + os.clock() * 10000);
options_t.id = 'CITEREF_temp_preview_id_' .. math.random (100000, 999999); -- create temporary anchor ID for preview mode
end
end
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
options_t.id = mw.uri.anchorEncode(options_t.id); -- do this here; also used when adding preview warning messages
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {options_t.id, mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = cfg.citation_class_map_t[config.CitationClass];
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, {template_link, options_t.id}));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, {template_link, options_t.id}));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
local sort_key;
local cat_wikilink = 'cat wikilink';
if cfg.enable_sort_keys then -- when namespace sort keys enabled
local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext
sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace
cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key
end
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
if cfg.id_limits_data_load_fail then -- boolean true when load failed
utilities.set_message ('maint_id_limit_load_fail'); -- done here because this maint cat emits no message
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
for _, v in ipairs (z.prop_cats_t) do -- append properties categories
table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local enum_name; -- parameter name with enumerator (if any) replaced with '#'
local state;
local function state_test () -- local function to do testing of state values; operates on the upvalues <state> and <name>
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if 'string' ~= type (name) or name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted; positional params are 'number' type; not supported
return nil;
end
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
if 'document' == cite_class then -- special case for {{cite document}}
state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
return false;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates
state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test () then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test () then return true; end
end -- if here, fall into general validation
state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters
if true == state_test () then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ T W L _ U R L >--------------------------------------------------------
look for The Wikipedia Library urls in url-holding parameters. TWL urls are accessible only for readers who are
active extended confirmed Wikipedia editors. This function sets an error message when such urls are discovered
and when appropriate, sets the |<param>-url-access=subscription. returns nothing.
looks for: '.wikipedialibrary.idm.oclc.org'
]]
local function has_twl_url (url_params_t, cite_args_t)
local url_error_t = {}; -- sequence of url-holding parameters that have a TWL url
for param, value in pairs (url_params_t) do
if value:find ('%.wikipedialibrary%.idm%.oclc%.org') then -- has the TWL base url?
table.insert (url_error_t, param); -- add parameter name to the error list
end
end
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t); -- sor for error messaging
for i, param in ipairs (url_error_t) do
if cfg.url_access_map_t[param] then -- if <param> has a matching -access parameter
cite_args_t[cfg.url_access_map_t[param]] = cfg.keywords_xlate.subscription; -- set |<param>-url-access=subscription
end
url_error_t[i] = utilities.wrap_style ('parameter', param); -- make the parameter pretty for error message
end
utilities.set_message ('err_param_has_twl_url', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< M I S C _ U R L _ D E T E C T >------------------------------------------------
look for miscellaneous urls that might be converted to, or are duplicates of, identifiers.
]]
local misc_url_patterns_t = {
'idm%.oclc%.org', -- but not wikipedialibrary.idm.oclc.org; has_twl_url()
'https?://citeseerx?%.ist%.psu%.edu/', -- simplified so we catch all citeseer and citeseerx urls except ~/document/... (the 'new' form)
}
local ignore_patterns_t = {
'wikipedialibrary.idm.oclc.org', -- handled by has_twl_url()
'https?://citeseerx?%.ist%.psu%.edu/document', -- 'new'-form citeseerx urls that mostly work; ignore for now
}
local function misc_url_detect (url_params_t)
local ignore_flag = false;
for _, value in pairs (url_params_t) do
for _, ignore_pattern in ipairs (ignore_patterns_t) do
if value:find (ignore_pattern) then -- matches this ignore_pattern?
ignore_flag = true; -- found a pattern to ignore
break; --
end
end
if not ignore_flag then -- if ignore_flag is set then don't bother to test this url <value>
for _, misc_pattern in ipairs (misc_url_patterns_t) do
if value:find (misc_pattern) then -- matches this misc_pattern?
utilities.set_message ('maint_misc_url'); -- found one; set the message
return; -- and done; no need to test other <value>s
end
end
end
ignore_flag = false; -- reset
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (non_url_param_t)
local url_error_t = {};
check_for_url (non_url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< _ C I T A T I O N >------------------------------------------------------------
Module entry point
frame – from template call (citation()); may be nil when called from another module
args_t – table of all cs1|2 parameters in the template (the parent frame)
config_t – table of template-supplied parameter (the #invoke frame)
]]
local function _citation (frame, args_t, config_t) -- save a copy in case we need to display an error message in preview mode
if not frame then
frame = mw.getCurrentFrame(); -- if called from another module, get a frame for frame-provided functions
end
-- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here)
local sandbox = ((config_t.SandboxPath and '' ~= config_t.SandboxPath) and config_t.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}}
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
local cite_args_t = {}; -- because args_t is the parent (template) frame args (which cannot be modified); params and their values will be placed here
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs (args_t) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if cfg.enum_needs_xlation and 'string' == type (k) then -- for wikis that set date_names['local_digits'] to non-western digits
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- translate 'local' digits enumerators to Western 0-9
end
if not validate( k, config_t.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config_t.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config_t.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config_t.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
cite_args_t[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config_t.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and cfg.err_msg_supl.empty_str or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
end
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local non_url_param_t = {}; -- table of parameters and values that are not url-holding parameters
local url_param_t = {}; -- table of url-holding paramters and their values
for k, v in pairs (cite_args_t) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
cite_args_t[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) then -- when parameter k is not positional
if not cfg.url_skip[k] then -- and not in url skip table
non_url_param_t[k] = v; -- make a parameter/value list for extraneous url check
else -- and is in url skip table (a url-holding parameter)
url_param_t[k] = v; -- make a parameter/value list to check for values that are The Wikipedia Library url
end
end
end
if cfg.suppress_archive_today_urls then
has_archive_today_url (cite_args_t); -- look for and suppress archive.today urls and dependent parameters for all templates
end
has_extraneous_url (non_url_param_t); -- look for url in parameter values where a url does not belong
has_twl_url (url_param_t, cite_args_t); -- look for url-holding parameters that hold a The Wikipedia Library url
misc_url_detect (url_param_t); -- look for url-holding parameters that hold certain miscellaneous urls
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Citation/CS1' .. sandbox .. '/styles.css'}),
citation0 (config_t, cite_args_t)
});
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
Template entry point
]]
local function citation (frame)
local config_t = {}; -- table to store parameters from the module {{#invoke:}}
local args_t = frame:getParent().args; -- get template's preset parameters
for k, v in pairs (frame.args) do -- get parameters from the {{#invoke}} frame
config_t[k] = v;
-- args_t[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
return _citation (frame, args_t, config_t)
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
citation = citation, -- template entry point
_citation = _citation, -- module entry point
}
3oosv6gdshi4e6cm8r0tq8pjoevqbo6
Module:Citation/CS1/Configuration
828
12882
124167
118668
2026-11-07T20:03:20Z
en>Trappist the monk
0
synch from sandbox;
124167
Scribunto
text/plain
local lang_obj = mw.getContentLanguage(); -- make a language object for the local language; used here for languages and dates
--[[--------------------------< S E T T I N G S >--------------------------------------------------------------
boolean settings used to control various things. these setting located here to make them easy to find
]]
-- these settings local to this module only
local local_digits_from_mediawiki = false; -- for i18n; when true, module fills date_names['local_digits'] from MediaWiki; manual fill required else; always false at en.wiki
-- these settings exported to other modules
local use_identifier_redirects = true; -- when true use redirect name for identifier label links; always true at en.wiki
local local_lang_cat_enable = false; -- when true categorizes pages where |language=<local wiki's language>; always false at en.wiki
local date_name_auto_xlate_enable = false; -- when true translates English month-names to the local-wiki's language month names; always false at en.wiki
local date_digit_auto_xlate_enable = false; -- when true translates Western date digit to the local-wiki's language digits (date_names['local_digits']); always false at en.wiki
local enable_sort_keys = true; -- when true module adds namespace sort keys to error and maintenance category links
local suppress_archive_today_urls = true; -- when true module suppresses all parameters with an archive.today url and any deprendent parameters
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E S >------------------------------
List of namespaces identifiers for namespaces that will not be included in citation error categories.
Same as setting notracking = true by default.
For wikis that have a current version of Module:cs1 documentation support, this #invoke will return an unordered
list of namespace names and their associated identifiers:
{{#invoke:cs1 documentation support|uncategorized_namespace_lister|all=<anything>}}
]]
local uncategorized_namespaces_t = {[2]=true}; -- init with user namespace id
for k, _ in pairs (mw.site.talkNamespaces) do -- add all talk namespace ids
uncategorized_namespaces_t[k] = true;
end
local uncategorized_subpages = {'/[Ss]andbox', '/[Tt]estcases', '/[^/]*[Ll]og', '/[Aa]rchive'}; -- list of Lua patterns found in page names of pages we should not categorize
--[[
at en.wiki Greek characters are used as sort keys for certain items in a category so that those items are
placed at the end of a category page. See Wikipedia:Categorization#Sort_keys. That works well for en.wiki
because English is written using the Latn script. This may not work well for other languages. At en.wiki it
is desireable to place content from certain namespaces at the end of a category listing so the module adds sort
keys to error and maintenance category links when rendering a cs1|2 template on a page in that namespace.
i18n: if this does not work well for your language, set <enable_sort_keys> to false.
]]
local name_space_sort_keys = { -- sort keys to be used with these namespaces:
[4] = 'ω', -- wikipedia; omega
[10] = 'τ', -- template; tau
[118] = 'Δ', -- draft; delta
['other'] = 'ο', -- all other non-talk namespaces except main (article); omicron
}
--[[--------------------------< M E S S A G E S >--------------------------------------------------------------
Translation table
The following contains fixed text that may be output as part of a citation.
This is separated from the main body to aid in future translations of this
module.
]]
local messages = {
['agency'] = '$1 $2', -- $1 is sepc, $2 is agency
['archived-dead'] = 'Archived from $1 on $2',
['archived-live'] = '$1 from the original on $2',
['archived-unfit'] = 'Archived from the original on $1',
['archived'] = 'Archived',
['by'] = 'By', -- contributions to authored works: introduction, foreword, afterword
['cartography'] = 'Cartography by $1',
['collaboration'] = '$1 ($2)', -- $1 is author with et al, $2 is collaboration
['editor'] = 'ed.',
['editors'] = 'eds.',
['edition'] = '($1 ed.)',
['episode'] = 'Episode $1',
['et al'] = 'et al.',
['in'] = 'In', -- edited works
['inactive'] = ' (inactive $1)', -- $1 is date which the doi was found to be broken in
['inset'] = '$1 inset',
['interview'] = 'Interviewed by $1',
invisible_1 = '$1 $2', -- $1 stripmarker name; $2 is text from <invisible_chars[1]>
invisible_2 = '$1 character', -- $1 character name from <invisible_chars[1]>
['mismatch'] = '<code class="cs1-code">|$1=</code> / <code class="cs1-code">|$2=</code> mismatch', -- $1 is year param name; $2 is date param name
['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]: $1',
['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none
['original'] = 'the original',
['origdate'] = ' [$1]',
['retrieved'] = 'Retrieved $1',
['season'] = 'Season $1',
['section'] = '§ $1',
['sections'] = '§§ $1',
['series'] = '$1 $2', -- $1 is sepc, $2 is series
['seriesnum'] = 'Series $1',
['translated'] = 'Translated by $1',
['type'] = ' ($1)', -- for titletype
wikidata = 'Wikidata', -- these used for interwikilinked author/editor/... names
wikipedia = 'Wikipedia',
wikisource = 'Wikisource',
['vol'] = '$1 Vol. $2', -- $1 is sepc; bold journal style volume is in presentation{}
['vol-no'] = '$1 Vol. $2, no. $3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization)
['issue'] = '$1 No. $2', -- $1 is sepc
['art'] = '$1 Art. $2', -- $1 is sepc; for {{cite conference}} only
['vol-art'] = '$1 Vol. $2, art. $3', -- sepc, volume, article-number; for {{cite conference}} only
['j-vol'] = '$1 $2', -- sepc, volume; bold journal volume is in presentation{}
['j-issue'] = ' ($1)',
['j-article-num'] = ' $1', -- TODO: any punctuation here? static text?
['nopp'] = '$1 $2'; -- page(s) without prefix; $1 is sepc
['p-prefix'] = "$1 p. $2", -- $1 is sepc
['pp-prefix'] = "$1 pp. $2", -- $1 is sepc
['j-page(s)'] = ': $1', -- same for page and pages
['sheet'] = '$1 Sheet $2', -- $1 is sepc
['sheets'] = '$1 Sheets $2', -- $1 is sepc
['j-sheet'] = ': Sheet $1',
['j-sheets'] = ': Sheets $1',
['language'] = '(in $1)',
['via'] = " – via $1",
['event'] = 'Event occurs at',
['minutes'] = ' $1 minutes in', -- $1 is the number of minutes
-- Determines the location of the help page
['help page link'] = 'Help:CS1 errors',
['help page label'] = 'help',
-- categories
['cat wikilink'] = '[[Category:$1]]', -- $1 is the category name
['cat wikilink sk'] = '[[Category:$1|$2]]', -- $1 is the category name; $2 is namespace sort key
[':cat wikilink'] = '[[:Category:$1|link]]', -- category name as maintenance message wikilink; $1 is the category name
-- Internal errors (should only occur if configuration is bad)
['undefined_error'] = 'Called with an undefined error condition',
['unknown_ID_key'] = 'Unrecognized ID key: ', -- an ID key in id_handlers not found in ~/Identifiers func_map{}
['unknown_ID_access'] = 'Unrecognized ID access keyword: ', -- an ID access keyword in id_handlers not found in keywords_lists['id-access']{}
['unknown_argument_map'] = 'Argument map not defined for this variable',
['bare_url_no_origin'] = 'Bare URL found but origin indicator is nil or empty',
['warning_msg_e'] = '<span style="color:#d33"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has errors</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
['warning_msg_m'] = '<span style="color:#085"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has maintenance messages</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
}
--[[--------------------------< C I T A T I O N _ C L A S S _ M A P >------------------------------------------
this table maps the value assigned to |CitationClass= in the cs1|2 templates to the canonical template name when
the value assigned to |CitationClass= is different from the canonical template name. |CitationClass= values are
used as class attributes in the <cite> tag that encloses the citation so these names may not contain spaces while
the canonical template name may. These names are used in warning_msg_e and warning_msg_m to create links to the
template's documentation when an article is displayed in preview mode.
]]
local citation_class_map_t = { -- TODO: in Module:Cite/config write a function to use this table
arxiv = 'cite arXiv', -- as the source for known_templates_t and citation_classes_t
['audio-visual'] = 'cite AV media',
['AV-media-notes'] = 'cite AV media notes',
biorxiv = 'cite bioRxiv',
book = 'cite book',
citation = 'citation',
citeseerx = 'cite CiteSeerX',
conference = 'cite conference',
document = 'cite document',
encyclopaedia = 'cite encyclopedia',
episode = 'cite episode',
interview = 'cite interview',
journal = 'cite journal',
magazine = 'cite magazine',
mailinglist = 'cite mailing list',
map = 'cite map',
medrxiv = 'cite medRxiv',
news = 'cite news',
newsgroup = 'cite newsgroup',
podcast = 'cite podcast',
pressrelease = 'cite press release',
report = 'cite report',
serial = 'cite serial',
sign = 'cite sign',
speech = 'cite speech',
ssrn = 'cite SSRN',
techreport = 'cite tech report',
thesis = 'cite thesis',
web = 'cite web',
}
--[=[-------------------------< E T _ A L _ P A T T E R N S >--------------------------------------------------
This table provides Lua patterns for the phrase "et al" and variants in name text
(author, editor, etc.). The main module uses these to identify and emit the 'etal' message.
]=]
local et_al_patterns = {
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][%.;,\"']*$", -- variations on the 'et al' theme
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][Ii][AaIi][Ee]?[%.;,\"']*$", -- variations on the 'et alia', 'et alii' and 'et aliae' themes (false positive 'et aliie' unlikely to match)
"[;,]? *%f[%a]and [Oo]thers", -- an alternative to et al.
"%[%[ *[Ee][Tt]%.? *[Aa][Ll]%.? *%]%]", -- a wikilinked form
"%(%( *[Ee][Tt]%.? *[Aa][Ll]%.? *%)%)", -- a double-bracketed form (to counter partial removal of ((...)) syntax)
"[%(%[] *[Ee][Tt]%.? *[Aa][Ll]%.? *[%)%]]", -- a bracketed form
}
--[[--------------------------< P R E S E N T A T I O N >------------------------
Fixed presentation markup. Originally part of citation_config.messages it has
been moved into its own, more semantically correct place.
]]
local presentation =
{
-- .citation-comment class is specified at Help:CS1_errors#Controlling_error_message_display
['hidden-error'] = '<span class="cs1-hidden-error citation-comment">$1</span>',
['visible-error'] = '<span class="cs1-visible-error citation-comment">$1</span>',
['hidden-maint'] = '<span class="cs1-maint citation-comment">$1</span>',
['accessdate'] = '<span class="reference-accessdate">$1$2</span>', -- to allow editors to hide accessdate using personal CSS
['bdi'] = '<bdi$1>$2</bdi>', -- bidirectional isolation used with |script-title= and the like
['cite'] = '<cite class="$1">$2</cite>'; -- for use when citation does not have a namelist and |ref= not set so no id="..." attribute
['cite-id'] = '<cite id="$1" class="$2">$3</cite>'; -- for use when when |ref= is set or when citation has a namelist
['format'] = ' <span class="cs1-format">($1)</span>', -- for |format=, |chapter-format=, etc.
['interwiki'] = ' <span class="cs1-format">[in $1]</span>', -- for interwiki-language-linked author, editor, etc
['interproj'] = ' <span class="cs1-format">[at $1]</span>', -- for interwiki-project-linked author, editor, etc (:d: and :s: supported; :w: ignored)
-- various access levels, for |access=, |doi-access=, |arxiv=, ...
-- narrow no-break space   may work better than nowrap CSS. Or not? Browser support?
['ext-link-access-signal'] = '<span class="$1" title="$2">$3</span>', -- external link with appropriate lock icon
['free'] = {class='id-lock-free', title='Freely accessible'}, -- classes defined in Module:Citation/CS1/styles.css
['registration'] = {class='id-lock-registration', title='Free registration required'},
['limited'] = {class='id-lock-limited', title='Free access subject to limited trial, subscription normally required'},
['subscription'] = {class='id-lock-subscription', title='Paid subscription required'},
['interwiki-icon'] = '<span class="$1" title="$2">$3</span>',
['class-wikisource'] = 'cs1-ws-icon',
['italic-title'] = "''$1''",
['kern-left'] = '<span class="cs1-kern-left"></span>$1', -- spacing to use when title contains leading single or double quote mark
['kern-right'] = '$1<span class="cs1-kern-right"></span>', -- spacing to use when title contains trailing single or double quote mark
['nowrap1'] = '<span class="nowrap">$1</span>', -- for nowrapping an item: <span ...>yyyy-mm-dd</span>
['nowrap2'] = '<span class="nowrap">$1</span> $2', -- for nowrapping portions of an item: <span ...>dd mmmm</span> yyyy (note white space)
['ocins'] = '<span title="$1" class="Z3988"></span>',
['parameter'] = '<code class="cs1-code">|$1=</code>',
['ps_cs1'] = '.'; -- CS1 style postscript (terminal) character
['ps_cs2'] = ''; -- CS2 style postscript (terminal) character (empty string)
['quoted-text'] = '<q>$1</q>', -- for wrapping |quote= content
['quoted-title'] = '"$1"',
['sep_cs1'] = '.', -- CS1 element separator
['sep_cs2'] = ',', -- CS2 separator
['sep_nl'] = ';', -- CS1|2 style name-list separator between names is a semicolon
['sep_nl_and'] = ' and ', -- used as last nl sep when |name-list-style=and and list has 2 items
['sep_nl_end'] = '; and ', -- used as last nl sep when |name-list-style=and and list has 3+ names
['sep_name'] = ', ', -- CS1|2 style last/first separator is <comma><space>
['sep_nl_vanc'] = ',', -- Vancouver style name-list separator between authors is a comma
['sep_name_vanc'] = ' ', -- Vancouver style last/first separator is a space
['sep_list'] = ', ', -- used for |language= when list has 3+ items except for last sep which uses sep_list_end
['sep_list_pair'] = ' and ', -- used for |language= when list has 2 items
['sep_list_end'] = ', and ', -- used as last list sep for |language= when list has 3+ items
['trans-italic-title'] = "[''$1'']",
['trans-quoted-title'] = "[$1]", -- for |trans-title= and |trans-quote=
['vol-bold'] = '$1 <b>$2</b>', -- sepc, volume; for bold journal cites; for other cites ['vol'] in messages{}
}
--[[--------------------------< A L I A S E S >---------------------------------
Aliases table for commonly passed parameters.
Parameter names on the right side in the assignments in this table must have been
defined in the Whitelist before they will be recognized as valid parameter names
]]
local aliases = {
['AccessDate'] = {'access-date', 'accessdate'}, -- Used by InternetArchiveBot
['Agency'] = 'agency',
['ArchiveDate'] = {'archive-date', 'archivedate'}, -- Used by InternetArchiveBot
['ArchiveFormat'] = 'archive-format',
['ArchiveURL'] = {'archive-url', 'archiveurl'}, -- Used by InternetArchiveBot
['ArticleNumber'] = 'article-number',
['ASINTLD'] = 'asin-tld',
['At'] = 'at', -- Used by InternetArchiveBot
['Authors'] = {'people', 'credits'},
['BookTitle'] = {'book-title', 'booktitle'},
['Cartography'] = 'cartography',
['Chapter'] = {'chapter', 'contribution', 'entry', 'article', 'section'},
['ChapterFormat'] = {'chapter-format', 'contribution-format', 'entry-format',
'article-format', 'section-format'};
['ChapterURL'] = {'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot
['ChapterUrlAccess'] = {'chapter-url-access', 'contribution-url-access',
'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot
['Class'] = 'class', -- cite arxiv and arxiv identifier
['Collaboration'] = 'collaboration',
['Conference'] = {'conference', 'event'},
['ConferenceFormat'] = 'conference-format',
['ConferenceURL'] = 'conference-url', -- Used by InternetArchiveBot
['Date'] = {'date', 'publication-date', 'air-date', 'airdate'}, -- air-date and airdate for cite episode and cite serial only
['Degree'] = 'degree',
['DF'] = 'df',
['DisplayAuthors'] = {'display-authors', 'display-subjects'},
['DisplayContributors'] = 'display-contributors',
['DisplayEditors'] = 'display-editors',
['DisplayInterviewers'] = 'display-interviewers',
['DisplayTranslators'] = 'display-translators',
['Docket'] = 'docket',
['DoiBroken'] = 'doi-broken-date',
['Edition'] = 'edition',
['Embargo'] = 'pmc-embargo-date',
['Encyclopedia'] = {'encyclopedia', 'encyclopaedia', 'dictionary'}, -- cite encyclopedia only
['Episode'] = 'episode', -- cite serial only TODO: make available to cite episode?
['Format'] = 'format',
['ID'] = {'id', 'ID'},
['Inset'] = 'inset',
['Issue'] = {'issue', 'number'},
['Language'] = {'language', 'lang'},
['MailingList'] = {'mailing-list', 'mailinglist'}, -- cite mailing list only
['Map'] = 'map', -- cite map only
['MapFormat'] = 'map-format', -- cite map only
['MapURL'] = {'map-url', 'mapurl'}, -- cite map only -- Used by InternetArchiveBot
['MapUrlAccess'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot
['Minutes'] = 'minutes',
['Mode'] = 'mode',
['NameListStyle'] = 'name-list-style',
['Network'] = 'network',
['Newsgroup'] = 'newsgroup', -- cite newsgroup only
['NoPP'] = {'no-pp', 'nopp'},
['NoTracking'] = {'no-tracking', 'template-doc-demo'},
['Number'] = 'number', -- this case only for cite techreport
['OrigDate'] = {'orig-date', 'orig-year', 'origyear'},
['Others'] = 'others',
['Page'] = {'page', 'p'}, -- Used by InternetArchiveBot
['Pages'] = {'pages', 'pp'}, -- Used by InternetArchiveBot
['Periodical'] = {'journal', 'magazine', 'newspaper', 'periodical', 'website', 'work'},
['PostScript'] = 'postscript',
['PublicationPlace'] = {'publication-place', 'location', 'place'}, -- TODO: when all templates that use |publication-place= and |place= or |location= make 'location' cannonical
['PublisherName'] = {'publisher', 'institution'},
['Quote'] = {'quote', 'quotation'},
['QuotePage'] = 'quote-page',
['QuotePages'] = 'quote-pages',
['Ref'] = 'ref',
['Scale'] = 'scale',
['ScriptChapter'] = {'script-chapter', 'script-contribution', 'script-entry',
'script-article', 'script-section'},
['ScriptEncyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only
['ScriptMap'] = 'script-map',
['ScriptPeriodical'] = {'script-journal', 'script-magazine', 'script-newspaper',
'script-periodical', 'script-website', 'script-work'},
['ScriptQuote'] = 'script-quote',
['ScriptTitle'] = 'script-title', -- Used by InternetArchiveBot
['Season'] = 'season',
['Sections'] = 'sections', -- cite map only
['Series'] = {'series', 'version'},
['SeriesLink'] = {'series-link', 'serieslink'},
['SeriesNumber'] = {'series-number', 'series-no'},
['Sheet'] = 'sheet', -- cite map only
['Sheets'] = 'sheets', -- cite map only
['Station'] = 'station',
['Time'] = 'time',
['TimeCaption'] = 'time-caption',
['Title'] = 'title', -- Used by InternetArchiveBot
['TitleLink'] = {'title-link', 'episode-link', 'episodelink'}, -- Used by InternetArchiveBot
['TitleNote'] = {'title-note', 'department'},
['TitleType'] = {'type', 'medium'},
['TransChapter'] = {'trans-article', 'trans-chapter', 'trans-contribution',
'trans-entry', 'trans-section'},
['Transcript'] = 'transcript',
['TranscriptFormat'] = 'transcript-format',
['TranscriptURL'] = 'transcript-url', -- Used by InternetArchiveBot
['TransEncyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only
['TransMap'] = 'trans-map', -- cite map only
['TransPeriodical'] = {'trans-journal', 'trans-magazine', 'trans-newspaper',
'trans-periodical', 'trans-website', 'trans-work'},
['TransQuote'] = 'trans-quote',
['TransTitle'] = 'trans-title', -- Used by InternetArchiveBot
['URL'] = {'url', 'URL'}, -- Used by InternetArchiveBot
['UrlAccess'] = 'url-access', -- Used by InternetArchiveBot
['UrlStatus'] = 'url-status', -- Used by InternetArchiveBot
['Vauthors'] = 'vauthors',
['Veditors'] = 'veditors',
['Via'] = 'via',
['Volume'] = 'volume',
['Year'] = 'year',
['AuthorList-First'] = {"first#", "author-first#", "author#-first", "author-given#", "author#-given",
"subject-first#", "subject#-first", "subject-given#", "subject#-given",
"given#"},
['AuthorList-Last'] = {"last#", "author-last#", "author#-last", "author-surname#", "author#-surname",
"subject-last#", "subject#-last", "subject-surname#", "subject#-surname",
"author#", 'host#', "subject#", "surname#"},
['AuthorList-Link'] = {"author-link#", "author#-link", "subject-link#",
"subject#-link", "authorlink#", "author#link"},
['AuthorList-Mask'] = {"author-mask#", "author#-mask", "subject-mask#", "subject#-mask"},
['ContributorList-First'] = {'contributor-first#', 'contributor#-first',
'contributor-given#', 'contributor#-given'},
['ContributorList-Last'] = {'contributor-last#', 'contributor#-last',
'contributor-surname#', 'contributor#-surname', 'contributor#'},
['ContributorList-Link'] = {'contributor-link#', 'contributor#-link'},
['ContributorList-Mask'] = {'contributor-mask#', 'contributor#-mask'},
['EditorList-First'] = {"editor-first#", "editor#-first", "editor-given#", "editor#-given"},
['EditorList-Last'] = {"editor-last#", "editor#-last", "editor-surname#",
"editor#-surname", "editor#"},
['EditorList-Link'] = {"editor-link#", "editor#-link"},
['EditorList-Mask'] = {"editor-mask#", "editor#-mask"},
['InterviewerList-First'] = {'interviewer-first#', 'interviewer#-first',
'interviewer-given#', 'interviewer#-given'},
['InterviewerList-Last'] = {'interviewer-last#', 'interviewer#-last',
'interviewer-surname#', 'interviewer#-surname', 'interviewer#'},
['InterviewerList-Link'] = {'interviewer-link#', 'interviewer#-link'},
['InterviewerList-Mask'] = {'interviewer-mask#', 'interviewer#-mask'},
['TranslatorList-First'] = {'translator-first#', 'translator#-first',
'translator-given#', 'translator#-given'},
['TranslatorList-Last'] = {'translator-last#', 'translator#-last',
'translator-surname#', 'translator#-surname', 'translator#'},
['TranslatorList-Link'] = {'translator-link#', 'translator#-link'},
['TranslatorList-Mask'] = {'translator-mask#', 'translator#-mask'},
}
--[[--------------------------< D E P E N D E N C I E S _ T >--------------------------------------------------
a table of url-holding parameters upon which other parameters are dependent.
this table is used by has_archive_today_url() to suppress parameters that are dependant upon a url-holding parameter
that has as a value an archive.today (or alternate tld) url.
archive.today is deprecated at en.wiki; see Wikipedia:Requests_for_comment/Archive.is_RFC_5
]]
local url_dependency_map_t = { -- table of url-holding parameters and the meta-parameters that are dependent on them
['url'] = {'AccessDate', 'ArchiveURL', 'Format', 'UrlAccess'},
['archive-url'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['archiveurl'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['article-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['chapter-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['conference-url'] = {'ConferenceFormat'},
['contribution-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['entry-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['map-url'] = {'MapFormat', 'MapUrlAccess'},
['section-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['transcript-url'] = {'TranscriptFormat'},
};
local dependencies_t = {}; -- the table of url-holding parameters and their dependent parameters
for url_param, meta_parameters_t in pairs (url_dependency_map_t) do -- sequence of meta-parameters (indexes) into <aliases> table
local dependant_params_t = {}; -- collection of parameters that are dependent on this <url_param>
for _, meta_parameter in ipairs (meta_parameters_t) do -- for each <aliases> meta-parameter (index)
if 'string' == type (aliases[meta_parameter]) then -- for single parameter names (no aliases), <aliases[meta_parameter]> will be a string
table.insert (dependant_params_t, aliases[meta_parameter]); -- add to this <url_param>'s dependency sequence
else
for _, alias in ipairs (aliases[meta_parameter]) do -- for each alias in aliases[meta_parameter] (aliases['AccessDate'] for example)
table.insert (dependant_params_t, alias); -- add to this <url_param>'s dependency sequence
end
end
end
dependencies_t[url_param] = dependant_params_t; -- add the <url_param> and its dependent parameters
end
--[[--------------------------< P U N C T _ S K I P >---------------------------
builds a table of parameter names that the extraneous terminal punctuation check should not check.
]]
local punct_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'BookTitle', 'Chapter', 'ScriptChapter', 'ScriptTitle', 'Title', 'TransChapter', 'Transcript', 'TransMap', 'TransTitle', -- title-holding parameters
'AuthorList-Mask', 'ContributorList-Mask', 'EditorList-Mask', 'InterviewerList-Mask', 'TranslatorList-Mask', -- name-list mask may have name separators
'PostScript', 'Quote', 'ScriptQuote', 'TransQuote', 'Ref', -- miscellaneous
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'MapURL', 'TranscriptURL', 'URL', -- URL-holding parameters
}
local url_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'ID', 'MapURL', 'TranscriptURL', 'URL', -- parameters allowed to hold urls
'Page', 'Pages', 'At', 'QuotePage', 'QuotePages', -- insource locators allowed to hold urls
}
local function build_skip_table (skip_t, meta_params)
for _, meta_param in ipairs (meta_params) do -- for each meta parameter key
local params = aliases[meta_param]; -- get the parameter or the table of parameters associated with the meta parameter name
if 'string' == type (params) then
skip_t[params] = 1; -- just a single parameter
else
for _, param in ipairs (params) do -- get the parameter name
skip_t[param] = 1; -- add the parameter name to the skip table
local count;
param, count = param:gsub ('#', ''); -- remove enumerator marker from enumerated parameters
if 0 ~= count then -- if removed
skip_t[param] = 1; -- add param name without enumerator marker
end
end
end
end
return skip_t;
end
local punct_skip = {};
local url_skip = {};
--[[--------------------------< U R L _ A C C E S S _ M A P >--------------------------------------------------
this table used by the wikipedia library url test, has_twl_url(), which automatically sets a url-access parameter
to 'subscription' when it discovers a wikipedia library url in any of the url-holding paramters used as keys in
this table.
translators: if your wiki uses parameter names for these url-holding parameters and their matching -access parameters,
add your wiki's parameters to this list. Leave the English parameters in place.
TODO: is there a better way to do this?
]]
local url_access_map_t = {
['chapter-url'] = 'chapter-url-access',
['contribution-url'] = 'contribution-url-access',
['entry-url'] = 'entry-url-access',
['article-url'] = 'article-url-access',
['section-url'] = 'section-url-access',
['map-url'] = 'map-url-access',
['mapurl'] = 'map-url-access',
['url'] = 'url-access',
['URL'] = 'url-access'
}
--[[--------------------------< S I N G L E - L E T T E R S E C O N D - L E V E L D O M A I N S >----------
this is a list of tlds that are known to have single-letter second-level domain names. This list does not include
ccTLDs which are accepted in is_domain_name().
]]
local single_letter_2nd_lvl_domains_t = {'cash', 'company', 'foundation', 'media', 'org', 'today'};
--[[-----------< S P E C I A L C A S E T R A N S L A T I O N S >------------
This table is primarily here to support internationalization. Translations in
this table are used, for example, when an error message, category name, etc.,
is extracted from the English alias key. There may be other cases where
this translation table may be useful.
]]
local is_Latn = 'A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191';
local special_case_translation = {
author = 'author',
editor = 'editor',
name_list_params = '$1-name-list parameters', -- $1 is 'author' or 'editor'; used with err_redundant_parameters
['AuthorList'] = 'authors list', -- used to assemble maintenance category names
['ContributorList'] = 'contributors list', -- translation of these names plus translation of the base maintenance category names in maint_cats{} table below
['EditorList'] = 'editors list', -- must match the names of the actual categories
['InterviewerList'] = 'interviewers list', -- this group or translations used by name_has_ed_markup() and name_has_mult_names()
['TranslatorList'] = 'translators list',
-- Lua patterns to match pseudo-titles used by InternetArchiveBot and others as placeholder for unknown |title= value
['archived_copy'] = { -- used with CS1 maint: Archive[d] copy as title
['en'] = '^archived?%s+copy$', -- for English; translators: keep this because templates imported from en.wiki
['local'] = nil, -- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
},
-- Lua patterns to match generic titles; usually created by bots or reference filling tools
-- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
-- generic titles and patterns in this table should be lowercase only
-- leave ['local'] nil except when there is a matching generic title in your language
-- boolean 'true' for plain-text searches; 'false' for pattern searches
['generic_titles'] = {
['accept'] = {
},
['reject'] = {
{['en'] = {'^wayback%s+machine$', false}, ['local'] = nil},
{['en'] = {'are you a robot', true}, ['local'] = nil},
{['en'] = {'hugedomains', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?no +title[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'page not found', true}, ['local'] = nil},
{['en'] = {'subscribe to read', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?unknown[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'website is for sale', true}, ['local'] = nil},
{['en'] = {'^404', false}, ['local'] = nil},
{['en'] = {'error[ %-]404', false}, ['local'] = nil},
{['en'] = {'internet archive wayback machine', true}, ['local'] = nil},
{['en'] = {'log into facebook', true}, ['local'] = nil},
{['en'] = {'login • instagram', true}, ['local'] = nil},
{['en'] = {'redirecting...', true}, ['local'] = nil},
{['en'] = {'usurped title', true}, ['local'] = nil}, -- added by a GreenC bot
{['en'] = {'wayback machine', true}, ['local'] = nil},
{['en'] = {'webcite query result', true}, ['local'] = nil},
{['en'] = {'wikiwix\'s cache', true}, ['local'] = nil},
{['en'] = {'bot verification', true}, ['local'] = nil},
}
},
-- boolean 'true' for plain-text searches, search string must be lowercase only
-- boolean 'false' for pattern searches
-- leave ['local'] nil except when there is a matching generic name in your language
['generic_names'] = {
['accept'] = {
{['en'] = {'%[%[[^|]*%(author%) *|[^%]]*%]%]', false}, ['local'] = nil},
},
['reject'] = {
{['en'] = {'about us', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]dvisor%f[%A]', false}, ['local'] = nil},
{['en'] = {'allmusic', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]uthor%f[%A]', false}, ['local'] = nil},
{['en'] = {'^[Bb]ureau$', false}, ['local'] = nil},
{['en'] = {'business', true}, ['local'] = nil},
{['en'] = {'cnn', true}, ['local'] = nil},
{['en'] = {'collaborator', true}, ['local'] = nil},
{['en'] = {'^[Cc]ompany$', false}, ['local'] = nil},
{['en'] = {'contributor', true}, ['local'] = nil},
{['en'] = {'contact us', true}, ['local'] = nil},
{['en'] = {'correspondent', true}, ['local'] = nil},
{['en'] = {'^[Dd]esk$', false}, ['local'] = nil},
{['en'] = {'directory', true}, ['local'] = nil},
{['en'] = {'%f[%(%[][%(%[]%s*eds?%.?%s*[%)%]]?$', false}, ['local'] = nil},
{['en'] = {'[,%.%s]%f[e]eds?%.?$', false}, ['local'] = nil},
{['en'] = {'^eds?[%.,;]', false}, ['local'] = nil},
{['en'] = {'^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]dited%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]ditors?%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]mail%f[%A]', false}, ['local'] = nil},
{['en'] = {'facebook', true}, ['local'] = nil},
{['en'] = {'google', true}, ['local'] = nil},
{['en'] = {'^[Gg]roup$', false}, ['local'] = nil},
{['en'] = {'home page', true}, ['local'] = nil},
{['en'] = {'^[Ii]nc%.?$', false}, ['local'] = nil},
{['en'] = {'instagram', true}, ['local'] = nil},
{['en'] = {'interviewer', true}, ['local'] = nil},
{['en'] = {'^[Ll]imited$', false}, ['local'] = nil},
{['en'] = {'linkedIn', true}, ['local'] = nil},
{['en'] = {'^[Nn]ews$', false}, ['local'] = nil},
{['en'] = {'[Nn]ews[ %-]?[Rr]oom', false}, ['local'] = nil},
{['en'] = {'pinterest', true}, ['local'] = nil},
{['en'] = {'policy', true}, ['local'] = nil},
{['en'] = {'privacy', true}, ['local'] = nil},
{['en'] = {'reuters', true}, ['local'] = nil},
{['en'] = {'translator', true}, ['local'] = nil},
{['en'] = {'tumblr', true}, ['local'] = nil},
{['en'] = {'twitter', true}, ['local'] = nil},
{['en'] = {'site name', true}, ['local'] = nil},
{['en'] = {'statement', true}, ['local'] = nil},
{['en'] = {'submitted', true}, ['local'] = nil},
{['en'] = {'super.?user', false}, ['local'] = nil},
{['en'] = {'%f['..is_Latn..'][Uu]ser%f[^'..is_Latn..']', false}, ['local'] = nil},
{['en'] = {'updated', true}, ['local'] = nil},
{['en'] = {'verfasser', true}, ['local'] = nil},
}
}
}
--[[--------------------------< D A T E _ N A M E S >----------------------------------------------------------
This table of tables lists local language date names and fallback English date names.
The code in Date_validation will look first in the local table for valid date names.
If date names are not found in the local table, the code will look in the English table.
Because citations can be copied to the local wiki from en.wiki, the English is
required when the date-name translation function date_name_xlate() is used.
In these tables, season numbering is defined by
Extended Date/Time Format (EDTF) Specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard
defines various divisions using numbers 21-41. CS1|2 only supports generic seasons.
EDTF does support the distinction between north and south hemisphere seasons
but CS1|2 has no way to make that distinction.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
The standard does not address 'named' dates so, for the purposes of CS1|2,
Easter and Christmas are defined here as 98 and 99, which should be out of the
ISO 8601 (EDTF) range of uses for a while.
local_date_names_from_mediawiki is a boolean. When set to:
true – module will fetch local month names from MediaWiki for both date_names['local']['long'] and date_names['local']['short']; this will unconditionally overwrite manual translations
false – module will *not* fetch local month names from MediaWiki
Caveat lector: There is no guarantee that MediaWiki will provide short month names. At your wiki you can test
the results of the MediaWiki fetch in the debug console with this command (the result is alpha sorted):
=mw.dumpObject (p.date_names['local'])
While the module can fetch month names from MediaWiki, it cannot fetch the quarter, season, and named date names
from MediaWiki. Those must be translated manually.
]]
local local_date_names_from_mediawiki = true; -- when false, manual translation required for date_names['local']['long'] and date_names['local']['short']; overwrites manual translations
-- when true, module fetches long and short month names from MediaWiki
local date_names = {
['en'] = { -- English
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
-- when local_date_names_from_mediawiki = false
['local'] = { -- replace these English date names with the local language equivalents
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
['inv_local_long'] = {}, -- used in date reformatting & translation; copy of date_names['local'].long where k/v are inverted: [1]='<local name>' etc.
['inv_local_short'] = {}, -- used in date reformatting & translation; copy of date_names['local'].short where k/v are inverted: [1]='<local name>' etc.
['inv_local_quarter'] = {}, -- used in date translation; copy of date_names['local'].quarter where k/v are inverted: [1]='<local name>' etc.
['inv_local_season'] = {}, -- used in date translation; copy of date_names['local'].season where k/v are inverted: [1]='<local name>' etc.
['inv_local_named'] = {}, -- used in date translation; copy of date_names['local'].named where k/v are inverted: [1]='<local name>' etc.
['local_digits'] = {['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4', ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9'}, -- used to convert local language digits to Western 0-9
['xlate_digits'] = {},
}
if local_date_names_from_mediawiki then -- if fetching local month names from MediaWiki is enabled
local long_t = {};
local short_t = {};
for i=1, 12 do -- loop 12x and
local name = lang_obj:formatDate('F', '2022-' .. i .. '-1'); -- get long month name for each i
long_t[name] = i; -- save it
name = lang_obj:formatDate('M', '2022-' .. i .. '-1'); -- get short month name for each i
short_t[name] = i; -- save it
end
date_names['local']['long'] = long_t; -- write the long table – overwrites manual translation
date_names['local']['short'] = short_t; -- write the short table – overwrites manual translation
end
-- create inverted date-name tables for reformatting and/or translation
for _, invert_t in pairs {{'long', 'inv_local_long'}, {'short', 'inv_local_short'}, {'quarter', 'inv_local_quarter'}, {'season', 'inv_local_season'}, {'named', 'inv_local_named'}} do
for name, i in pairs (date_names['local'][invert_t[1]]) do -- this table is ['name'] = i
date_names[invert_t[2]][i] = name; -- invert to get [i] = 'name' for conversions from ymd
end
end
if local_digits_from_mediawiki then -- if fetching local digits from MediaWiki is enabled
local digits_t = {};
for i=0, 9 do -- loop 10x and
digits_t [lang_obj:formatNum (i)] = tostring (i); -- format the loop indexer as local lang table index and assign loop indexer (a string) as the value
end
date_names['local_digits'] = digits_t;
end
for ld, ed in pairs (date_names.local_digits) do -- make a digit translation table for simple date translation from en to local language using local_digits table
date_names.xlate_digits [ed] = ld; -- en digit becomes index with local digit as the value
end
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}}
'{{ *[Uu]se +(dmy) +dates *[|}]', -- 1159k -- sorted by approximate transclusion count
'{{ *[Uu]se +(mdy) +dates *[|}]', -- 212k
'{{ *[Uu]se +(MDY) +dates *[|}]', -- 788
'{{ *[Uu]se +(DMY) +dates *[|}]', -- 343
'{{ *([Mm]dy) *[|}]', -- 176
'{{ *[Uu]se *(dmy) *[|}]', -- 156 + 18
'{{ *[Uu]se *(mdy) *[|}]', -- 149 + 11
'{{ *([Dd]my) *[|}]', -- 56
'{{ *[Uu]se +(MDY) *[|}]', -- 5
'{{ *([Dd]MY) *[|}]', -- 3
'{{ *[Uu]se(mdy)dates *[|}]', -- 1
'{{ *[Uu]se +(DMY) *[|}]', -- 0
'{{ *([Mm]DY) *[|}]', -- 0
}
local title_object = mw.title.getCurrentTitle();
local content; -- done this way so that unused templates appear in unused-template-reports; self-transcluded makes them look like they are used
if 10 ~= title_object.namespace then -- all namespaces except Template
content = title_object:getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
end
local function get_date_format ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects
local start, _, match = content:find(pattern); -- match is the three letters indicating desired date format
if match then
local use_dates_template = content:match ('%b{}', start); -- get the whole template
if use_dates_template:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length
return match:lower() .. '-' .. use_dates_template:match ('| *cs1%-dates *= *([lsy][sy]?)');
else
return match:lower() .. '-all'; -- no |cs1-dates= k/v pair; return value appropriate for use in |df=
end
end
end
end
--[[-----------------< V O L U M E , I S S U E , P A G E S >------------------
These tables hold cite class values (from the template invocation) and identify those templates that support
|volume=, |issue=, and |page(s)= parameters. Cite conference and cite map require further qualification which
is handled in the main module.
]]
local templates_using_volume = {'citation', 'audio-visual', 'book', 'conference', 'encyclopaedia', 'interview', 'journal', 'magazine', 'map', 'news', 'report', 'techreport', 'thesis'}
local templates_using_issue = {'citation', 'conference', 'episode', 'interview', 'journal', 'magazine', 'map', 'news', 'podcast'}
local templates_not_using_page = {'audio-visual', 'episode', 'mailinglist', 'newsgroup', 'podcast', 'serial', 'sign', 'speech'}
--[[
These tables control when it is appropriate for {{citation}} to render |volume= and/or |issue=. The parameter
names in the tables constrain {{citation}} so that its renderings match the renderings of the equivalent cs1
templates. For example, {{cite web}} does not support |volume= so the equivalent {{citation |website=...}} must
not support |volume=.
]]
local citation_no_volume_t = { -- {{citation}} does not render |volume= when these parameters are used
'website', 'mailinglist', 'script-website',
}
local citation_issue_t = { -- {{citation}} may render |issue= when these parameters are used
'journal', 'magazine', 'newspaper', 'periodical', 'work',
'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-work',
}
--[[
Patterns for finding extra text in |volume=, |issue=, |page=, |pages=
]]
local vol_iss_pg_patterns = {
good_ppattern = '^P[^%.PpGg]', -- OK to begin with uppercase P: P7 (page 7 of section P), but not p123 (page 123); TODO: this allows 'Pages' which it should not
bad_ppatterns = { -- patterns for |page= and |pages=
'^[Pp][PpGg]?%.?[ %d]',
'^[Pp][Pp]?%. ', -- from {{p.}} and {{pp.}} templates
'^[Pp]ages?',
'^[Pp]gs.?',
},
vi_patterns_t = { -- combined to catch volume-like text in |issue= and issue-like text in |volume=
'^volumes?', -- volume-like text
'^vols?[%.:=]?',
'^issues?', --issue-like text
'^iss[%.:=]?',
'^numbers?',
'^nos?%A', -- don't match 'november' or 'nostradamus'
'^nr[%.:=]?',
'^n[%.:= ]', -- might be a valid issue without separator (space char is sep char here)
'^n°', -- 'n' with degree sign (U+00B0)
'^№', -- precomposed unicode numero character (U+2116)
},
}
--[[--------------------------< K E Y W O R D S >-------------------------------
These tables hold keywords for those parameters that have defined sets of acceptable keywords.
]]
--[[-------------------< K E Y W O R D S T A B L E >--------------------------
this is a list of keywords; each key in the list is associated with a table of
synonymous keywords possibly from different languages.
for I18N: add local-language keywords to value table; do not change the key.
For example, adding the German keyword 'ja':
['affirmative'] = {'yes', 'true', 'y', 'ja'},
Because CS1|2 templates from en.wiki articles are often copied to other local wikis,
it is recommended that the English keywords remain in these tables.
]]
local keywords = {
['amp'] = {'&', 'amp', 'ampersand'}, -- |name-list-style=
['and'] = {'and', 'serial'}, -- |name-list-style=
['affirmative'] = {'yes', 'true', 'y'}, -- |no-tracking=, |no-pp= -- Used by InternetArchiveBot
['afterword'] = {'afterword'}, -- |contribution=
['bot: unknown'] = {'bot: unknown'}, -- |url-status= -- Used by InternetArchiveBot
['cs1'] = {'cs1'}, -- |mode=
['cs2'] = {'cs2'}, -- |mode=
['dead'] = {'dead', 'deviated'}, -- |url-status= -- Used by InternetArchiveBot
['dmy'] = {'dmy'}, -- |df=
['dmy-all'] = {'dmy-all'}, -- |df=
etal = {'etal'}, -- |display-authors=, etc
['foreword'] = {'foreword'}, -- |contribution=
['free'] = {'free'}, -- |<id>-access= -- Used by InternetArchiveBot
['harv'] = {'harv'}, -- |ref=; this no longer supported; is_valid_parameter_value() called with <invert> = true
['introduction'] = {'introduction'}, -- |contribution=
['limited'] = {'limited'}, -- |url-access= -- Used by InternetArchiveBot
['live'] = {'live'}, -- |url-status= -- Used by InternetArchiveBot
['mdy'] = {'mdy'}, -- |df=
['mdy-all'] = {'mdy-all'}, -- |df=
['none'] = {'none'}, -- |postscript=, |ref=, |title=, |type= -- Used by InternetArchiveBot
['off'] = {'off'}, -- |title= (potentially also: |title-link=, |postscript=, |ref=, |type=)
['preface'] = {'preface'}, -- |contribution=
['registration'] = {'registration'}, -- |url-access= -- Used by InternetArchiveBot
['subscription'] = {'subscription'}, -- |url-access= -- Used by InternetArchiveBot
['unfit'] = {'unfit'}, -- |url-status= -- Used by InternetArchiveBot
['usurped'] = {'usurped'}, -- |url-status= -- Used by InternetArchiveBot
['vanc'] = {'vanc'}, -- |name-list-style=
['ymd'] = {'ymd'}, -- |df=
['ymd-all'] = {'ymd-all'}, -- |df=
-- ['yMd'] = {'yMd'}, -- |df=; not supported at en.wiki
-- ['yMd-all'] = {'yMd-all'}, -- |df=; not supported at en.wiki
}
--[[------------------------< X L A T E _ K E Y W O R D S >---------------------
this function builds a list, keywords_xlate{}, of the keywords found in keywords{} where the values from keywords{}
become the keys in keywords_xlate{} and the keys from keywords{} become the values in keywords_xlate{}:
['affirmative'] = {'yes', 'true', 'y'}, -- in keywords{}
becomes
['yes'] = 'affirmative', -- in keywords_xlate{}
['true'] = 'affirmative',
['y'] = 'affirmative',
the purpose of this function is to act as a translator between a non-English keyword and its English equivalent
that may be used in other modules of this suite
]]
local function xlate_keywords ()
local out_table = {}; -- output goes here
for k, keywords_t in pairs (keywords) do -- spin through the keywords table
for _, keyword in ipairs (keywords_t) do -- for each keyword
out_table[keyword] = k; -- create an entry in the output table where keyword is the key
end
end
return out_table;
end
local keywords_xlate = xlate_keywords (); -- the list of translated keywords
--[[----------------< M A K E _ K E Y W O R D S _ L I S T >---------------------
this function assembles, for parameter-value validation, the list of keywords appropriate to that parameter.
keywords_lists{}, is a table of tables from keywords{}
]]
local function make_keywords_list (keywords_lists)
local out_table = {}; -- output goes here
for _, keyword_list in ipairs (keywords_lists) do -- spin through keywords_lists{} and get a table of keywords
for _, keyword in ipairs (keyword_list) do -- spin through keyword_list{} and add each keyword, ...
table.insert (out_table, keyword); -- ... as plain text, to the output list
end
end
return out_table;
end
--[[----------------< K E Y W O R D S _ L I S T S >-----------------------------
this is a list of lists of valid keywords for the various parameters in [key].
Generally the keys in this table are the canonical en.wiki parameter names though
some are contrived because of use in multiple differently named parameters:
['yes_true_y'], ['id-access'].
The function make_keywords_list() extracts the individual keywords from the
appropriate list in keywords{}.
The lists in this table are used to validate the keyword assignment for the
parameters named in this table's keys.
]]
local keywords_lists = {
['yes_true_y'] = make_keywords_list ({keywords.affirmative}),
['contribution'] = make_keywords_list ({keywords.afterword, keywords.foreword, keywords.introduction, keywords.preface}),
['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all']}),
-- ['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all'], keywords.yMd, keywords['yMd-all']}), -- not supported at en.wiki
['mode'] = make_keywords_list ({keywords.cs1, keywords.cs2}),
['name-list-style'] = make_keywords_list ({keywords.amp, keywords['and'], keywords.vanc}),
['ref'] = make_keywords_list ({keywords.harv}), -- inverted check; |ref=harv no longer supported
['url-access'] = make_keywords_list ({keywords.subscription, keywords.limited, keywords.registration}),
['url-status'] = make_keywords_list ({keywords.dead, keywords.live, keywords.unfit, keywords.usurped, keywords['bot: unknown']}),
['id-access'] = make_keywords_list ({keywords.free}),
}
--[[--------------------------< C S 1 _ C O N F I G _ G E T >--------------------------------------------------
fetch and validate values from {{cs1 config}} template to fill <global_cs1_config_t>
no error messages; when errors are detected, the parameter value from {{cs1 config}} is blanked.
Supports all parameters and aliases associated with the metaparameters: DisplayAuthors, DisplayContributors,
DisplayEditors, DisplayInterviewers, DisplayTranslators, NameListStyle, and Mode. The DisplayWhatever metaparameters
accept numeric values only (|display-authors=etal and the like is not supported).
]]
local global_cs1_config_t = {}; -- TODO: add value returned from get_date_format() to this table?
local function get_cs1_config ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
local start = content:find('{{ *[Cc][Ss]1 config *[|}]'); -- <start> is offset into <content> when {{cs1 config}} found; nil else
if start then
local cs1_config_template = content:match ('%b{}', start); -- get the whole template
if not cs1_config_template then
return nil;
end
local params_t = mw.text.split (cs1_config_template:gsub ('^{{%s*', ''):gsub ('%s*}}$', ''), '%s*|%s*'); -- remove '{{' and '}}'; make a sequence of parameter/value pairs (split on the pipe)
table.remove (params_t, 1); -- remove the template name because it isn't a parameter/value pair
local config_meta_params_t = {'DisplayAuthors', 'DisplayContributors', 'DisplayEditors', 'DisplayInterviewers', 'DisplayTranslators', 'NameListStyle', 'Mode'};
local meta_param_map_t = {}; -- list of accepted parameter names usable in {{cs1 config}} goes here
for _, meta_param in ipairs (config_meta_params_t) do -- for i18n using <config_meta_params_t>, map template parameter names to their metaparameter equivalents
if 'table' == type (aliases[meta_param]) then -- if <meta_param> is a sequence,
for _, param in ipairs (aliases[meta_param]) do -- extract its contents
meta_param_map_t[param] = meta_param; -- and add to <meta_param_map_t>
end
else
meta_param_map_t[aliases[meta_param]] = meta_param; -- not a sequence so just add the parameter to <meta_param_map_t>
end
end
local keywords_t = {}; -- map valid keywords to their associate metaparameter; reverse form of <keyword_lists[key] for these metaparameters
for _, metaparam_t in ipairs ({{'NameListStyle', 'name-list-style'}, {'Mode', 'mode'}}) do -- only these metaparameter / keywords_lists key pairs
for _, keyword in ipairs (keywords_lists[metaparam_t[2]]) do -- spin through the list of keywords
keywords_t[keyword] = metaparam_t[1]; -- add [keyword] = metaparameter to the map
end
end
for _, param in ipairs (params_t) do -- spin through the {{cs1 config}} parameters and fill <global_cs1_config_t>
local k, v = param:match ('([^=]-)%s*=%s*(.+)'); -- <k> is the parameter name; <v> is parameter's assigned value
if k then
if k:find ('^display') then -- if <k> is one of the |display-<namelist>= parameters
if v:match ('%d+') then -- the assigned value must be digits; doesn't accept 'etal'
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the display param and its value to globals table
end
else
if keywords_t[v] == meta_param_map_t[k] then -- keywords_t[v] returns nil or the metaparam name; these must be the same
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the parameter and its value to globals table
end
end
end
end
end
end
get_cs1_config (); -- fill <global_cs1_config_t>
--[[---------------------< S T R I P M A R K E R S >----------------------------
Common pattern definition location for stripmarkers so that we don't have to go
hunting for them if (when) MediaWiki changes their form.
]]
local stripmarkers = {
['any'] = '\127[^\127]*UNIQ%-%-(%a+)%-[%a%d]+%-QINU[^\127]*\127', -- capture returns name of stripmarker
['math'] = '\127[^\127]*UNIQ%-%-math%-[%a%d]+%-QINU[^\127]*\127' -- math stripmarkers used in coins_cleanup() and coins_replace_math_stripmarker()
}
--[[------------< I N V I S I B L E _ C H A R A C T E R S >---------------------
This table holds non-printing or invisible characters indexed either by name or
by Unicode group. Values are decimal representations of UTF-8 codes. The table
is organized as a table of tables because the Lua pairs keyword returns table
data in an arbitrary order. Here, we want to process the table from top to bottom
because the entries at the top of the table are also found in the ranges specified
by the entries at the bottom of the table.
Also here is a pattern that recognizes stripmarkers that begin and end with the
delete characters. The nowiki stripmarker is not an error but some others are
because the parameter values that include them become part of the template's
metadata before stripmarker replacement.
]]
local invisible_defs = {
del = '\127', -- used to distinguish between stripmarker and del char
zwj = '\226\128\141', -- used with capture because zwj may be allowed
}
local invisible_chars = {
{'replacement', '\239\191\189'}, -- U+FFFD, EF BF BD
{'zero width joiner', '('.. invisible_defs.zwj .. ')'}, -- U+200D, E2 80 8D; capture because zwj may be allowed
{'zero width space', '\226\128\139'}, -- U+200B, E2 80 8B
{'hair space', '\226\128\138'}, -- U+200A, E2 80 8A
{'soft hyphen', '\194\173'}, -- U+00AD, C2 AD
{'horizontal tab', '\009'}, -- U+0009 (HT), 09
{'line feed', '\010'}, -- U+000A (LF), 0A
{'no-break space', '\194\160'}, -- U+00A0 (NBSP), C2 A0
{'carriage return', '\013'}, -- U+000D (CR), 0D
{'stripmarker', stripmarkers.any}, -- stripmarker; may or may not be an error; capture returns the stripmaker type
{'delete', '('.. invisible_defs.del .. ')'}, -- U+007F (DEL), 7F; must be done after stripmarker test; capture to distinguish isolated del chars not part of stripmarker
{'C0 control', '[\000-\008\011\012\014-\031]'}, -- U+0000–U+001F (NULL–US), 00–1F (except HT, LF, CR (09, 0A, 0D))
{'C1 control', '[\194\128-\194\159]'}, -- U+0080–U+009F (XXX–APC), C2 80 – C2 9F
-- {'Specials', '[\239\191\185-\239\191\191]'}, -- U+FFF9-U+FFFF, EF BF B9 – EF BF BF
-- {'Private use area', '[\238\128\128-\239\163\191]'}, -- U+E000–U+F8FF, EE 80 80 – EF A3 BF
-- {'Supplementary Private Use Area-A', '[\243\176\128\128-\243\191\191\189]'}, -- U+F0000–U+FFFFD, F3 B0 80 80 – F3 BF BF BD
-- {'Supplementary Private Use Area-B', '[\244\128\128\128-\244\143\191\189]'}, -- U+100000–U+10FFFD, F4 80 80 80 – F4 8F BF BD
}
--[[
Indic script makes use of zero width joiner as a character modifier so zwj
characters must be left in. This pattern covers all of the unicode characters
for these languages:
Devanagari 0900–097F – https://unicode.org/charts/PDF/U0900.pdf
Devanagari extended A8E0–A8FF – https://unicode.org/charts/PDF/UA8E0.pdf
Bengali 0980–09FF – https://unicode.org/charts/PDF/U0980.pdf
Gurmukhi 0A00–0A7F – https://unicode.org/charts/PDF/U0A00.pdf
Gujarati 0A80–0AFF – https://unicode.org/charts/PDF/U0A80.pdf
Oriya 0B00–0B7F – https://unicode.org/charts/PDF/U0B00.pdf
Tamil 0B80–0BFF – https://unicode.org/charts/PDF/U0B80.pdf
Telugu 0C00–0C7F – https://unicode.org/charts/PDF/U0C00.pdf
Kannada 0C80–0CFF – https://unicode.org/charts/PDF/U0C80.pdf
Malayalam 0D00–0D7F – https://unicode.org/charts/PDF/U0D00.pdf
plus the not-necessarily Indic scripts for Sinhala and Burmese:
Sinhala 0D80-0DFF - https://unicode.org/charts/PDF/U0D80.pdf
Myanmar 1000-109F - https://unicode.org/charts/PDF/U1000.pdf
Myanmar extended A AA60-AA7F - https://unicode.org/charts/PDF/UAA60.pdf
Myanmar extended B A9E0-A9FF - https://unicode.org/charts/PDF/UA9E0.pdf
the pattern is used by has_invisible_chars() and coins_cleanup()
]]
local indic_script = '[\224\164\128-\224\181\191\224\163\160-\224\183\191\225\128\128-\225\130\159\234\167\160-\234\167\191\234\169\160-\234\169\191]';
-- list of emoji that use a zwj character (U+200D) to combine with another emoji
-- from: https://www.unicode.org/Public/18.0.0/emoji/emoji-zwj-sequences.txt; version: 18.0; 2026-01-09
-- table created by: [[:en:Module:Make emoji zwj table]]
local emoji_t = { -- indexes are decimal forms of the hex values in U+xxxx
[8596] = true, -- U+2194 ↔ left right arrow
[8597] = true, -- U+2195 ↕ up down arrow
[9760] = true, -- U+2620 ☠ skull and crossbones
[9792] = true, -- U+2640 ♀ female sign
[9794] = true, -- U+2642 ♂ male sign
[9877] = true, -- U+2695 ⚕ staff of aesculapius
[9878] = true, -- U+2696 ⚖ scales
[9895] = true, -- U+26A7 ⚧ male with stroke and male and female sign
[9992] = true, -- U+2708 ✈ airplane
[10052] = true, -- U+2744 ❄ snowflake
[10084] = true, -- U+2764 ❤ heavy black heart
[10145] = true, -- U+27A1 ➡ black rightwards arrow
[11035] = true, -- U+2B1B ⬛ black large square
[127752] = true, -- U+1F308 🌈 rainbow
[127787] = true, -- U+1F32B 🌫 fog
[127806] = true, -- U+1F33E 🌾 ear of rice
[127859] = true, -- U+1F373 🍳 cooking
[127868] = true, -- U+1F37C 🍼 baby bottle
[127876] = true, -- U+1F384 🎄 christmas tree
[127891] = true, -- U+1F393 🎓 graduation cap
[127908] = true, -- U+1F3A4 🎤 microphone
[127912] = true, -- U+1F3A8 🎨 artist palette
[127979] = true, -- U+1F3EB 🏫 school
[127981] = true, -- U+1F3ED 🏭 factory
[128048] = true, -- U+1F430 🐰 rabbit face
[128102] = true, -- U+1F466 👦 boy
[128103] = true, -- U+1F467 👧 girl
[128104] = true, -- U+1F468 👨 man
[128105] = true, -- U+1F469 👩 woman
[128139] = true, -- U+1F48B 💋 kiss mark
[128165] = true, -- U+1F4A5 💥 collision symbol
[128168] = true, -- U+1F4A8 💨 dash symbol
[128171] = true, -- U+1F4AB 💫 dizzy symbol
[128187] = true, -- U+1F4BB 💻 personal computer
[128188] = true, -- U+1F4BC 💼 brief case
[128293] = true, -- U+1F525 🔥 fire
[128295] = true, -- U+1F527 🔧 wrench
[128300] = true, -- U+1F52C 🔬 microscope
[128488] = true, -- U+1F5E8 🗨 left speech bubble
[128640] = true, -- U+1F680 🚀 rocket
[128658] = true, -- U+1F692 🚒 fire engine
[129001] = true, -- U+1F7E9 🟩 large green square
[129003] = true, -- U+1F7EB 🟫 large brown square
[129309] = true, -- U+1F91D 🤝 handshake
[129455] = true, -- U+1F9AF 🦯 probing cane
[129456] = true, -- U+1F9B0 🦰 emoji component red hair
[129457] = true, -- U+1F9B1 🦱 emoji component curly hair
[129458] = true, -- U+1F9B2 🦲 emoji component bald
[129459] = true, -- U+1F9B3 🦳 emoji component white hair
[129466] = true, -- U+1F9BA 🦺 safety vest
[129468] = true, -- U+1F9BC 🦼 motorized wheelchair
[129469] = true, -- U+1F9BD 🦽 manual wheelchair
[129489] = true, -- U+1F9D1 🧑 adult
[129490] = true, -- U+1F9D2 🧒 child
[129648] = true, -- U+1FA70 🩰 ballet shoes
[129657] = true, -- U+1FA79 🩹 adhesive bandage
[129775] = true, -- U+1FAEF fight cloud
[129778] = true, -- U+1FAF2 🫲 leftwards hand
}
--[[----------------------< L A N G U A G E S U P P O R T >-------------------
These tables and constants support various language-specific functionality.
]]
local this_wiki_code = lang_obj:getCode(); -- get this wiki's language code
if string.match (mw.site.server, 'wikidata') then
this_wiki_code = mw.getCurrentFrame():callParserFunction('int', {'lang'}); -- on Wikidata so use interface language setting instead
end
local mw_languages_by_tag_t = mw.language.fetchLanguageNames (this_wiki_code, 'all'); -- get a table of language tag/name pairs known to Wikimedia; used for interwiki tests
local mw_languages_by_name_t = {};
for k, v in pairs (mw_languages_by_tag_t) do -- build a 'reversed' table name/tag language pairs know to MediaWiki; used for |language=
v = mw.ustring.lower (v); -- lowercase for tag fetch; get name's proper case from mw_languages_by_tag_t[<tag>]
if mw_languages_by_name_t[v] then -- when name already in the table
if 2 == #k or 3 == #k then -- if tag does not have subtags
mw_languages_by_name_t[v] = k; -- prefer the shortest tag for this name
end
else -- here when name not in the table
mw_languages_by_name_t[v] = k; -- so add name and matching tag
end
end
local inter_wiki_map = {}; -- map of interwiki prefixes that are language-code prefixes
for k, v in pairs (mw.site.interwikiMap ('local')) do -- spin through the base interwiki map (limited to local)
if mw_languages_by_tag_t[v["prefix"]] then -- if the prefix matches a known language tag
inter_wiki_map[v["prefix"]] = true; -- add it to our local map
end
end
--[[--------------------< S C R I P T _ L A N G _ C O D E S >-------------------
This table is used to hold ISO 639-1 two-character and ISO 639-3 three-character
language codes that apply only to |script-title= and |script-chapter=
]]
local script_lang_codes = {
'ab', 'am', 'ar', 'as', 'az', 'be', 'bg', 'bn', 'bo', 'bs', 'ce', 'chr',
'cu', 'dv', 'dz', 'el', 'fa', 'grc', 'gu', 'he', 'hi', 'hy', 'ja', 'ka',
'kaa', 'kk', 'km', 'kn', 'ko', 'ku', 'ky', 'lo', 'mk', 'ml', 'mn', 'mni',
'mr', 'my', 'ne', 'or', 'ota', 'pa', 'ps', 'ru', 'sd', 'si', 'sr', 'syc',
'ta', 'te', 'tg', 'th', 'ti', 'tkr', 'tt', 'ug', 'uk', 'ur', 'uz', 'yi',
'yue', 'zh', 'zgh'
};
--[[---------------< L A N G U A G E R E M A P P I N G >----------------------
These tables hold language information that is different (correct) from MediaWiki's definitions
For each ['<tag>'] = 'language name' in lang_tag_remap{} there must be a matching ['language name'] = {'language name', '<tag>'} in lang_name_remap{}
lang_tag_remap{}:
key is always lowercase ISO 639-1, -2, -3 language tag or a valid lowercase IETF language tag
value is properly spelled and capitalized language name associated with <tag>
only one language name per <tag>;
key/value pair must have matching entry in lang_name_remap{}
lang_name_remap{}:
key is always lowercase language name
value is a table the holds correctly spelled and capitalized language name [1] and associated tag [2] (tag must match a tag key in lang_tag_remap{})
may have multiple keys referring to a common preferred name and tag; For example:
['kolsch'] and ['kölsch'] both refer to 'Kölsch' and 'ksh'
]]
local lang_tag_remap = { -- used for |language= and |script-title= / |script-chapter=
['als'] = 'Tosk Albanian', -- MediaWiki returns Alemannisch
['bh'] = 'Bihari', -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bla'] = 'Blackfoot', -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['bn'] = 'Bengali', -- MediaWiki returns Bangla
['ca-valencia'] = 'Valencian', -- IETF variant of Catalan
['fkv'] = 'Kven', -- MediaWiki returns Kvensk
['gsw'] = 'Swiss German',
['ilo'] = 'Ilocano', -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['ksh'] = 'Kölsch', -- MediaWiki: Colognian; use IANA/ISO 639 preferred name
['ksh-x-colog'] = 'Colognian', -- override MediaWiki ksh; no IANA/ISO 639 code for Colognian; IETF private code created at Module:Lang/data
['mis-x-ripuar'] = 'Ripuarian', -- override MediaWiki ksh; no IANA/ISO 639 code for Ripuarian; IETF private code created at Module:Lang/data
['nan-tw'] = 'Taiwanese Hokkien', -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese and support en.wiki preferred name
['sr-ec'] = 'Serbian (Cyrillic script)', -- MediaWiki returns српски (ћирилица)
['sr-el'] = 'Serbian (Latin script)', -- MediaWiki returns srpski (latinica)
['tet'] = 'Tetun', -- MediaWiki returns Tetum
}
local lang_name_remap = { -- used for |language=; names require proper capitalization; tags must be lowercase
['alemannic'] = {'Swiss German', 'gsw'}, -- ISO 639-2, -3 alternate for Swiss German; MediaWiki mediawiki returns Alemannic for gsw; en.wiki preferred name
['alemannisch'] = {'Swiss German', 'gsw'}, -- not an ISO or IANA language name; MediaWiki uses 'als' as a subdomain name for Alemannic Wikipedia: als.wikipedia.org
['bangla'] = {'Bengali', 'bn'}, -- MediaWiki returns Bangla (the endonym) but we want Bengali (the exonym); here we remap
['bengali'] = {'Bengali', 'bn'}, -- MediaWiki doesn't use exonym so here we provide correct language name and 639-1 code
['bhojpuri'] = {'Bhojpuri', 'bho'}, -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bihari'] = {'Bihari', 'bh'}, -- MediaWiki replaces 'Bihari' with 'Bhojpuri' so 'Bihari' cannot be found
['blackfoot'] = {'Blackfoot', 'bla'}, -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['colognian'] = {'Colognian', 'ksh-x-colog'}, -- MediaWiki preferred name for ksh
['ilocano'] = {'Ilocano', 'ilo'}, -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['kolsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name (use non-diacritical o instead of umlaut ö)
['kölsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name
['kven'] = {'Kven', 'fkv'}, -- Unicode CLDR have decided not to support English language name for these two...
['kvensk'] = {'Kven', 'fkv'}, -- ...they say to refer to IANA registry for English names
['ripuarian'] = {'Ripuarian', 'mis-x-ripuar'}, -- group of dialects; no code in MediaWiki or in IANA/ISO 639
['serbian (cyrillic script)'] = {'Serbian (Cyrillic script)', 'sr-cyrl'}, -- special case to get correct tag when |language=sr-ec
['serbian (latin script)'] = {'Serbian (Latin script)', 'sr-latn'}, -- special case to get correct tag when |language=sr-el
['swiss german'] = {'Swiss German', 'gsw'},
['taiwanese hokkien'] = {'Taiwanese Hokkien', 'nan-tw'}, -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese
['tetum'] = {'Tetun', 'tet'},
['tetun'] = {'Tetun', 'tet'},
['tosk albanian'] = {'Tosk Albanian', 'als'}, -- MediaWiki replaces 'Tosk Albanian' with 'Alemannisch' so 'Tosk Albanian' cannot be found
['valencian'] = {'Valencian', 'ca-valencia'}, -- variant of Catalan; categorizes as Valencian
}
--[[---------------< P R O P E R T I E S _ C A T E G O R I E S >----------------
Properties categories. These are used for investigating qualities of citations.
]]
local prop_cats = {
['foreign-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is foreign-language name, $2 is ISO639-1 code
['foreign-lang-source-2'] = 'CS1 foreign language sources (ISO 639-2)|$1', -- |language= category; a cat for ISO639-2 languages; $1 is the ISO 639-2 code used as a sort key
['interproj-linked-name'] = 'CS1 interproject-linked names|$1', -- any author, editor, etc that has an interproject link; $1 is interproject tag used as a sort key
['interwiki-linked-name'] = 'CS1 interwiki-linked names|$1', -- any author, editor, etc that has an interwiki link; $1 is interwiki tag used as a sort key; yeilds to interproject
['local-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is local-language name, $2 is ISO639-1 code; not emitted when local_lang_cat_enable is false
['location-test'] = 'CS1 location test',
['long-vol'] = 'CS1: long volume value', -- probably temporary cat to identify scope of |volume= values longer than 4 characters
['script'] = 'CS1 uses $1-language script ($2)', -- |script-title=xx: has matching category; $1 is language name, $2 is language tag
['tracked-param'] = 'CS1 tracked parameter: $1', -- $1 is base (enumerators removed) parameter name
['unfit'] = 'CS1: unfit URL', -- |url-status=unfit or |url-status=usurped; used to be a maint cat
['vanc-accept'] = 'CS1:Vancouver names with accept markup', -- for |vauthors=/|veditors= with accept-as-written markup
['year-range-abbreviated'] = 'CS1: abbreviated year range', -- probably temporary cat to identify scope of |date=, |year= values using YYYY–YY form
}
--[[-------------------< T I T L E _ T Y P E S >--------------------------------
Here we map a template's CitationClass to TitleType (default values for |type= parameter)
]]
local title_types = {
['AV-media-notes'] = 'Media notes',
['document'] = 'Document',
['interview'] = 'Interview',
['mailinglist'] = 'Mailing list',
['map'] = 'Map',
['podcast'] = 'Podcast',
['pressrelease'] = 'Press release',
['report'] = 'Report',
['speech'] = 'Speech',
['techreport'] = 'Technical report',
['thesis'] = 'Thesis',
}
--[[--------------------------< B U I L D _ K N O W N _ F R E E _ D O I _ R E G I S T R A N T S _ T A B L E >--
build a table of doi registrants known to be free-to-read In a doi, the registrant ID is the series of digits
between the '10.' and the first '/': in doi 10.1100/sommat, 1100 is the registrant ID
see §3.2.2 DOI prefix of the Doi Handbook p. 43
https://www.doi.org/doi-handbook/DOI_Handbook_Final.pdf#page=43
]]
local function build_free_doi_registrants_table()
local registrants_t = {};
for _, v in ipairs ({
'1045', '1074', '1096', '1100', '1155', '1186', '1194', '1371', '1613', '1629', '1989', '1999', '2147', '2196', '3114', '3285', --for 10.1155/... ISRN prior to 2007 should not be flagged--
'3389', '3390', '3767', '3906', '3748', '3814', '3847', '3897', '4061', '4089', '4102', '4103', '4172', '4175', '4230', '4236', '4239',
'4240', '4249', '4251', '4252', '4253', '4254', '4291', '4292', '4312', '4329', '4330', '4331', '5070', '5074', '5086', '5194', '5210',
'5306', '5312', '5313', '5314', '5315', '5316', '5317', '5318', '5319', '5320', '5321', '5334', '5402', '5409', '5410', '5411',
'5412', '5492', '5493', '5494', '5495', '5496', '5497', '5498', '5499', '5500', '5501', '5527', '5528', '5662', '6064', '6219',
'7167', '7217', '7287', '7482', '7490', '7554', '7717', '7759', '7766', '9778',
'11131', '11569', '11647', '11648', '12688', '12703', '12715', '12942', '12998', '13105', '14256', '14293', '14303', '14502', '14720',
'15215', '15227', '15292', '15458', '15347', '15412', '15560', '16995', '17573', '17645', '18553', '18637', '18757', '19080', '19173',
'20419', '20944', '21037', '21105', '21468', '21767', '21425', '22261', '22323', '22459', '24105', '24196', '24404', '24413', '24966',
'26529', '26614', '26775', '26873', '30845', '32545', '34291', '34641', '35711', '35712', '35713', '35995', '36648', '37126', '37532',
'37871', '47128', '47622', '47959', '48438', '51741', '51746', '51935', '51936', '51937', '51938', '51939', '51940', '52165', '52437',
'52975', '53288', '53347', '54081', '54947', '55295', '55667', '55741', '55914', '56042', '57009', '58647', '58782', '59081', '59490',
'61375', '66183', '70587',
}) do
registrants_t[v] = true; -- build a k/v table of known free-to-read doi registrants
end
return registrants_t;
end
-- known free registrants identifiable by the doi suffix incipit
local extended_registrants_t = { -- doi suffix incipits are evaluated as lua patterns
['1001'] = {'jamanetworkopen', 'jamahealthforum'}, -- JAMA Network Open, JAMA Health Forum
['1002'] = {'1878-0261', '2056-4538', '2211-5463', '2475-8876', '2688-8319', 'aaai%.', 'aac2%.', 'ache%.', 'acm2%.', 'acn3%.', 'acr2%.', 'admi%.', 'adpr%.', 'adrr%.', 'adsr%.', 'advs%.', 'ael2%.', 'aelm%.', 'aesr%.', 'aff2%.', 'agf2%.', 'agg2%.', 'agm2%.', 'ags3%.', 'agt2%.', 'aidi%.', 'ail2%.', 'aisy%.', 'aiv2%.', 'alz%.', 'ame2%.', 'ams2%.', 'anbr%.', 'ansa%.', 'apj%.', 'app5%.', 'aps3%.', 'apxr%.', 'aro2%.', 'ars2%.', 'asl2%.', 'atn2%.', 'bco2%.', 'bes2%.', 'bmm2%.', 'bod2%.', 'brb3%.', 'brh2%.', 'brx2%.', 'bsa3%.', 'bte2%.', 'btm2%.', 'cai2%.', 'cam4%.', 'cbh2%.', 'ccr3%.', 'ccs3%.', 'cdt3%.', 'celc%.', 'cep4%.', 'ces2%.', 'cesm%.', 'ceur%.', 'cey2%.', 'cfch%.', 'cfp2%.', 'cin4%.', 'clc%.', 'clem%.', 'cli2%.', 'clt2%.', 'cmt2%.', 'cmtd%.', 'cnl2%.', 'cnr2%.', 'cns%.', 'cns3%.', 'cnx2%.', 'cre2%.', 'csc3%.', 'cso2%.', 'ctd2%.', 'cti2%.', 'ctm2%.', 'dad2%.', 'deo2%.', 'dep2%.', 'dni2%.', 'dro2%.', 'dug2%.', 'dvr2%.', 'eas2%.', 'ece2%.', 'ece3%.', 'ecog%.', 'ecs2%.', 'edm2%.', 'edn3%.', 'eem2%.', 'eer3%.', 'efd2%.', 'ejsc%.', 'elsa%.', 'elt2%.', 'eng2%.', 'eom2%.', 'epi4%.', 'epr2%.', 'ese3%.', 'exp%.', 'fbe2%.', 'fci2%.', 'fer3%.', 'fes3%.', 'fft2%.', 'fhu2%.', 'fle2%.', 'flm2%.', 'fob2%.', 'fpf2%.', 'fsh3%.', 'fsn3%.', 'gcb4%.', 'gch2%.', 'gdj3%.', 'geo2%.', 'ggn2%.', 'gin2%.', 'glr2%.', 'gps3%.', 'gtm2%.', 'hbm%.', 'hcs2%.', 'hem3%.', 'hkj2%.', 'hsr2%.', 'ibra%.', 'idm2%.', 'ifm2%.', 'iid3%.', 'iju5%.', 'ila2%.', 'imed%.', 'imm3%.', 'imo2%.', 'imt2%.', 'inc2%.', 'inc3%.', 'inf2%.', 'inm3%.', 'inmd%.', 'ird3%.', 'ise3%.', 'jaa2%.', 'jav%.', 'jbt%.', 'jcc5%.', 'jcla%.', 'jcsm%.', 'jcv2%.', 'jeo2%.', 'jev2%.', 'jex2%.', 'jfa2%.', 'jgf2%.', 'jgh3%.', 'jha2%.', 'jia2%.', 'jmd2%.', 'jmrs%.', 'joa3%.', 'jpr3%.', 'jsf2%.', 'jsp2%.', 'jvc2%.', 'kjm2%.', 'kot2%.', 'lci2%.', 'ldr%.', 'leap%.', 'leg3%.', 'lim2%.', 'lio2%.', 'loe2%.', 'lol2%.', 'lrh2%.', 'mame%.', 'mba2%.', 'mbo3%.', 'mco2%.', 'mdb2%.', 'mdr2%.', 'med4%.', 'mef2%.', 'met%.', 'metm%.', 'mgea%.', 'mgg3%.', 'mhs2%.', 'mlf2%.', 'mmr3%.', 'moda%.', 'mog2%.', 'mpr%.', 'mps2%.', 'msd2%.', 'nam2%.', 'nano%.', 'nap2%.', 'neo2%.', 'nep3%.', 'njb%.', 'nop2%.', 'npp2%.', 'npr2%.', 'ntls%.', 'open%.', 'orm2%.', 'osp4%.', 'oto2%.', 'pan3%.', 'pchj%.', 'pcn5%.', 'pdi3%.', 'ped4%.', 'pei3%.', 'pfm2%.', 'pgr2%.', 'phmt%.', 'pld3%.', 'pls2%.', 'pmf2%.', 'pne2%.', 'pnp%.', 'poh2%.', 'ppj2%.', 'ppp3%.', 'prm2%.', 'pro6%.', 'prp2%.', 'psp4%.', 'puh2%.', 'pul2%.', 'qub2%.', 'rai2%.', 'rar2%.', 'rco2%.', 'rcr2%.', 'rfc2%.', 'rmb2%.', 'rpm2%.', 'rse2%.', 'rvr2%.', 'sae2%.', 'sen2%.', 'sfp2%.', 'smb2%.', 'smm2%.', 'smmd%.', 'smo2%.', 'smsc%.', 'sst2%.', 'sst3%.', 'sstr%.', 'sus2%.', 'tch2%.', 'tcr4%.', 'tpg2%.', 'trc2%.', 'tre%.', 'uar2%.', 'ueg2%.', 'uro2%.', 'viw2%.', 'vms3%.', 'vro2%.', 'vzj2%.', 'we%.', 'wjo2%.', 'wlb3%.', 'wll2%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1007'] = {'s12543', 's40565'}, -- Fuzzy Information and Engineering, Journal of Modern Power Systems and Clean Energy
['1016'] = {'j%.aace', 'j%.aed', 'j%.aiopen', 'j%.animal', 'j%.apsb', -- AACE Endocrinology and Diabetes, AACE Endocrinology and Diabetes, AI Open, Animal, Acta Pharmaceutica Sinica B
'j%.addicn', 'j%.abrep', 'j%.eurpsy', 'j%.fob', 'j%.gpb', 'j%.heliyon', -- Addiction Neuroscience, Addictive Behaviors Reports, European Psychiatry, FEBS Open Bio, Genomics, Proteomics & Bioinformatics after 2015, Heliyon
'j%.mucimm%.', 'j%.nlp', 'j%.patter', 'j%.proche', 'j%.vgie', -- Mucosal Immunology, Natural Language Processing, Patterns, Procedia Chemistry, VideoGIE
's1004-4132', 's1007-0214', 's1672-0229', 's1933-0219'}, -- Journal of Systems Engineering and Electronics, Tsinghua Science and Technology, Genomics, Proteomics & Bioinformatics before 2015, Mucosal Immunology
['1017'] = {'apj%.', 'nlp', 'mdh', 'S09249338', 'S15574660'}, -- Natural Language Processing Journal, Medical History, European Psychiatry, Asia Pacific Journal
['1021'] = {'acscentsci%.', 'acs%.chas%.', 'acsomega%.', 'jacsau%.',
'acsbiomedchemau%.', 'acsengineeringau%.', 'acsenvironau%.',
'acsmaterialsau%.', 'acsmeasuresciau%.', 'acsnanoscienceau%.',
'acsorginorgau%.', 'acsphyschemau%.', 'acspolymersau%.',
'aps%.', 'cbe%.', 'cbmi%.', 'envhealth%.', 'ehp%.', 'photonsci%.',
'polymscitech%.', 'prechem%.'}, -- ACS journals
['1029'] = {'2025cn', '2025csj', '2025ea', '2025gc', '2025gh', '2025ms', '2025sw', '2025wr', '2026ef', '2026gl', '2026jh', 'aga2.70129'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1038'] = {'41541%.', '43246%.', 'asiamat%.', 'boneres%.', 'cddis%.', 'cddiscovery%.', 'celldisc%.', 'mi%.', 'ncomms', 'nutd%.', 'oncsis%.', 'srep', 's40494', 's41377', 's41392', 's41396', 's41398', 's41405', 's41407', 's41408', 's41439', 's41467', 's41514', 's41522', 's41523', 's41524', 's41525', 's41526', 's41528', 's41529', 's41531', 's41533', 's41534', 's41535', 's41536', 's41537', 's41538', 's41539', 's41540', 's41545', 's41598', 's41612', 's41698', 's41699', 's41746', 's42003', 's42004', 's42005', 's42949', 's43247', 's43705', 's43856', 's44168', 's44172', 's44182', 's44183', 's44184', 's44185', 's44259', 's44260', 's44264', 's44271', 's44276', 's44294', 's44296', 's44298', 's44303', 's44304', 's44306', 's44310', 's44323', 's44324', 's44325', 's44328', 's44333', 's44334', 's44335', 's44341', 's44355', 's44383', 's44384', 's44385', 's44386', 's44387', 's44400', 's44401', 's44406', 's44407', 's44431', 's44432', 's44433', 's44434', 's44435', 's44440', 's44453', 's44454', 's44455', 's44456', 's44458', 's44459', 's44482', 's44484', 's44485', 's44488', 's44513', 's44528', 'sdata%.'}, -- Nature journals (npj series, Communications series, and many others, see https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&diff=prev&oldid=1368822567 and https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&diff=next&oldid=1368822567)
['1046'] = {'j%.1365-8711', 'j%.1365-246x'}, -- MNRAS, GJI
['1049'] = {'aie2%.', 'blc2%.', 'bme2', 'bsb2%.', 'ccs2%.', 'cds2', 'cdt2', 'cim2%.', 'cit2%.', 'cje%.', 'cmu2%.', 'cps2%.', 'csy2%.', 'cth2%.', 'cvi2%.', 'dgt2%.', 'ein2%.', 'ell2%.', 'elp2%.', 'els2', 'ema3%.', 'enb2%.', 'enc2%.', 'esi2%.', 'gtd2%.', 'htl2%.', 'hve2%.', 'ipr2%.', 'ise2', 'itr2%.', 'mia2%.', 'mna2%.', 'nbt2', 'nde2%.', 'ntw2%.', 'ote2%.', 'pel2%.', 'qtc2%.', 'rpg2%.', 'rsn2%.', 'ses2%.', 'sfw2', 'sil2', 'smc2%.', 'smt2%.', 'stg2%.', 'syb2%.', 'tje2%.', 'wss2%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1051'] = {'0004-6361','parasite'}, -- Astronomy & Astrophysics, Parasite
['1057'] = {'s41599'}, -- Humanities and Social Sciences Communications
['1080'] = {'14399776'}, -- International Journal of Fluid Power
['1090'] = {'cams', 'ecgd', 's1088-4173', 'ert', 's1088-4165', 's2330-1511',-- Free AMS journals
'bproc', 's2330-0000', 'btran', 'noti'},
['1093'] = {'asjof', 'bjro', 'bjsopen', 'ehjopen', 'hropen ', 'jamiaopen', 'ofid', 'oxfclm', -- Aesthetic Surgery Journal Open Forum, BJR Open, BJS Open, European Heart Journal Open, Human Reproduction Open, JAMIA Open, Open Forum Infectious Diseases, Oxford Open Climate Change
'oodh', 'ooec', 'ooenergy', 'oxfimm', 'ooih', 'oxfmat', 'oons', --Oxford Open Digital Health, Oxford Open Economics, Oxford Open Energy, Oxford Open Immunology, Oxford Open Infrastructure and Health, Oxford Open Materials Science, Oxford Open Neuroscience
'qopen', 'schizbullopen', 'mnras', 'mnrasl', 'gji', 'pnasnexus',-- Q Open, Schizophrenia Bulletin Open, MNRAS, MNRAS Letters, GJI, PNAS Nexus
'rasti', 'ismeco', 'ismejo'}, -- RASTI, ISME Communications, ISME Journal
['1096'] = {'fba%.'}, -- FASEB BioAdvances
['1098'] = {'rsbm', 'rsob', 'rsos'}, -- Biographical Memoirs of Fellows of the Royal Society, Open Biology, Royal Society Open Science
['1099'] = {'acmi', 'mic', '00221287', 'mgen'}, -- Access Microbiology, Microbiology, Journal of General Microbiology, Microbial Genomics
['1107'] = {'S20569890', 'S20522525', 'S16005775', 'S24143146'}, -- Acta Crystallographica E, IUCrJ, Journal of Synchrotron Radiation, IUCrData
['1109'] = {'access%.', 'ieeedata%.', 'jeds%.', 'jispin%.', 'jmw%.', 'jphot%.', 'jsas%.', 'jstars%.', 'jsteap%.', 'jtehm%.', 'jxcdc%.', 'lls%.', 'lsmc%.', 'oajpe%.', 'ojap%.', 'ojcas%.', 'ojcoms%.', 'ojcs%.', 'ojcsys%.', 'ojemb%.', 'ojia%.', 'ojid%.', 'ojies%.', 'ojim%.', 'ojits%.', 'ojnano%.', 'ojpel%.', 'ojse%.', 'ojsp%.', 'ojsscs%.', 'ojuffc%.', 'ojvt%.', 'sr%.', 'tfr%.', 'tmlcn%.', 'tp%.', 'tqe%.', 'oa', 'oj'}, -- IEEE journals see [[User talk:DreamRimmer#Wikipedia:Bot requests/Archive 88#Web scrapping v4]]
['1111'] = {'1365-2435', '1442-1984', '1751-7915', '1753-0407', '1755-0998', '1758-2229', '1759-7714', '2041-210x', 'j%.1365-2966', 'j%.1745-3933', 'j%.1365-246X','acel%.', 'adb%.', 'anec%.', 'aogs%.', 'bor%.', 'bpa%.', 'cas%.', 'con4%.', 'cpr%.', 'crj%.', 'csp2%.', 'cts%.', 'ddi%.', 'ejed%.', 'ene%.', 'eva%.', 'gbb%.', 'gcbb%.', 'hex%.', 'irv%.', 'iwj%.', 'jch%.', 'jcmm%.', 'jdi%.', 'jfr3%.', 'jocd%.', 'jwas%.', 'mcn%.', 'mpp%.', 'myc%.', 'nrm%.', 'os%.', 'pbi%.', 'srt%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1112'] = {'tlm3%.'}, -- Transactions of the London Mathematical Society
['1113'] = {'ep'}, -- Experimental Physiology
['1128'] = {'asmcr', 'jmbe', 'mbio', 'mra', 'spectrum', 'msphere', 'msystems'}, --ASM Case Reports, Journal of Microbiology & Biology Education, mBio, Microbiology Resource Announcements, Microbiology Spectrum, mSphere, mSystems
['1130'] = {'GES'}, -- Geosphere
['1136'] = {'bmjopen'}, -- BMJ Open
['1140'] = {'epjconf', 'epjds'}, -- EPJ Web of Conferences, EPJ Data Science
['1161'] = {'jaha%.'},
['1162'] = {'qss'}, -- Quantitative Science Studies
['1176'] = {'appi%.prcp%.'},
['1177'] = {'21582440', '23328584'}, -- SAGE Open, AERA Open
['1192'] = {'bjo', 'j%.eurpsy'}, -- BJPsych Open, European Psychiatry
['1210'] = {'jendso','jcemcr'}, -- Journal of the Endocrine Society, JCEM Case Reports
['1215'] = {'21573689', '21573698'}, -- L&O Fluids
['1242'] = {'bio', 'dmm'}, -- Biology Open, Disease Models & Mechanisms
['1257'] = {'jep'}, -- Journal of Economic Perspectives
['1587'] = {'comex%.', 'transcom%.'}, -- IEICE Communications Express, IEICE Transactions on Communications
['1590'] = {'0102-3306', 's0074-0276'}, -- Acta Botanica Brasilica, Memórias do Instituto Oswaldo Cruz
['1631'] = {'eng%.'}, -- ENGINEERING Information Technology & Electronic Engineering
['2106'] = {'JBJS.OA'}, -- JBJS Open Access
['2903'] = {'j%.efsa%.'},
['3322'] = {'caac%.'},
['3982'] = {'qw', 'te'},
['4171'] = {'dm','mag'}, -- Documenta Mathematica, EMS Magazine
['4319'] = {'lo%.', 'lol%.', 'lom%.'}, -- L&O, L&O e-Lectures, L&O Methods
['5852'] = {'ejt'}, -- European Journal of Taxonomy
['7155'] = {'jgaa'}, -- Journal of Graph Algorithms and Applications
['7758'] = {'rsf'}, -- RSJ Journal
['11158'] = {'saasp'}, -- Systematic and Applied Acarology Special Publications
['11646'] = {'megataxa', 'mesozoic'}, -- Megataxa, Mesozoic
['13052'] = {'jcsm2245-1439%.', 'jmm1550-4646%.'}, -- Journal of Cyber Security and Mobility, Journal of Mobile Multimedia
['14231'] = {'ag'}, -- Algebraic Geometry
['14814'] = {'phy2%.'},
['15302'] = {'vr%.'},
['15446'] = {'abc'}, -- Acta Biológica Colombiana
['17239'] = {'jowr'}, -- Journal of Writing Research
['17775'] = {'cseejpes%.'}, -- CSEE Journal of Power and Energy Systems
['22073'] = {'pja'}, -- Persian Journal of Acarology
['23919'] = {'aise%.', 'chain%.', 'cjee%.', 'csms%.', 'etr%.', -- See [[User talk:DreamRimmer#Wikipedia:Bot requests/Archive 88#Web scrapping v4]]
'hyper%.', 'ics%.', 'ienergy%.', 'jsc%.',
'metaresource%.', 'saiee%.', 'tup-icn%.', 'ursirsb%.'},
['24295'] = {'cpsstpea%.'}, -- CPSS Transactions on Power Electronics and Applications
['24310'] = {'abm'}, -- Acta Botanica Malacitana
['24425'] = {'agp'}, -- Acta Geologica Polonica
['26599'] = {'bdma%.', 'cai%.', 'ijcs%.', 'jicv%.'}, -- Big Data Mining and Analytics, Cybernetics and Intelligence, International Journal of Crowd Science, Journal of Intelligent and Connected Vehicles
['30941'] = {'cestems%.'}, -- CES Transactions on Electrical Machines and Systems
['35249'] = {'rche'}, -- Revista Chilena de Entomología
['37520'] = {'fi'}, -- Fossil Imprint
['53562'] = {'ajcb'} -- Asian Journal of Conservation Biology
}
--[[===================<< E R R O R M E S S A G I N G >>======================
]]
--[[----------< E R R O R M E S S A G E S U P P L E M E N T S >-------------
I18N for those messages that are supplemented with additional specific text that
describes the reason for the error
TODO: merge this with special_case_translations{}?
]]
local err_msg_supl = {
['char'] = 'invalid character', -- |isbn=, |sbn=
['check'] = 'checksum', -- |isbn=, |sbn=
empty_str = '(empty string)', -- empty unknown parameter check when cite has |=
['flag'] = 'flag', -- |archive-url=
['form'] = 'invalid form', -- |isbn=, |sbn=
['group'] = 'invalid group id', -- |isbn=
['initials'] = 'initials', -- Vancouver
['invalid language code'] = 'invalid language code', -- |script-<param>=
['journal'] = 'journal', -- |bibcode=
['length'] = 'length', -- |isbn=, |bibcode=, |sbn=
['liveweb'] = 'liveweb', -- |archive-url=
['missing comma'] = 'missing comma', -- Vancouver
['missing prefix'] = 'missing prefix', -- |script-<param>=
['missing title part'] = 'missing title part', -- |script-<param>=
['name'] = 'name', -- Vancouver
['non-Latin char'] = 'non-Latin character', -- Vancouver
['path'] = 'path', -- |archive-url=
['prefix'] = 'invalid prefix', -- |isbn=
['punctuation'] = 'punctuation', -- Vancouver
['save'] = 'save command', -- |archive-url=
['suffix'] = 'suffix', -- Vancouver
['timestamp'] = 'timestamp', -- |archive-url=
['unknown language code'] = 'unknown language code', -- |script-<param>=
['value'] = 'value', -- |bibcode=
['year'] = 'year', -- |bibcode=
}
--[[--------------< E R R O R _ C O N D I T I O N S >---------------------------
Error condition table. This table has two sections: errors at the top, maintenance
at the bottom. Maint 'messaging' does not have a 'message' (message=nil)
The following contains a list of IDs for various error conditions defined in the
code. For each ID, we specify a text message to display, an error category to
include, and whether the error message should be wrapped as a hidden comment.
Anchor changes require identical changes to matching anchor in Help:CS1 errors
TODO: rename error_conditions{} to something more generic; create separate error
and maint tables inside that?
]]
local error_conditions = {
err_accessdate_missing_url = {
message = '<code class="cs1-code">|access-date=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'accessdate_missing_url',
category = 'CS1 errors: access-date without URL',
hidden = false
},
err_apostrophe_markup = {
message = 'Italic or bold markup not allowed in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'apostrophe_markup',
category = 'CS1 errors: markup',
hidden = false
},
err_archive_date_missing_url = {
message = '<code class="cs1-code">|archive-date=</code> requires <code class="cs1-code">|archive-url=</code>',
anchor = 'archive_date_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_date_url_ts_mismatch = {
message = '<code class="cs1-code">|archive-date=</code> / <code class="cs1-code">|archive-url=</code> timestamp mismatch; $1 suggested',
anchor = 'archive_date_url_ts_mismatch',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_date = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|archive-date=</code>',
anchor = 'archive_missing_date',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_url = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'archive_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_url = {
message = '<code class="cs1-code">|archive-url=</code> is malformed: $1', -- $1 is error message detail
anchor = 'archive_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_arxiv_missing = {
message = '<code class="cs1-code">|arxiv=</code> required',
anchor = 'arxiv_missing',
category = 'CS1 errors: arXiv', -- same as bad arxiv
hidden = false
},
err_asintld_missing_asin = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|asin=</code>', -- $1 is parameter name
anchor = 'asintld_missing_asin',
category = 'CS1 errors: ASIN TLD',
hidden = false
},
err_bad_arxiv = {
message = 'Check <code class="cs1-code">|arxiv=</code> value',
anchor = 'bad_arxiv',
category = 'CS1 errors: arXiv',
hidden = false
},
err_bad_asin = {
message = 'Check <code class="cs1-code">|asin=</code> value',
anchor = 'bad_asin',
category ='CS1 errors: ASIN',
hidden = false
},
err_bad_asin_tld = {
message = 'Check <code class="cs1-code">|asin-tld=</code> value',
anchor = 'bad_asin_tld',
category ='CS1 errors: ASIN TLD',
hidden = false
},
err_bad_bibcode = {
message = 'Check <code class="cs1-code">|bibcode=</code> $1', -- $1 is error message detail
anchor = 'bad_bibcode',
category = 'CS1 errors: bibcode',
hidden = false
},
err_bad_biorxiv = {
message = 'Check <code class="cs1-code">|biorxiv=</code> value',
anchor = 'bad_biorxiv',
category = 'CS1 errors: bioRxiv',
hidden = false
},
err_bad_citeseerx = {
message = 'Check <code class="cs1-code">|citeseerx=</code> value',
anchor = 'bad_citeseerx',
category = 'CS1 errors: citeseerx',
hidden = false
},
err_bad_date = {
message = 'Check date values in: $1', -- $1 is a parameter name list
anchor = 'bad_date',
category = 'CS1 errors: dates',
hidden = false
},
err_bad_doi = {
message = 'Check <code class="cs1-code">|doi=</code> value',
anchor = 'bad_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_bad_hdl = {
message = 'Check <code class="cs1-code">|hdl=</code> value',
anchor = 'bad_hdl',
category = 'CS1 errors: HDL',
hidden = false
},
err_bad_isbn = {
message = 'Check <code class="cs1-code">|isbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_isbn',
category = 'CS1 errors: ISBN',
hidden = false
},
err_bad_ismn = {
message = 'Check <code class="cs1-code">|ismn=</code> value',
anchor = 'bad_ismn',
category = 'CS1 errors: ISMN',
hidden = false
},
err_bad_issn = {
message = 'Check <code class="cs1-code">|$1issn=</code> value', -- $1 is 'e' or '' for eissn or issn
anchor = 'bad_issn',
category = 'CS1 errors: ISSN',
hidden = false
},
err_bad_jfm = {
message = 'Check <code class="cs1-code">|jfm=</code> value',
anchor = 'bad_jfm',
category = 'CS1 errors: JFM',
hidden = false
},
err_bad_jstor = {
message = 'Check <code class="cs1-code">|jstor=</code> value',
anchor = 'bad_jstor',
category = 'CS1 errors: JSTOR',
hidden = false
},
err_bad_lccn = {
message = 'Check <code class="cs1-code">|lccn=</code> value',
anchor = 'bad_lccn',
category = 'CS1 errors: LCCN',
hidden = false
},
err_bad_medrxiv = {
message = 'Check <code class="cs1-code">|medrxiv=</code> value',
anchor = 'bad_medrxiv',
category = 'CS1 errors: medRxiv',
hidden = false
},
err_bad_mr = {
message = 'Check <code class="cs1-code">|mr=</code> value',
anchor = 'bad_mr',
category = 'CS1 errors: MR',
hidden = false
},
err_bad_oclc = {
message = 'Check <code class="cs1-code">|oclc=</code> value',
anchor = 'bad_oclc',
category = 'CS1 errors: OCLC',
hidden = false
},
err_bad_ol = {
message = 'Check <code class="cs1-code">|ol=</code> value',
anchor = 'bad_ol',
category = 'CS1 errors: OL',
hidden = false
},
err_bad_osti = {
message = 'Check <code class="cs1-code">|osti=</code> value',
anchor = 'bad_osti',
category = 'CS1 errors: OSTI',
hidden = false
},
err_bad_paramlink = { -- for |title-link=, |author/editor/translator-link=, |series-link=, |episode-link=
message = 'Check <code class="cs1-code">|$1=</code> value', -- $1 is parameter name
anchor = 'bad_paramlink',
category = 'CS1 errors: parameter link',
hidden = false
},
err_bad_pmc = {
message = 'Check <code class="cs1-code">|pmc=</code> value',
anchor = 'bad_pmc',
category = 'CS1 errors: PMC',
hidden = false
},
err_bad_pmid = {
message = 'Check <code class="cs1-code">|pmid=</code> value',
anchor = 'bad_pmid',
category = 'CS1 errors: PMID',
hidden = false
},
err_bad_rfc = {
message = 'Check <code class="cs1-code">|rfc=</code> value',
anchor = 'bad_rfc',
category = 'CS1 errors: RFC',
hidden = false
},
err_bad_s2cid = {
message = 'Check <code class="cs1-code">|s2cid=</code> value',
anchor = 'bad_s2cid',
category = 'CS1 errors: S2CID',
hidden = false
},
err_bad_sbn = {
message = 'Check <code class="cs1-code">|sbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_sbn',
category = 'CS1 errors: SBN',
hidden = false
},
err_bad_ssrn = {
message = 'Check <code class="cs1-code">|ssrn=</code> value',
anchor = 'bad_ssrn',
category = 'CS1 errors: SSRN',
hidden = false
},
err_bad_url = {
message = 'Check $1 value', -- $1 is parameter name
anchor = 'bad_url',
category = 'CS1 errors: URL',
hidden = false
},
err_bad_usenet_id = {
message = 'Check <code class="cs1-code">|message-id=</code> value',
anchor = 'bad_message_id',
category = 'CS1 errors: message-id',
hidden = false
},
err_bad_zbl = {
message = 'Check <code class="cs1-code">|zbl=</code> value',
anchor = 'bad_zbl',
category = 'CS1 errors: Zbl',
hidden = false
},
err_bare_url_missing_title = {
message = '$1 missing title', -- $1 is parameter name
anchor = 'bare_url_missing_title',
category = 'CS1 errors: bare URL',
hidden = false
},
err_biorxiv_missing = {
message = '<code class="cs1-code">|biorxiv=</code> required',
anchor = 'biorxiv_missing',
category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv
hidden = false
},
err_chapter_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'chapter_ignored',
category = 'CS1 errors: chapter ignored',
hidden = false
},
err_citation_missing_title = {
message = 'Missing or empty <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'citation_missing_title',
category = 'CS1 errors: missing title',
hidden = false
},
err_citeseerx_missing = {
message = '<code class="cs1-code">|citeseerx=</code> required',
anchor = 'citeseerx_missing',
category = 'CS1 errors: citeseerx', -- same as bad citeseerx
hidden = false
},
err_cite_web_url = { -- this error applies to cite web and to cite podcast
message = 'Missing or empty <code class="cs1-code">|url=</code>',
anchor = 'cite_web_url',
category = 'CS1 errors: requires URL',
hidden = false
},
err_class_ignored = {
message = '<code class="cs1-code">|class=</code> ignored',
anchor = 'class_ignored',
category = 'CS1 errors: class',
hidden = false
},
err_contributor_ignored = {
message = '<code class="cs1-code">|contributor=</code> ignored',
anchor = 'contributor_ignored',
category = 'CS1 errors: contributor',
hidden = false
},
err_contributor_missing_required_param = {
message = '<code class="cs1-code">|contributor=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'contributor_missing_required_param',
category = 'CS1 errors: contributor',
hidden = false
},
err_deprecated_params = {
message = 'Cite uses deprecated parameter <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'deprecated_params',
category = 'CS1 errors: deprecated parameters',
hidden = false
},
err_disp_name = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name; $2 is the assigned value
anchor = 'disp_name',
category = 'CS1 errors: display-names',
hidden = false,
},
err_doibroken_missing_doi = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|doi=</code>', -- $1 is parameter name
anchor = 'doibroken_missing_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_embargo_missing_pmc = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|pmc=</code>', -- $1 is parameter name
anchor = 'embargo_missing_pmc',
category = 'CS1 errors: PMC embargo',
hidden = false
},
err_empty_citation = {
message = 'Empty citation',
anchor = 'empty_citation',
category = 'CS1 errors: empty citation',
hidden = false
},
err_etal = {
message = 'Explicit use of et al. in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'explicit_et_al',
category = 'CS1 errors: explicit use of et al.',
hidden = false
},
err_extra_text_edition = {
message = '<code class="cs1-code">|edition=</code> has extra text',
anchor = 'extra_text_edition',
category = 'CS1 errors: extra text: edition',
hidden = false,
},
err_extra_text_issue = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_issue',
category = 'CS1 errors: extra text: issue',
hidden = false,
},
err_extra_text_pages = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_pages',
category = 'CS1 errors: extra text: pages',
hidden = false,
},
err_extra_text_volume = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_volume',
category = 'CS1 errors: extra text: volume',
hidden = false,
},
err_first_missing_last = {
message = '<code class="cs1-code">|$1=</code> missing <code class="cs1-code">|$2=</code>', -- $1 is first alias, $2 is matching last alias
anchor = 'first_missing_last',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_format_missing_url = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|$2=</code>', -- $1 is format parameter $2 is url parameter
anchor = 'format_missing_url',
category = 'CS1 errors: format without URL',
hidden = false
},
err_generic_name = {
message = '<code class="cs1-code">|$1=</code> has generic name', -- $1 is parameter name
anchor = 'generic_name',
category = 'CS1 errors: generic name',
hidden = false,
},
err_generic_title = {
message = 'Cite uses generic title',
anchor = 'generic_title',
category = 'CS1 errors: generic title',
hidden = false,
},
err_invalid_isbn_date = {
message = 'ISBN / Date incompatibility',
anchor = 'invalid_isbn_date',
category = 'CS1 errors: ISBN date',
hidden = true
},
err_invalid_param_val = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name $2 is parameter value
anchor = 'invalid_param_val',
category = 'CS1 errors: invalid parameter value',
hidden = false
},
err_invisible_char = {
message = '$1 in $2 at position $3', -- $1 is invisible char $2 is parameter name $3 is position number
anchor = 'invisible_char',
category = 'CS1 errors: invisible characters',
hidden = false
},
err_medrxiv_missing = {
message = '<code class="cs1-code">|medrxiv=</code> required',
anchor = 'medrxiv_missing',
category = 'CS1 errors: medRxiv', -- same as bad medRxiv
hidden = false
},
err_missing_name = {
message = 'Missing <code class="cs1-code">|$1$2=</code>', -- $1 is modified NameList; $2 is enumerator
anchor = 'missing_name',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_missing_periodical = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical periodical parameter name for cite $1
anchor = 'missing_periodical',
category = 'CS1 errors: missing periodical',
hidden = false
},
err_missing_pipe = {
message = 'Missing pipe in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'missing_pipe',
category = 'CS1 errors: missing pipe',
hidden = false
},
err_missing_publisher = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical publisher parameter name for cite $1
anchor = 'missing_publisher',
category = 'CS1 errors: missing publisher',
hidden = false
},
err_numeric_names = {
message = '<code class="cs1-code">|$1=</code> has numeric name', -- $1 is parameter name',
anchor = 'numeric_names',
category = 'CS1 errors: numeric name',
hidden = false,
},
err_param_access_requires_param = {
message = '<code class="cs1-code">|$1-access=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'param_access_requires_param',
category = 'CS1 errors: param-access',
hidden = false
},
err_param_has_ext_link = {
message = 'External link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_ext_link',
category = 'CS1 errors: external links',
hidden = false
},
err_param_has_twl_url = {
message = 'Wikipedia Library link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_twl_url',
category = 'CS1 errors: URL',
hidden = false
},
err_param_unknown_empty = {
message = 'Cite has empty unknown parameter$1: $2', -- $1 is 's' or empty space; $2 is emty unknown param list
anchor = 'param_unknown_empty',
category = 'CS1 errors: empty unknown parameters',
hidden = false
},
err_parameter_ignored = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'parameter_ignored',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_parameter_ignored_suggest = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored (<code class="cs1-code">|$2=</code> suggested)', -- $1 is unknown parameter $2 is suggested parameter name
anchor = 'parameter_ignored_suggest',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_periodical_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'periodical_ignored',
category = 'CS1 errors: periodical ignored',
hidden = false
},
err_redundant_parameters = {
message = 'More than one of $1 specified', -- $1 is error message detail
anchor = 'redundant_parameters',
category = 'CS1 errors: redundant parameter',
hidden = false
},
err_script_parameter = {
message = 'Invalid <code class="cs1-code">|$1=</code>: $2', -- $1 is parameter name $2 is script language code or error detail
anchor = 'script_parameter',
category = 'CS1 errors: script parameters',
hidden = false
},
err_ssrn_missing = {
message = '<code class="cs1-code">|ssrn=</code> required',
anchor = 'ssrn_missing',
category = 'CS1 errors: SSRN',
hidden = false
},
err_text_ignored = {
message = 'Text "$1" ignored', -- $1 is ignored text
anchor = 'text_ignored',
category = 'CS1 errors: unrecognized parameter',
hidden = false
},
err_trans_missing_title = {
message = '<code class="cs1-code">|trans-$1=</code> requires <code class="cs1-code">|$1=</code> or <code class="cs1-code">|script-$1=</code>', -- $1 is base parameter name
anchor = 'trans_missing_title',
category = 'CS1 errors: translated title',
hidden = false
},
err_url_suppressed = {
message = '<code class="cs1-code">|url=</code> suppressed',
anchor = 'url_suppressed',
category = 'CS1 errors: url suppressed',
hidden = false
},
err_vancouver = {
message = 'Vancouver style error: $1 in name $2', -- $1 is error detail, $2 is the nth name
anchor = 'vancouver',
category = 'CS1 errors: Vancouver style',
hidden = false
},
err_wikilink_in_url = {
message = 'URL–wikilink conflict', -- uses ndash
anchor = 'wikilink_in_url',
category = 'CS1 errors: URL–wikilink conflict', -- uses ndash
hidden = false
},
--[[--------------------------< M A I N T >-------------------------------------
maint messages do not have a message (message = nil); otherwise the structure
is the same as error messages
]]
maint_archive_origin = {
message = nil,
anchor = 'archive_origin',
category = 'CS1 maint: archive origin',
hidden = true,
},
maint_archived_copy = {
message = nil,
anchor = 'archived_copy',
category = 'CS1 maint: archived copy as title',
hidden = true,
},
maint_bibcode = {
message = nil,
anchor = 'bibcode',
category = 'CS1 maint: bibcode',
hidden = true,
},
maint_location_no_publisher = { -- cite book, conference, encyclopedia; citation as book cite or encyclopedia cite
message = nil,
anchor = 'location_no_publisher',
category = 'CS1 maint: location missing publisher',
hidden = true,
},
maint_bot_unknown = {
message = nil,
anchor = 'bot:_unknown',
category = 'CS1 maint: bot: original URL status unknown',
hidden = true,
},
maint_date_auto_xlated = { -- date auto-translation not supported by en.wiki
message = nil,
anchor = 'date_auto_xlated',
category = 'CS1 maint: date auto-translated',
hidden = true,
},
maint_date_format = {
message = nil,
anchor = 'date_format',
category = 'CS1 maint: date format',
hidden = true,
},
maint_date_year = {
message = nil,
anchor = 'date_year',
category = 'CS1 maint: date and year',
hidden = true,
},
maint_deprecated_archive = {
message = nil,
anchor = 'deprecated_archive',
category = 'CS1 maint: deprecated archival service',
hidden = true,
},
maint_doi_ignore = {
message = nil,
anchor = 'doi_ignore',
category = 'CS1 maint: ignored DOI errors',
hidden = true,
},
maint_doi_inactive = {
message = nil,
anchor = 'doi_inactive',
category = 'CS1 maint: DOI inactive',
hidden = true,
},
maint_doi_inactive_dated = {
message = nil,
anchor = 'doi_inactive_dated',
category = 'CS1 maint: DOI inactive as of $2$3$1', -- $1 is year, $2 is month-name or empty string, $3 is space or empty string
hidden = true,
},
maint_doi_unflagged_free = {
message = nil,
anchor = 'doi_unflagged_free',
category = 'CS1 maint: unflagged free DOI',
hidden = true,
},
maint_extra_punct = {
message = nil,
anchor = 'extra_punct',
category = 'CS1 maint: extra punctuation',
hidden = true,
},
maint_id_limit_load_fail = { -- applies to all cs1|2 templates on a page;
message = nil, -- maint message (category link) never emitted
anchor = 'id_limit_load_fail',
category = 'CS1 maint: ID limit load fail',
hidden = true,
},
maint_isbn_ignore = {
message = nil,
anchor = 'ignore_isbn_err',
category = 'CS1 maint: ignored ISBN errors',
hidden = true,
},
maint_issn_ignore = {
message = nil,
anchor = 'ignore_issn',
category = 'CS1 maint: ignored ISSN errors',
hidden = true,
},
maint_jfm_format = {
message = nil,
anchor = 'jfm_format',
category = 'CS1 maint: JFM format',
hidden = true,
},
maint_location = {
message = nil,
anchor = 'location',
category = 'CS1 maint: location',
hidden = true,
},
maint_misc_url = {
message = nil,
anchor = 'misc_url',
category = 'CS1 maint: miscellaneous url',
hidden = true,
},
maint_missing_class = {
message = nil,
anchor = 'missing_class',
category = 'CS1 maint: missing class',
hidden = true,
},
maint_mr_format = {
message = nil,
anchor = 'mr_format',
category = 'CS1 maint: MR format',
hidden = true,
},
maint_mult_names = {
message = nil,
anchor = 'mult_names',
category = 'CS1 maint: multiple names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_numeric_names = {
message = nil,
anchor = 'numeric_names',
category = 'CS1 maint: numeric names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_others = {
message = nil,
anchor = 'others',
category = 'CS1 maint: others',
hidden = true,
},
maint_others_avm = {
message = nil,
anchor = 'others_avm',
category = 'CS1 maint: others in cite AV media (notes)',
hidden = true,
},
maint_overridden_setting = {
message = nil,
anchor = 'overridden',
category = 'CS1 maint: overridden setting',
hidden = true,
},
maint_page_art_num = {
message = nil,
anchor = 'page_art_num',
category = 'CS1 maint: article number as page number',
hidden = true,
},
maint_periodical_has_isbn = {
message = nil,
anchor = 'periodical_has_isbn',
category = 'CS1 maint: periodical has ISBN',
hidden = true,
},
maint_pmc_embargo = {
message = nil,
anchor = 'embargo',
category = 'CS1 maint: PMC embargo expired',
hidden = true,
},
maint_pmc_format = {
message = nil,
anchor = 'pmc_format',
category = 'CS1 maint: PMC format',
hidden = true,
},
maint_postscript = {
message = nil,
anchor = 'postscript',
category = 'CS1 maint: postscript',
hidden = true,
},
maint_publisher_location = {
message = nil,
anchor = 'publisher_location',
category = 'CS1 maint: publisher location',
hidden = true,
},
maint_ref_duplicates_default = {
message = nil,
anchor = 'ref_default',
category = 'CS1 maint: ref duplicates default',
hidden = true,
},
maint_shortened_archive_url = {
message = nil,
anchor = 'shortened_archive_url',
category = 'CS1 maint: shortened archive url',
hidden = true,
},
maint_unknown_lang = {
message = nil,
anchor = 'unknown_lang',
category = 'CS1 maint: unrecognized language',
hidden = true,
},
maint_untitled = {
message = nil,
anchor = 'untitled',
category = 'CS1 maint: untitled periodical',
hidden = true,
},
maint_url_status = {
message = nil,
anchor = 'url_status',
category = 'CS1 maint: url-status',
hidden = true,
},
maint_work_isbn = {
message = nil,
anchor = 'work_isbn',
category = 'CS1 maint: work parameter with ISBN',
hidden = true,
},
maint_year= {
message = nil,
anchor = 'year',
category = 'CS1 maint: year',
hidden = true,
},
maint_zbl = {
message = nil,
anchor = 'zbl',
category = 'CS1 maint: Zbl',
hidden = true,
},
}
--[[--------------------------< I D _ L I M I T S _ D A T A _ T >----------------------------------------------
fetch id limits for certain identifiers from c:Data:CS1/Identifier limits.tab. This source is a json tabular
data file maintained at wikipedia commons. Convert the json format to a table of k/v pairs.
The values from <id_limits_data_t> are used to set handle.id_limit.
From 2025-02-21, MediaWiki is broken. Use this link to edit the tablular data file:
https://commons.wikimedia.org/w/index.php?title=Data:CS1/Identifier_limits.tab&action=edit
See Phab:T389105
]]
local id_limits_data_t;
local id_limits_data_load_fail = false; -- flag; assume that we will be successful when loading json id limit tabular data
local use_commons_data = true; -- set to false if your wiki does not have access to mediawiki commons; then,
if false == use_commons_data then -- update this table from https://commons.wikimedia.org/wiki/Data:CS1/Identifier_limits.tab; last update: 2026-08-02
id_limits_data_t = {['OCLC'] = 11160000000, ['OSTI'] = 23010000, ['PMC'] = 13500000, ['PMID'] = 42900000, ['RFC'] = 9300, ['SSRN'] = 7500000, ['S2CID'] = 290000000}; -- this table must be maintained locally
else -- here for wikis that do have access to mediawiki commons
local load_fail_limit = 99999999999; -- very high number to avoid error messages on load failure
id_limits_data_t = {['OCLC'] = load_fail_limit, ['OSTI'] = load_fail_limit, ['PMC'] = load_fail_limit, ['PMID'] = load_fail_limit, ['RFC'] = load_fail_limit, ['SSRN'] = load_fail_limit, ['S2CID'] = load_fail_limit};
if mw.ext.data == nil then
id_limits_data_load_fail = true; -- safeguard against Lua errors if mw.ext.data is not available for some reason
else
local tab_data_t = mw.ext.data.get ('CS1/Identifier limits.tab'); -- attempt to load the tabular data from commons into <tab_data_t>
if false == tab_data_t then -- undocumented 'feature': mw.ext.data.get() sometimes returns false
id_limits_data_load_fail = true; -- set the flag so that Module:Citation/CS1 can create an unannotated maint category
else
for _, limit_t in ipairs (tab_data_t.data) do -- overwrite default <load_fail_limit> values from the data table in the tabular data
id_limits_data_t[limit_t[1]] = limit_t[2]; -- <limit[1]> is identifier; <limit[2]> is upper limit for that identifier
end
end
end
end
--[[--------------------------< I D _ H A N D L E R S >--------------------------------------------------------
The following contains a list of values for various defined identifiers. For each
identifier we specify a variety of information necessary to properly render the
identifier in the citation.
parameters: a list of parameter aliases for this identifier; first in the list is the canonical form
link: Wikipedia article name
redirect: a local redirect to a local Wikipedia article name; at en.wiki, 'ISBN (identifier)' is a redirect to 'International Standard Book Number'
q: Wikidata q number for the identifier
label: the label preceding the identifier; label is linked to a Wikipedia article (in this order):
redirect from id_handlers['<id>'].redirect when use_identifier_redirects is true
Wikidata-supplied article name for the local wiki from id_handlers['<id>'].q
local article name from id_handlers['<id>'].link
prefix: the first part of a URL that will be concatenated with a second part which usually contains the identifier
suffix: optional third part to be added after the identifier
encode: true if URI should be percent-encoded; otherwise false
COinS: identifier link or keyword for use in COinS:
for identifiers registered at info-uri.info use: info:.... where '...' is the appropriate identifier label
for identifiers that have COinS keywords, use the keyword: rft.isbn, rft.issn, rft.eissn
for |asin= and |ol=, which require assembly, use the keyword: url
for others make a URL using the value in prefix/suffix and #label, use the keyword: pre (not checked; any text other than 'info', 'rft', or 'url' works here)
set to nil to leave the identifier out of the COinS
separator: character or text between label and the identifier in the rendered citation
id_limit: for those identifiers with established limits, this property holds the upper limit
access: use this parameter to set the access level for all instances of this identifier.
the value must be a valid access level for an identifier (see ['id-access'] in this file).
custom_access: to enable custom access level for an identifier, set this parameter
to the parameter that should control it (normally 'id-access')
]]
local id_handlers = {
['ARXIV'] = {
parameters = {'arxiv', 'eprint'},
link = 'arXiv',
redirect = 'arXiv (identifier)',
q = 'Q118398',
label = 'arXiv',
prefix = 'https://arxiv.org/abs/',
encode = false,
COinS = 'info:arxiv',
separator = ':',
access = 'free', -- free to read
},
['ASIN'] = {
parameters = { 'asin', 'ASIN' },
link = 'Amazon Standard Identification Number',
redirect = 'ASIN (identifier)',
q = 'Q1753278',
label = 'ASIN',
prefix = 'https://www.amazon.',
COinS = 'url',
separator = ' ',
encode = false;
},
['BIBCODE'] = {
parameters = {'bibcode'},
link = 'Bibcode',
redirect = 'Bibcode (identifier)',
q = 'Q25754',
label = 'Bibcode',
prefix = 'https://scixplorer.org/abs/',
encode = false,
COinS = 'info:bibcode',
separator = ':',
custom_access = 'bibcode-access',
},
['BIORXIV'] = {
parameters = {'biorxiv'},
link = 'bioRxiv',
redirect = 'bioRxiv (identifier)',
q = 'Q19835482',
label = 'bioRxiv',
prefix = 'https://doi.org/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['CITESEERX'] = {
parameters = {'citeseerx'},
link = 'CiteSeerX',
redirect = 'CiteSeerX (identifier)',
q = 'Q2715061',
label = 'CiteSeerX',
prefix = 'https://citeseerx.ist.psu.edu/viewdoc/summary?doi=',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['DOI'] = { -- Used by InternetArchiveBot
parameters = { 'doi', 'DOI'},
link = 'Digital object identifier',
redirect = 'doi (identifier)',
q = 'Q25670',
label = 'doi',
prefix = 'https://doi.org/',
COinS = 'info:doi',
separator = ':',
encode = true,
custom_access = 'doi-access',
},
['EISSN'] = {
parameters = {'eissn', 'EISSN'},
link = 'International Standard Serial Number#Electronic ISSN',
redirect = 'eISSN (identifier)',
q = 'Q46339674',
label = 'eISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.eissn',
encode = false,
separator = ' ',
},
['HDL'] = {
parameters = { 'hdl', 'HDL' },
link = 'Handle System',
redirect = 'hdl (identifier)',
q = 'Q3126718',
label = 'hdl',
prefix = 'https://hdl.handle.net/',
COinS = 'info:hdl',
separator = ':',
encode = true,
custom_access = 'hdl-access',
},
['ISBN'] = { -- Used by InternetArchiveBot
parameters = {'isbn', 'ISBN'},
link = 'International Standard Book Number',
redirect = 'ISBN (identifier)',
q = 'Q33057',
label = 'ISBN',
prefix = 'Special:BookSources/',
COinS = 'rft.isbn',
separator = ' ',
},
['ISMN'] = {
parameters = {'ismn', 'ISMN'},
link = 'International Standard Music Number',
redirect = 'ISMN (identifier)',
q = 'Q1666938',
label = 'ISMN',
prefix = '', -- not currently used;
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['ISSN'] = {
parameters = {'issn', 'ISSN'},
link = 'International Standard Serial Number',
redirect = 'ISSN (identifier)',
q = 'Q131276',
label = 'ISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.issn',
encode = false,
separator = ' ',
},
['JFM'] = {
parameters = {'jfm', 'JFM'},
link = 'Jahrbuch über die Fortschritte der Mathematik',
redirect = 'JFM (identifier)',
q = '',
label = 'JFM',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['JSTOR'] = {
parameters = {'jstor', 'JSTOR'},
link = 'JSTOR',
redirect = 'JSTOR (identifier)',
q = 'Q1420342',
label = 'JSTOR',
prefix = 'https://www.jstor.org/stable/',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
custom_access = 'jstor-access',
},
['LCCN'] = {
parameters = {'lccn', 'LCCN'},
link = 'Library of Congress Control Number',
redirect = 'LCCN (identifier)',
q = 'Q620946',
label = 'LCCN',
prefix = 'https://lccn.loc.gov/',
COinS = 'info:lccn',
encode = false,
separator = ' ',
},
['MEDRXIV'] = {
parameters = {'medrxiv'},
link = 'medRxiv',
redirect = 'medRxiv (identifier)',
q = 'Q58465838',
label = 'medRxiv',
prefix = 'https://www.medrxiv.org/content/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = false,
separator = ' ',
},
['MR'] = {
parameters = {'mr', 'MR'},
link = 'Mathematical Reviews',
redirect = 'MR (identifier)',
q = 'Q211172',
label = 'MR',
prefix = 'https://mathscinet.ams.org/mathscinet-getitem?mr=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['OCLC'] = {
parameters = {'oclc', 'OCLC'},
link = 'OCLC',
redirect = 'OCLC (identifier)',
q = 'Q190593',
label = 'OCLC',
prefix = 'https://search.worldcat.org/oclc/',
COinS = 'info:oclcnum',
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OCLC or 0,
},
['OL'] = {
parameters = { 'ol', 'OL' },
link = 'Open Library',
redirect = 'OL (identifier)',
q = 'Q1201876',
label = 'OL',
prefix = 'https://openlibrary.org/',
COinS = 'url',
separator = ' ',
encode = true,
custom_access = 'ol-access',
},
['OSTI'] = {
parameters = {'osti', 'OSTI'},
link = 'Office of Scientific and Technical Information',
redirect = 'OSTI (identifier)',
q = 'Q2015776',
label = 'OSTI',
prefix = 'https://www.osti.gov/biblio/',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OSTI or 0,
custom_access = 'osti-access',
},
['PMC'] = {
parameters = {'pmc', 'PMC'},
link = 'PubMed Central',
redirect = 'PMC (identifier)',
q = 'Q229883',
label = 'PMC',
prefix = 'https://www.ncbi.nlm.nih.gov/pmc/articles/PMC',
suffix = '',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.PMC or 0,
access = 'free', -- free to read
},
['PMID'] = {
parameters = {'pmid', 'PMID'},
link = 'PubMed Identifier',
redirect = 'PMID (identifier)',
q = 'Q2082879',
label = 'PMID',
prefix = 'https://pubmed.ncbi.nlm.nih.gov/',
COinS = 'info:pmid',
encode = false,
separator = ' ',
id_limit = id_limits_data_t.PMID or 0,
},
['RFC'] = {
parameters = {'rfc', 'RFC'},
link = 'Request for Comments',
redirect = 'RFC (identifier)',
q = 'Q212971',
label = 'RFC',
prefix = 'https://tools.ietf.org/html/rfc',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.RFC or 0,
access = 'free', -- free to read
},
['SBN'] = {
parameters = {'sbn', 'SBN'},
link = 'Standard Book Number', -- redirect to International_Standard_Book_Number#History
redirect = 'SBN (identifier)',
label = 'SBN',
prefix = 'Special:BookSources/0-', -- prefix has leading zero necessary to make 9-digit sbn a 10-digit isbn
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['SSRN'] = {
parameters = {'ssrn', 'SSRN'},
link = 'Social Science Research Network',
redirect = 'SSRN (identifier)',
q = 'Q7550801',
label = 'SSRN',
prefix = 'https://papers.ssrn.com/sol3/papers.cfm?abstract_id=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.SSRN or 0,
custom_access = 'ssrn-access',
},
['S2CID'] = {
parameters = {'s2cid', 'S2CID'},
link = 'Semantic Scholar',
redirect = 'S2CID (identifier)',
q = 'Q22908627',
label = 'S2CID',
prefix = 'https://api.semanticscholar.org/CorpusID:',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.S2CID or 0,
custom_access = 's2cid-access',
},
['USENETID'] = {
parameters = {'message-id'},
link = 'Usenet',
redirect = 'Usenet (identifier)',
q = 'Q193162',
label = 'Usenet:',
prefix = 'news:',
encode = false,
COinS = 'pre', -- use prefix value
separator = ' ',
},
['ZBL'] = {
parameters = {'zbl', 'ZBL' },
link = 'Zentralblatt MATH',
redirect = 'Zbl (identifier)',
q = 'Q190269',
label = 'Zbl',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
}
--[[--------------------------< E X P O R T S >---------------------------------
]]
return {
use_identifier_redirects = use_identifier_redirects, -- booleans defined in the settings at the top of this module
local_lang_cat_enable = local_lang_cat_enable,
date_name_auto_xlate_enable = date_name_auto_xlate_enable,
date_digit_auto_xlate_enable = date_digit_auto_xlate_enable,
enable_sort_keys = enable_sort_keys,
suppress_archive_today_urls = suppress_archive_today_urls,
-- tables and variables created when this module is loaded
dependencies_t = dependencies_t, -- used to suppress parameters dependent on url-holding parameters holding archive.today urls
enum_needs_xlation = '1' ~= date_names.xlate_digits['1'], -- to avoid unnecessary enumerator translation
global_df = get_date_format (), -- this line can be replaced with "global_df = 'dmy-all'," to have all dates auto translated to dmy format.
global_cs1_config_t = global_cs1_config_t, -- global settings from {{cs1 config}}
id_limits_data_load_fail = id_limits_data_load_fail, -- true when commons tabular identifier-limit data fails to load
known_free_doi_registrants_t = build_free_doi_registrants_table(),
punct_skip = build_skip_table (punct_skip, punct_meta_params),
url_skip = build_skip_table (url_skip, url_meta_params),
archive_today_tlds_t = {['today'] = true, ['ph'] = true, ['is'] = true, ['md'] = true, ['li'] = true, ['fo'] = true, ['vn'] = true}; -- used by is_archive_today_url()
name_space_sort_keys = name_space_sort_keys,
aliases = aliases,
special_case_translation = special_case_translation,
date_names = date_names,
err_msg_supl = err_msg_supl,
error_conditions = error_conditions,
et_al_patterns = et_al_patterns,
extended_registrants_t = extended_registrants_t,
id_handlers = id_handlers,
keywords_lists = keywords_lists,
keywords_xlate = keywords_xlate,
stripmarkers = stripmarkers,
invisible_chars = invisible_chars,
invisible_defs = invisible_defs,
indic_script = indic_script,
emoji_t = emoji_t,
messages = messages,
presentation = presentation,
prop_cats = prop_cats,
script_lang_codes = script_lang_codes,
lang_tag_remap = lang_tag_remap,
lang_name_remap = lang_name_remap,
this_wiki_code = this_wiki_code,
title_types = title_types,
uncategorized_namespaces = uncategorized_namespaces_t,
uncategorized_subpages = uncategorized_subpages,
templates_using_volume = templates_using_volume,
templates_using_issue = templates_using_issue,
templates_not_using_page = templates_not_using_page,
vol_iss_pg_patterns = vol_iss_pg_patterns,
single_letter_2nd_lvl_domains_t = single_letter_2nd_lvl_domains_t,
url_access_map_t = url_access_map_t,
inter_wiki_map = inter_wiki_map,
mw_languages_by_tag_t = mw_languages_by_tag_t,
mw_languages_by_name_t = mw_languages_by_name_t,
citation_class_map_t = citation_class_map_t,
citation_issue_t = citation_issue_t,
citation_no_volume_t = citation_no_volume_t,
}
mtf0w1ow8dokpa8ltsmoqupkxr4vaq4
124168
124167
2026-11-09T20:20:37Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Citation/CS1/Configuration]]
124167
Scribunto
text/plain
local lang_obj = mw.getContentLanguage(); -- make a language object for the local language; used here for languages and dates
--[[--------------------------< S E T T I N G S >--------------------------------------------------------------
boolean settings used to control various things. these setting located here to make them easy to find
]]
-- these settings local to this module only
local local_digits_from_mediawiki = false; -- for i18n; when true, module fills date_names['local_digits'] from MediaWiki; manual fill required else; always false at en.wiki
-- these settings exported to other modules
local use_identifier_redirects = true; -- when true use redirect name for identifier label links; always true at en.wiki
local local_lang_cat_enable = false; -- when true categorizes pages where |language=<local wiki's language>; always false at en.wiki
local date_name_auto_xlate_enable = false; -- when true translates English month-names to the local-wiki's language month names; always false at en.wiki
local date_digit_auto_xlate_enable = false; -- when true translates Western date digit to the local-wiki's language digits (date_names['local_digits']); always false at en.wiki
local enable_sort_keys = true; -- when true module adds namespace sort keys to error and maintenance category links
local suppress_archive_today_urls = true; -- when true module suppresses all parameters with an archive.today url and any deprendent parameters
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E S >------------------------------
List of namespaces identifiers for namespaces that will not be included in citation error categories.
Same as setting notracking = true by default.
For wikis that have a current version of Module:cs1 documentation support, this #invoke will return an unordered
list of namespace names and their associated identifiers:
{{#invoke:cs1 documentation support|uncategorized_namespace_lister|all=<anything>}}
]]
local uncategorized_namespaces_t = {[2]=true}; -- init with user namespace id
for k, _ in pairs (mw.site.talkNamespaces) do -- add all talk namespace ids
uncategorized_namespaces_t[k] = true;
end
local uncategorized_subpages = {'/[Ss]andbox', '/[Tt]estcases', '/[^/]*[Ll]og', '/[Aa]rchive'}; -- list of Lua patterns found in page names of pages we should not categorize
--[[
at en.wiki Greek characters are used as sort keys for certain items in a category so that those items are
placed at the end of a category page. See Wikipedia:Categorization#Sort_keys. That works well for en.wiki
because English is written using the Latn script. This may not work well for other languages. At en.wiki it
is desireable to place content from certain namespaces at the end of a category listing so the module adds sort
keys to error and maintenance category links when rendering a cs1|2 template on a page in that namespace.
i18n: if this does not work well for your language, set <enable_sort_keys> to false.
]]
local name_space_sort_keys = { -- sort keys to be used with these namespaces:
[4] = 'ω', -- wikipedia; omega
[10] = 'τ', -- template; tau
[118] = 'Δ', -- draft; delta
['other'] = 'ο', -- all other non-talk namespaces except main (article); omicron
}
--[[--------------------------< M E S S A G E S >--------------------------------------------------------------
Translation table
The following contains fixed text that may be output as part of a citation.
This is separated from the main body to aid in future translations of this
module.
]]
local messages = {
['agency'] = '$1 $2', -- $1 is sepc, $2 is agency
['archived-dead'] = 'Archived from $1 on $2',
['archived-live'] = '$1 from the original on $2',
['archived-unfit'] = 'Archived from the original on $1',
['archived'] = 'Archived',
['by'] = 'By', -- contributions to authored works: introduction, foreword, afterword
['cartography'] = 'Cartography by $1',
['collaboration'] = '$1 ($2)', -- $1 is author with et al, $2 is collaboration
['editor'] = 'ed.',
['editors'] = 'eds.',
['edition'] = '($1 ed.)',
['episode'] = 'Episode $1',
['et al'] = 'et al.',
['in'] = 'In', -- edited works
['inactive'] = ' (inactive $1)', -- $1 is date which the doi was found to be broken in
['inset'] = '$1 inset',
['interview'] = 'Interviewed by $1',
invisible_1 = '$1 $2', -- $1 stripmarker name; $2 is text from <invisible_chars[1]>
invisible_2 = '$1 character', -- $1 character name from <invisible_chars[1]>
['mismatch'] = '<code class="cs1-code">|$1=</code> / <code class="cs1-code">|$2=</code> mismatch', -- $1 is year param name; $2 is date param name
['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]: $1',
['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none
['original'] = 'the original',
['origdate'] = ' [$1]',
['retrieved'] = 'Retrieved $1',
['season'] = 'Season $1',
['section'] = '§ $1',
['sections'] = '§§ $1',
['series'] = '$1 $2', -- $1 is sepc, $2 is series
['seriesnum'] = 'Series $1',
['translated'] = 'Translated by $1',
['type'] = ' ($1)', -- for titletype
wikidata = 'Wikidata', -- these used for interwikilinked author/editor/... names
wikipedia = 'Wikipedia',
wikisource = 'Wikisource',
['vol'] = '$1 Vol. $2', -- $1 is sepc; bold journal style volume is in presentation{}
['vol-no'] = '$1 Vol. $2, no. $3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization)
['issue'] = '$1 No. $2', -- $1 is sepc
['art'] = '$1 Art. $2', -- $1 is sepc; for {{cite conference}} only
['vol-art'] = '$1 Vol. $2, art. $3', -- sepc, volume, article-number; for {{cite conference}} only
['j-vol'] = '$1 $2', -- sepc, volume; bold journal volume is in presentation{}
['j-issue'] = ' ($1)',
['j-article-num'] = ' $1', -- TODO: any punctuation here? static text?
['nopp'] = '$1 $2'; -- page(s) without prefix; $1 is sepc
['p-prefix'] = "$1 p. $2", -- $1 is sepc
['pp-prefix'] = "$1 pp. $2", -- $1 is sepc
['j-page(s)'] = ': $1', -- same for page and pages
['sheet'] = '$1 Sheet $2', -- $1 is sepc
['sheets'] = '$1 Sheets $2', -- $1 is sepc
['j-sheet'] = ': Sheet $1',
['j-sheets'] = ': Sheets $1',
['language'] = '(in $1)',
['via'] = " – via $1",
['event'] = 'Event occurs at',
['minutes'] = ' $1 minutes in', -- $1 is the number of minutes
-- Determines the location of the help page
['help page link'] = 'Help:CS1 errors',
['help page label'] = 'help',
-- categories
['cat wikilink'] = '[[Category:$1]]', -- $1 is the category name
['cat wikilink sk'] = '[[Category:$1|$2]]', -- $1 is the category name; $2 is namespace sort key
[':cat wikilink'] = '[[:Category:$1|link]]', -- category name as maintenance message wikilink; $1 is the category name
-- Internal errors (should only occur if configuration is bad)
['undefined_error'] = 'Called with an undefined error condition',
['unknown_ID_key'] = 'Unrecognized ID key: ', -- an ID key in id_handlers not found in ~/Identifiers func_map{}
['unknown_ID_access'] = 'Unrecognized ID access keyword: ', -- an ID access keyword in id_handlers not found in keywords_lists['id-access']{}
['unknown_argument_map'] = 'Argument map not defined for this variable',
['bare_url_no_origin'] = 'Bare URL found but origin indicator is nil or empty',
['warning_msg_e'] = '<span style="color:#d33"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has errors</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
['warning_msg_m'] = '<span style="color:#085"><code style="color: inherit; background: inherit; border: none; padding: inherit;">{{$1}}</code>: this [[#$2|reference]] has maintenance messages</span>; messages may be hidden ([[Help:CS1_errors#Controlling_error_message_display|help]]).'; -- $1 is template link; $2 is anchor ID
}
--[[--------------------------< C I T A T I O N _ C L A S S _ M A P >------------------------------------------
this table maps the value assigned to |CitationClass= in the cs1|2 templates to the canonical template name when
the value assigned to |CitationClass= is different from the canonical template name. |CitationClass= values are
used as class attributes in the <cite> tag that encloses the citation so these names may not contain spaces while
the canonical template name may. These names are used in warning_msg_e and warning_msg_m to create links to the
template's documentation when an article is displayed in preview mode.
]]
local citation_class_map_t = { -- TODO: in Module:Cite/config write a function to use this table
arxiv = 'cite arXiv', -- as the source for known_templates_t and citation_classes_t
['audio-visual'] = 'cite AV media',
['AV-media-notes'] = 'cite AV media notes',
biorxiv = 'cite bioRxiv',
book = 'cite book',
citation = 'citation',
citeseerx = 'cite CiteSeerX',
conference = 'cite conference',
document = 'cite document',
encyclopaedia = 'cite encyclopedia',
episode = 'cite episode',
interview = 'cite interview',
journal = 'cite journal',
magazine = 'cite magazine',
mailinglist = 'cite mailing list',
map = 'cite map',
medrxiv = 'cite medRxiv',
news = 'cite news',
newsgroup = 'cite newsgroup',
podcast = 'cite podcast',
pressrelease = 'cite press release',
report = 'cite report',
serial = 'cite serial',
sign = 'cite sign',
speech = 'cite speech',
ssrn = 'cite SSRN',
techreport = 'cite tech report',
thesis = 'cite thesis',
web = 'cite web',
}
--[=[-------------------------< E T _ A L _ P A T T E R N S >--------------------------------------------------
This table provides Lua patterns for the phrase "et al" and variants in name text
(author, editor, etc.). The main module uses these to identify and emit the 'etal' message.
]=]
local et_al_patterns = {
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][%.;,\"']*$", -- variations on the 'et al' theme
"[;,]? *[\"']*%f[%a][Ee][Tt]%.? *[Aa][Ll][Ii][AaIi][Ee]?[%.;,\"']*$", -- variations on the 'et alia', 'et alii' and 'et aliae' themes (false positive 'et aliie' unlikely to match)
"[;,]? *%f[%a]and [Oo]thers", -- an alternative to et al.
"%[%[ *[Ee][Tt]%.? *[Aa][Ll]%.? *%]%]", -- a wikilinked form
"%(%( *[Ee][Tt]%.? *[Aa][Ll]%.? *%)%)", -- a double-bracketed form (to counter partial removal of ((...)) syntax)
"[%(%[] *[Ee][Tt]%.? *[Aa][Ll]%.? *[%)%]]", -- a bracketed form
}
--[[--------------------------< P R E S E N T A T I O N >------------------------
Fixed presentation markup. Originally part of citation_config.messages it has
been moved into its own, more semantically correct place.
]]
local presentation =
{
-- .citation-comment class is specified at Help:CS1_errors#Controlling_error_message_display
['hidden-error'] = '<span class="cs1-hidden-error citation-comment">$1</span>',
['visible-error'] = '<span class="cs1-visible-error citation-comment">$1</span>',
['hidden-maint'] = '<span class="cs1-maint citation-comment">$1</span>',
['accessdate'] = '<span class="reference-accessdate">$1$2</span>', -- to allow editors to hide accessdate using personal CSS
['bdi'] = '<bdi$1>$2</bdi>', -- bidirectional isolation used with |script-title= and the like
['cite'] = '<cite class="$1">$2</cite>'; -- for use when citation does not have a namelist and |ref= not set so no id="..." attribute
['cite-id'] = '<cite id="$1" class="$2">$3</cite>'; -- for use when when |ref= is set or when citation has a namelist
['format'] = ' <span class="cs1-format">($1)</span>', -- for |format=, |chapter-format=, etc.
['interwiki'] = ' <span class="cs1-format">[in $1]</span>', -- for interwiki-language-linked author, editor, etc
['interproj'] = ' <span class="cs1-format">[at $1]</span>', -- for interwiki-project-linked author, editor, etc (:d: and :s: supported; :w: ignored)
-- various access levels, for |access=, |doi-access=, |arxiv=, ...
-- narrow no-break space   may work better than nowrap CSS. Or not? Browser support?
['ext-link-access-signal'] = '<span class="$1" title="$2">$3</span>', -- external link with appropriate lock icon
['free'] = {class='id-lock-free', title='Freely accessible'}, -- classes defined in Module:Citation/CS1/styles.css
['registration'] = {class='id-lock-registration', title='Free registration required'},
['limited'] = {class='id-lock-limited', title='Free access subject to limited trial, subscription normally required'},
['subscription'] = {class='id-lock-subscription', title='Paid subscription required'},
['interwiki-icon'] = '<span class="$1" title="$2">$3</span>',
['class-wikisource'] = 'cs1-ws-icon',
['italic-title'] = "''$1''",
['kern-left'] = '<span class="cs1-kern-left"></span>$1', -- spacing to use when title contains leading single or double quote mark
['kern-right'] = '$1<span class="cs1-kern-right"></span>', -- spacing to use when title contains trailing single or double quote mark
['nowrap1'] = '<span class="nowrap">$1</span>', -- for nowrapping an item: <span ...>yyyy-mm-dd</span>
['nowrap2'] = '<span class="nowrap">$1</span> $2', -- for nowrapping portions of an item: <span ...>dd mmmm</span> yyyy (note white space)
['ocins'] = '<span title="$1" class="Z3988"></span>',
['parameter'] = '<code class="cs1-code">|$1=</code>',
['ps_cs1'] = '.'; -- CS1 style postscript (terminal) character
['ps_cs2'] = ''; -- CS2 style postscript (terminal) character (empty string)
['quoted-text'] = '<q>$1</q>', -- for wrapping |quote= content
['quoted-title'] = '"$1"',
['sep_cs1'] = '.', -- CS1 element separator
['sep_cs2'] = ',', -- CS2 separator
['sep_nl'] = ';', -- CS1|2 style name-list separator between names is a semicolon
['sep_nl_and'] = ' and ', -- used as last nl sep when |name-list-style=and and list has 2 items
['sep_nl_end'] = '; and ', -- used as last nl sep when |name-list-style=and and list has 3+ names
['sep_name'] = ', ', -- CS1|2 style last/first separator is <comma><space>
['sep_nl_vanc'] = ',', -- Vancouver style name-list separator between authors is a comma
['sep_name_vanc'] = ' ', -- Vancouver style last/first separator is a space
['sep_list'] = ', ', -- used for |language= when list has 3+ items except for last sep which uses sep_list_end
['sep_list_pair'] = ' and ', -- used for |language= when list has 2 items
['sep_list_end'] = ', and ', -- used as last list sep for |language= when list has 3+ items
['trans-italic-title'] = "[''$1'']",
['trans-quoted-title'] = "[$1]", -- for |trans-title= and |trans-quote=
['vol-bold'] = '$1 <b>$2</b>', -- sepc, volume; for bold journal cites; for other cites ['vol'] in messages{}
}
--[[--------------------------< A L I A S E S >---------------------------------
Aliases table for commonly passed parameters.
Parameter names on the right side in the assignments in this table must have been
defined in the Whitelist before they will be recognized as valid parameter names
]]
local aliases = {
['AccessDate'] = {'access-date', 'accessdate'}, -- Used by InternetArchiveBot
['Agency'] = 'agency',
['ArchiveDate'] = {'archive-date', 'archivedate'}, -- Used by InternetArchiveBot
['ArchiveFormat'] = 'archive-format',
['ArchiveURL'] = {'archive-url', 'archiveurl'}, -- Used by InternetArchiveBot
['ArticleNumber'] = 'article-number',
['ASINTLD'] = 'asin-tld',
['At'] = 'at', -- Used by InternetArchiveBot
['Authors'] = {'people', 'credits'},
['BookTitle'] = {'book-title', 'booktitle'},
['Cartography'] = 'cartography',
['Chapter'] = {'chapter', 'contribution', 'entry', 'article', 'section'},
['ChapterFormat'] = {'chapter-format', 'contribution-format', 'entry-format',
'article-format', 'section-format'};
['ChapterURL'] = {'chapter-url', 'contribution-url', 'entry-url', 'article-url', 'section-url'}, -- Used by InternetArchiveBot
['ChapterUrlAccess'] = {'chapter-url-access', 'contribution-url-access',
'entry-url-access', 'article-url-access', 'section-url-access'}, -- Used by InternetArchiveBot
['Class'] = 'class', -- cite arxiv and arxiv identifier
['Collaboration'] = 'collaboration',
['Conference'] = {'conference', 'event'},
['ConferenceFormat'] = 'conference-format',
['ConferenceURL'] = 'conference-url', -- Used by InternetArchiveBot
['Date'] = {'date', 'publication-date', 'air-date', 'airdate'}, -- air-date and airdate for cite episode and cite serial only
['Degree'] = 'degree',
['DF'] = 'df',
['DisplayAuthors'] = {'display-authors', 'display-subjects'},
['DisplayContributors'] = 'display-contributors',
['DisplayEditors'] = 'display-editors',
['DisplayInterviewers'] = 'display-interviewers',
['DisplayTranslators'] = 'display-translators',
['Docket'] = 'docket',
['DoiBroken'] = 'doi-broken-date',
['Edition'] = 'edition',
['Embargo'] = 'pmc-embargo-date',
['Encyclopedia'] = {'encyclopedia', 'encyclopaedia', 'dictionary'}, -- cite encyclopedia only
['Episode'] = 'episode', -- cite serial only TODO: make available to cite episode?
['Format'] = 'format',
['ID'] = {'id', 'ID'},
['Inset'] = 'inset',
['Issue'] = {'issue', 'number'},
['Language'] = {'language', 'lang'},
['MailingList'] = {'mailing-list', 'mailinglist'}, -- cite mailing list only
['Map'] = 'map', -- cite map only
['MapFormat'] = 'map-format', -- cite map only
['MapURL'] = {'map-url', 'mapurl'}, -- cite map only -- Used by InternetArchiveBot
['MapUrlAccess'] = 'map-url-access', -- cite map only -- Used by InternetArchiveBot
['Minutes'] = 'minutes',
['Mode'] = 'mode',
['NameListStyle'] = 'name-list-style',
['Network'] = 'network',
['Newsgroup'] = 'newsgroup', -- cite newsgroup only
['NoPP'] = {'no-pp', 'nopp'},
['NoTracking'] = {'no-tracking', 'template-doc-demo'},
['Number'] = 'number', -- this case only for cite techreport
['OrigDate'] = {'orig-date', 'orig-year', 'origyear'},
['Others'] = 'others',
['Page'] = {'page', 'p'}, -- Used by InternetArchiveBot
['Pages'] = {'pages', 'pp'}, -- Used by InternetArchiveBot
['Periodical'] = {'journal', 'magazine', 'newspaper', 'periodical', 'website', 'work'},
['PostScript'] = 'postscript',
['PublicationPlace'] = {'publication-place', 'location', 'place'}, -- TODO: when all templates that use |publication-place= and |place= or |location= make 'location' cannonical
['PublisherName'] = {'publisher', 'institution'},
['Quote'] = {'quote', 'quotation'},
['QuotePage'] = 'quote-page',
['QuotePages'] = 'quote-pages',
['Ref'] = 'ref',
['Scale'] = 'scale',
['ScriptChapter'] = {'script-chapter', 'script-contribution', 'script-entry',
'script-article', 'script-section'},
['ScriptEncyclopedia'] = {'script-encyclopedia', 'script-encyclopaedia'}, -- cite encyclopedia only
['ScriptMap'] = 'script-map',
['ScriptPeriodical'] = {'script-journal', 'script-magazine', 'script-newspaper',
'script-periodical', 'script-website', 'script-work'},
['ScriptQuote'] = 'script-quote',
['ScriptTitle'] = 'script-title', -- Used by InternetArchiveBot
['Season'] = 'season',
['Sections'] = 'sections', -- cite map only
['Series'] = {'series', 'version'},
['SeriesLink'] = {'series-link', 'serieslink'},
['SeriesNumber'] = {'series-number', 'series-no'},
['Sheet'] = 'sheet', -- cite map only
['Sheets'] = 'sheets', -- cite map only
['Station'] = 'station',
['Time'] = 'time',
['TimeCaption'] = 'time-caption',
['Title'] = 'title', -- Used by InternetArchiveBot
['TitleLink'] = {'title-link', 'episode-link', 'episodelink'}, -- Used by InternetArchiveBot
['TitleNote'] = {'title-note', 'department'},
['TitleType'] = {'type', 'medium'},
['TransChapter'] = {'trans-article', 'trans-chapter', 'trans-contribution',
'trans-entry', 'trans-section'},
['Transcript'] = 'transcript',
['TranscriptFormat'] = 'transcript-format',
['TranscriptURL'] = 'transcript-url', -- Used by InternetArchiveBot
['TransEncyclopedia'] = {'trans-encyclopedia', 'trans-encyclopaedia'}, -- cite encyclopedia only
['TransMap'] = 'trans-map', -- cite map only
['TransPeriodical'] = {'trans-journal', 'trans-magazine', 'trans-newspaper',
'trans-periodical', 'trans-website', 'trans-work'},
['TransQuote'] = 'trans-quote',
['TransTitle'] = 'trans-title', -- Used by InternetArchiveBot
['URL'] = {'url', 'URL'}, -- Used by InternetArchiveBot
['UrlAccess'] = 'url-access', -- Used by InternetArchiveBot
['UrlStatus'] = 'url-status', -- Used by InternetArchiveBot
['Vauthors'] = 'vauthors',
['Veditors'] = 'veditors',
['Via'] = 'via',
['Volume'] = 'volume',
['Year'] = 'year',
['AuthorList-First'] = {"first#", "author-first#", "author#-first", "author-given#", "author#-given",
"subject-first#", "subject#-first", "subject-given#", "subject#-given",
"given#"},
['AuthorList-Last'] = {"last#", "author-last#", "author#-last", "author-surname#", "author#-surname",
"subject-last#", "subject#-last", "subject-surname#", "subject#-surname",
"author#", 'host#', "subject#", "surname#"},
['AuthorList-Link'] = {"author-link#", "author#-link", "subject-link#",
"subject#-link", "authorlink#", "author#link"},
['AuthorList-Mask'] = {"author-mask#", "author#-mask", "subject-mask#", "subject#-mask"},
['ContributorList-First'] = {'contributor-first#', 'contributor#-first',
'contributor-given#', 'contributor#-given'},
['ContributorList-Last'] = {'contributor-last#', 'contributor#-last',
'contributor-surname#', 'contributor#-surname', 'contributor#'},
['ContributorList-Link'] = {'contributor-link#', 'contributor#-link'},
['ContributorList-Mask'] = {'contributor-mask#', 'contributor#-mask'},
['EditorList-First'] = {"editor-first#", "editor#-first", "editor-given#", "editor#-given"},
['EditorList-Last'] = {"editor-last#", "editor#-last", "editor-surname#",
"editor#-surname", "editor#"},
['EditorList-Link'] = {"editor-link#", "editor#-link"},
['EditorList-Mask'] = {"editor-mask#", "editor#-mask"},
['InterviewerList-First'] = {'interviewer-first#', 'interviewer#-first',
'interviewer-given#', 'interviewer#-given'},
['InterviewerList-Last'] = {'interviewer-last#', 'interviewer#-last',
'interviewer-surname#', 'interviewer#-surname', 'interviewer#'},
['InterviewerList-Link'] = {'interviewer-link#', 'interviewer#-link'},
['InterviewerList-Mask'] = {'interviewer-mask#', 'interviewer#-mask'},
['TranslatorList-First'] = {'translator-first#', 'translator#-first',
'translator-given#', 'translator#-given'},
['TranslatorList-Last'] = {'translator-last#', 'translator#-last',
'translator-surname#', 'translator#-surname', 'translator#'},
['TranslatorList-Link'] = {'translator-link#', 'translator#-link'},
['TranslatorList-Mask'] = {'translator-mask#', 'translator#-mask'},
}
--[[--------------------------< D E P E N D E N C I E S _ T >--------------------------------------------------
a table of url-holding parameters upon which other parameters are dependent.
this table is used by has_archive_today_url() to suppress parameters that are dependant upon a url-holding parameter
that has as a value an archive.today (or alternate tld) url.
archive.today is deprecated at en.wiki; see Wikipedia:Requests_for_comment/Archive.is_RFC_5
]]
local url_dependency_map_t = { -- table of url-holding parameters and the meta-parameters that are dependent on them
['url'] = {'AccessDate', 'ArchiveURL', 'Format', 'UrlAccess'},
['archive-url'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['archiveurl'] = {'ArchiveDate', 'ArchiveFormat', 'UrlStatus'},
['article-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['chapter-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['conference-url'] = {'ConferenceFormat'},
['contribution-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['entry-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['map-url'] = {'MapFormat', 'MapUrlAccess'},
['section-url'] = {'ChapterFormat', 'ChapterUrlAccess'},
['transcript-url'] = {'TranscriptFormat'},
};
local dependencies_t = {}; -- the table of url-holding parameters and their dependent parameters
for url_param, meta_parameters_t in pairs (url_dependency_map_t) do -- sequence of meta-parameters (indexes) into <aliases> table
local dependant_params_t = {}; -- collection of parameters that are dependent on this <url_param>
for _, meta_parameter in ipairs (meta_parameters_t) do -- for each <aliases> meta-parameter (index)
if 'string' == type (aliases[meta_parameter]) then -- for single parameter names (no aliases), <aliases[meta_parameter]> will be a string
table.insert (dependant_params_t, aliases[meta_parameter]); -- add to this <url_param>'s dependency sequence
else
for _, alias in ipairs (aliases[meta_parameter]) do -- for each alias in aliases[meta_parameter] (aliases['AccessDate'] for example)
table.insert (dependant_params_t, alias); -- add to this <url_param>'s dependency sequence
end
end
end
dependencies_t[url_param] = dependant_params_t; -- add the <url_param> and its dependent parameters
end
--[[--------------------------< P U N C T _ S K I P >---------------------------
builds a table of parameter names that the extraneous terminal punctuation check should not check.
]]
local punct_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'BookTitle', 'Chapter', 'ScriptChapter', 'ScriptTitle', 'Title', 'TransChapter', 'Transcript', 'TransMap', 'TransTitle', -- title-holding parameters
'AuthorList-Mask', 'ContributorList-Mask', 'EditorList-Mask', 'InterviewerList-Mask', 'TranslatorList-Mask', -- name-list mask may have name separators
'PostScript', 'Quote', 'ScriptQuote', 'TransQuote', 'Ref', -- miscellaneous
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'MapURL', 'TranscriptURL', 'URL', -- URL-holding parameters
}
local url_meta_params = { -- table of aliases[] keys (meta parameters); each key has a table of parameter names for a value
'ArchiveURL', 'ChapterURL', 'ConferenceURL', 'ID', 'MapURL', 'TranscriptURL', 'URL', -- parameters allowed to hold urls
'Page', 'Pages', 'At', 'QuotePage', 'QuotePages', -- insource locators allowed to hold urls
}
local function build_skip_table (skip_t, meta_params)
for _, meta_param in ipairs (meta_params) do -- for each meta parameter key
local params = aliases[meta_param]; -- get the parameter or the table of parameters associated with the meta parameter name
if 'string' == type (params) then
skip_t[params] = 1; -- just a single parameter
else
for _, param in ipairs (params) do -- get the parameter name
skip_t[param] = 1; -- add the parameter name to the skip table
local count;
param, count = param:gsub ('#', ''); -- remove enumerator marker from enumerated parameters
if 0 ~= count then -- if removed
skip_t[param] = 1; -- add param name without enumerator marker
end
end
end
end
return skip_t;
end
local punct_skip = {};
local url_skip = {};
--[[--------------------------< U R L _ A C C E S S _ M A P >--------------------------------------------------
this table used by the wikipedia library url test, has_twl_url(), which automatically sets a url-access parameter
to 'subscription' when it discovers a wikipedia library url in any of the url-holding paramters used as keys in
this table.
translators: if your wiki uses parameter names for these url-holding parameters and their matching -access parameters,
add your wiki's parameters to this list. Leave the English parameters in place.
TODO: is there a better way to do this?
]]
local url_access_map_t = {
['chapter-url'] = 'chapter-url-access',
['contribution-url'] = 'contribution-url-access',
['entry-url'] = 'entry-url-access',
['article-url'] = 'article-url-access',
['section-url'] = 'section-url-access',
['map-url'] = 'map-url-access',
['mapurl'] = 'map-url-access',
['url'] = 'url-access',
['URL'] = 'url-access'
}
--[[--------------------------< S I N G L E - L E T T E R S E C O N D - L E V E L D O M A I N S >----------
this is a list of tlds that are known to have single-letter second-level domain names. This list does not include
ccTLDs which are accepted in is_domain_name().
]]
local single_letter_2nd_lvl_domains_t = {'cash', 'company', 'foundation', 'media', 'org', 'today'};
--[[-----------< S P E C I A L C A S E T R A N S L A T I O N S >------------
This table is primarily here to support internationalization. Translations in
this table are used, for example, when an error message, category name, etc.,
is extracted from the English alias key. There may be other cases where
this translation table may be useful.
]]
local is_Latn = 'A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191';
local special_case_translation = {
author = 'author',
editor = 'editor',
name_list_params = '$1-name-list parameters', -- $1 is 'author' or 'editor'; used with err_redundant_parameters
['AuthorList'] = 'authors list', -- used to assemble maintenance category names
['ContributorList'] = 'contributors list', -- translation of these names plus translation of the base maintenance category names in maint_cats{} table below
['EditorList'] = 'editors list', -- must match the names of the actual categories
['InterviewerList'] = 'interviewers list', -- this group or translations used by name_has_ed_markup() and name_has_mult_names()
['TranslatorList'] = 'translators list',
-- Lua patterns to match pseudo-titles used by InternetArchiveBot and others as placeholder for unknown |title= value
['archived_copy'] = { -- used with CS1 maint: Archive[d] copy as title
['en'] = '^archived?%s+copy$', -- for English; translators: keep this because templates imported from en.wiki
['local'] = nil, -- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
},
-- Lua patterns to match generic titles; usually created by bots or reference filling tools
-- translators: replace ['local'] = nil with lowercase translation only when bots or tools create generic titles in your language
-- generic titles and patterns in this table should be lowercase only
-- leave ['local'] nil except when there is a matching generic title in your language
-- boolean 'true' for plain-text searches; 'false' for pattern searches
['generic_titles'] = {
['accept'] = {
},
['reject'] = {
{['en'] = {'^wayback%s+machine$', false}, ['local'] = nil},
{['en'] = {'are you a robot', true}, ['local'] = nil},
{['en'] = {'hugedomains', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?no +title[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'page not found', true}, ['local'] = nil},
{['en'] = {'subscribe to read', true}, ['local'] = nil},
{['en'] = {'^[%(%[{<]?unknown[>}%]%)]?$', false}, ['local'] = nil},
{['en'] = {'website is for sale', true}, ['local'] = nil},
{['en'] = {'^404', false}, ['local'] = nil},
{['en'] = {'error[ %-]404', false}, ['local'] = nil},
{['en'] = {'internet archive wayback machine', true}, ['local'] = nil},
{['en'] = {'log into facebook', true}, ['local'] = nil},
{['en'] = {'login • instagram', true}, ['local'] = nil},
{['en'] = {'redirecting...', true}, ['local'] = nil},
{['en'] = {'usurped title', true}, ['local'] = nil}, -- added by a GreenC bot
{['en'] = {'wayback machine', true}, ['local'] = nil},
{['en'] = {'webcite query result', true}, ['local'] = nil},
{['en'] = {'wikiwix\'s cache', true}, ['local'] = nil},
{['en'] = {'bot verification', true}, ['local'] = nil},
}
},
-- boolean 'true' for plain-text searches, search string must be lowercase only
-- boolean 'false' for pattern searches
-- leave ['local'] nil except when there is a matching generic name in your language
['generic_names'] = {
['accept'] = {
{['en'] = {'%[%[[^|]*%(author%) *|[^%]]*%]%]', false}, ['local'] = nil},
},
['reject'] = {
{['en'] = {'about us', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]dvisor%f[%A]', false}, ['local'] = nil},
{['en'] = {'allmusic', true}, ['local'] = nil},
{['en'] = {'%f[%a][Aa]uthor%f[%A]', false}, ['local'] = nil},
{['en'] = {'^[Bb]ureau$', false}, ['local'] = nil},
{['en'] = {'business', true}, ['local'] = nil},
{['en'] = {'cnn', true}, ['local'] = nil},
{['en'] = {'collaborator', true}, ['local'] = nil},
{['en'] = {'^[Cc]ompany$', false}, ['local'] = nil},
{['en'] = {'contributor', true}, ['local'] = nil},
{['en'] = {'contact us', true}, ['local'] = nil},
{['en'] = {'correspondent', true}, ['local'] = nil},
{['en'] = {'^[Dd]esk$', false}, ['local'] = nil},
{['en'] = {'directory', true}, ['local'] = nil},
{['en'] = {'%f[%(%[][%(%[]%s*eds?%.?%s*[%)%]]?$', false}, ['local'] = nil},
{['en'] = {'[,%.%s]%f[e]eds?%.?$', false}, ['local'] = nil},
{['en'] = {'^eds?[%.,;]', false}, ['local'] = nil},
{['en'] = {'^[%(%[]%s*[Ee][Dd][Ss]?%.?%s*[%)%]]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]dited%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]ditors?%f[%A]', false}, ['local'] = nil},
{['en'] = {'%f[%a][Ee]mail%f[%A]', false}, ['local'] = nil},
{['en'] = {'facebook', true}, ['local'] = nil},
{['en'] = {'google', true}, ['local'] = nil},
{['en'] = {'^[Gg]roup$', false}, ['local'] = nil},
{['en'] = {'home page', true}, ['local'] = nil},
{['en'] = {'^[Ii]nc%.?$', false}, ['local'] = nil},
{['en'] = {'instagram', true}, ['local'] = nil},
{['en'] = {'interviewer', true}, ['local'] = nil},
{['en'] = {'^[Ll]imited$', false}, ['local'] = nil},
{['en'] = {'linkedIn', true}, ['local'] = nil},
{['en'] = {'^[Nn]ews$', false}, ['local'] = nil},
{['en'] = {'[Nn]ews[ %-]?[Rr]oom', false}, ['local'] = nil},
{['en'] = {'pinterest', true}, ['local'] = nil},
{['en'] = {'policy', true}, ['local'] = nil},
{['en'] = {'privacy', true}, ['local'] = nil},
{['en'] = {'reuters', true}, ['local'] = nil},
{['en'] = {'translator', true}, ['local'] = nil},
{['en'] = {'tumblr', true}, ['local'] = nil},
{['en'] = {'twitter', true}, ['local'] = nil},
{['en'] = {'site name', true}, ['local'] = nil},
{['en'] = {'statement', true}, ['local'] = nil},
{['en'] = {'submitted', true}, ['local'] = nil},
{['en'] = {'super.?user', false}, ['local'] = nil},
{['en'] = {'%f['..is_Latn..'][Uu]ser%f[^'..is_Latn..']', false}, ['local'] = nil},
{['en'] = {'updated', true}, ['local'] = nil},
{['en'] = {'verfasser', true}, ['local'] = nil},
}
}
}
--[[--------------------------< D A T E _ N A M E S >----------------------------------------------------------
This table of tables lists local language date names and fallback English date names.
The code in Date_validation will look first in the local table for valid date names.
If date names are not found in the local table, the code will look in the English table.
Because citations can be copied to the local wiki from en.wiki, the English is
required when the date-name translation function date_name_xlate() is used.
In these tables, season numbering is defined by
Extended Date/Time Format (EDTF) Specification (https://www.loc.gov/standards/datetime/)
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard
defines various divisions using numbers 21-41. CS1|2 only supports generic seasons.
EDTF does support the distinction between north and south hemisphere seasons
but CS1|2 has no way to make that distinction.
33-36 = Quarter 1, Quarter 2, Quarter 3, Quarter 4 (3 months each)
The standard does not address 'named' dates so, for the purposes of CS1|2,
Easter and Christmas are defined here as 98 and 99, which should be out of the
ISO 8601 (EDTF) range of uses for a while.
local_date_names_from_mediawiki is a boolean. When set to:
true – module will fetch local month names from MediaWiki for both date_names['local']['long'] and date_names['local']['short']; this will unconditionally overwrite manual translations
false – module will *not* fetch local month names from MediaWiki
Caveat lector: There is no guarantee that MediaWiki will provide short month names. At your wiki you can test
the results of the MediaWiki fetch in the debug console with this command (the result is alpha sorted):
=mw.dumpObject (p.date_names['local'])
While the module can fetch month names from MediaWiki, it cannot fetch the quarter, season, and named date names
from MediaWiki. Those must be translated manually.
]]
local local_date_names_from_mediawiki = true; -- when false, manual translation required for date_names['local']['long'] and date_names['local']['short']; overwrites manual translations
-- when true, module fetches long and short month names from MediaWiki
local date_names = {
['en'] = { -- English
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
-- when local_date_names_from_mediawiki = false
['local'] = { -- replace these English date names with the local language equivalents
['long'] = {['January'] = 1, ['February'] = 2, ['March'] = 3, ['April'] = 4, ['May'] = 5, ['June'] = 6, ['July'] = 7, ['August'] = 8, ['September'] = 9, ['October'] = 10, ['November'] = 11, ['December'] = 12},
['short'] = {['Jan'] = 1, ['Feb'] = 2, ['Mar'] = 3, ['Apr'] = 4, ['May'] = 5, ['Jun'] = 6, ['Jul'] = 7, ['Aug'] = 8, ['Sep'] = 9, ['Oct'] = 10, ['Nov'] = 11, ['Dec'] = 12},
['quarter'] = {['First Quarter'] = 33, ['Second Quarter'] = 34, ['Third Quarter'] = 35, ['Fourth Quarter'] = 36},
['season'] = {['Winter'] = 24, ['Spring'] = 21, ['Summer'] = 22, ['Fall'] = 23, ['Autumn'] = 23},
['named'] = {['Easter'] = 98, ['Christmas'] = 99},
},
['inv_local_long'] = {}, -- used in date reformatting & translation; copy of date_names['local'].long where k/v are inverted: [1]='<local name>' etc.
['inv_local_short'] = {}, -- used in date reformatting & translation; copy of date_names['local'].short where k/v are inverted: [1]='<local name>' etc.
['inv_local_quarter'] = {}, -- used in date translation; copy of date_names['local'].quarter where k/v are inverted: [1]='<local name>' etc.
['inv_local_season'] = {}, -- used in date translation; copy of date_names['local'].season where k/v are inverted: [1]='<local name>' etc.
['inv_local_named'] = {}, -- used in date translation; copy of date_names['local'].named where k/v are inverted: [1]='<local name>' etc.
['local_digits'] = {['0'] = '0', ['1'] = '1', ['2'] = '2', ['3'] = '3', ['4'] = '4', ['5'] = '5', ['6'] = '6', ['7'] = '7', ['8'] = '8', ['9'] = '9'}, -- used to convert local language digits to Western 0-9
['xlate_digits'] = {},
}
if local_date_names_from_mediawiki then -- if fetching local month names from MediaWiki is enabled
local long_t = {};
local short_t = {};
for i=1, 12 do -- loop 12x and
local name = lang_obj:formatDate('F', '2022-' .. i .. '-1'); -- get long month name for each i
long_t[name] = i; -- save it
name = lang_obj:formatDate('M', '2022-' .. i .. '-1'); -- get short month name for each i
short_t[name] = i; -- save it
end
date_names['local']['long'] = long_t; -- write the long table – overwrites manual translation
date_names['local']['short'] = short_t; -- write the short table – overwrites manual translation
end
-- create inverted date-name tables for reformatting and/or translation
for _, invert_t in pairs {{'long', 'inv_local_long'}, {'short', 'inv_local_short'}, {'quarter', 'inv_local_quarter'}, {'season', 'inv_local_season'}, {'named', 'inv_local_named'}} do
for name, i in pairs (date_names['local'][invert_t[1]]) do -- this table is ['name'] = i
date_names[invert_t[2]][i] = name; -- invert to get [i] = 'name' for conversions from ymd
end
end
if local_digits_from_mediawiki then -- if fetching local digits from MediaWiki is enabled
local digits_t = {};
for i=0, 9 do -- loop 10x and
digits_t [lang_obj:formatNum (i)] = tostring (i); -- format the loop indexer as local lang table index and assign loop indexer (a string) as the value
end
date_names['local_digits'] = digits_t;
end
for ld, ed in pairs (date_names.local_digits) do -- make a digit translation table for simple date translation from en to local language using local_digits table
date_names.xlate_digits [ed] = ld; -- en digit becomes index with local digit as the value
end
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}}
'{{ *[Uu]se +(dmy) +dates *[|}]', -- 1159k -- sorted by approximate transclusion count
'{{ *[Uu]se +(mdy) +dates *[|}]', -- 212k
'{{ *[Uu]se +(MDY) +dates *[|}]', -- 788
'{{ *[Uu]se +(DMY) +dates *[|}]', -- 343
'{{ *([Mm]dy) *[|}]', -- 176
'{{ *[Uu]se *(dmy) *[|}]', -- 156 + 18
'{{ *[Uu]se *(mdy) *[|}]', -- 149 + 11
'{{ *([Dd]my) *[|}]', -- 56
'{{ *[Uu]se +(MDY) *[|}]', -- 5
'{{ *([Dd]MY) *[|}]', -- 3
'{{ *[Uu]se(mdy)dates *[|}]', -- 1
'{{ *[Uu]se +(DMY) *[|}]', -- 0
'{{ *([Mm]DY) *[|}]', -- 0
}
local title_object = mw.title.getCurrentTitle();
local content; -- done this way so that unused templates appear in unused-template-reports; self-transcluded makes them look like they are used
if 10 ~= title_object.namespace then -- all namespaces except Template
content = title_object:getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625
end
local function get_date_format ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects
local start, _, match = content:find(pattern); -- match is the three letters indicating desired date format
if match then
local use_dates_template = content:match ('%b{}', start); -- get the whole template
if use_dates_template:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length
return match:lower() .. '-' .. use_dates_template:match ('| *cs1%-dates *= *([lsy][sy]?)');
else
return match:lower() .. '-all'; -- no |cs1-dates= k/v pair; return value appropriate for use in |df=
end
end
end
end
--[[-----------------< V O L U M E , I S S U E , P A G E S >------------------
These tables hold cite class values (from the template invocation) and identify those templates that support
|volume=, |issue=, and |page(s)= parameters. Cite conference and cite map require further qualification which
is handled in the main module.
]]
local templates_using_volume = {'citation', 'audio-visual', 'book', 'conference', 'encyclopaedia', 'interview', 'journal', 'magazine', 'map', 'news', 'report', 'techreport', 'thesis'}
local templates_using_issue = {'citation', 'conference', 'episode', 'interview', 'journal', 'magazine', 'map', 'news', 'podcast'}
local templates_not_using_page = {'audio-visual', 'episode', 'mailinglist', 'newsgroup', 'podcast', 'serial', 'sign', 'speech'}
--[[
These tables control when it is appropriate for {{citation}} to render |volume= and/or |issue=. The parameter
names in the tables constrain {{citation}} so that its renderings match the renderings of the equivalent cs1
templates. For example, {{cite web}} does not support |volume= so the equivalent {{citation |website=...}} must
not support |volume=.
]]
local citation_no_volume_t = { -- {{citation}} does not render |volume= when these parameters are used
'website', 'mailinglist', 'script-website',
}
local citation_issue_t = { -- {{citation}} may render |issue= when these parameters are used
'journal', 'magazine', 'newspaper', 'periodical', 'work',
'script-journal', 'script-magazine', 'script-newspaper', 'script-periodical', 'script-work',
}
--[[
Patterns for finding extra text in |volume=, |issue=, |page=, |pages=
]]
local vol_iss_pg_patterns = {
good_ppattern = '^P[^%.PpGg]', -- OK to begin with uppercase P: P7 (page 7 of section P), but not p123 (page 123); TODO: this allows 'Pages' which it should not
bad_ppatterns = { -- patterns for |page= and |pages=
'^[Pp][PpGg]?%.?[ %d]',
'^[Pp][Pp]?%. ', -- from {{p.}} and {{pp.}} templates
'^[Pp]ages?',
'^[Pp]gs.?',
},
vi_patterns_t = { -- combined to catch volume-like text in |issue= and issue-like text in |volume=
'^volumes?', -- volume-like text
'^vols?[%.:=]?',
'^issues?', --issue-like text
'^iss[%.:=]?',
'^numbers?',
'^nos?%A', -- don't match 'november' or 'nostradamus'
'^nr[%.:=]?',
'^n[%.:= ]', -- might be a valid issue without separator (space char is sep char here)
'^n°', -- 'n' with degree sign (U+00B0)
'^№', -- precomposed unicode numero character (U+2116)
},
}
--[[--------------------------< K E Y W O R D S >-------------------------------
These tables hold keywords for those parameters that have defined sets of acceptable keywords.
]]
--[[-------------------< K E Y W O R D S T A B L E >--------------------------
this is a list of keywords; each key in the list is associated with a table of
synonymous keywords possibly from different languages.
for I18N: add local-language keywords to value table; do not change the key.
For example, adding the German keyword 'ja':
['affirmative'] = {'yes', 'true', 'y', 'ja'},
Because CS1|2 templates from en.wiki articles are often copied to other local wikis,
it is recommended that the English keywords remain in these tables.
]]
local keywords = {
['amp'] = {'&', 'amp', 'ampersand'}, -- |name-list-style=
['and'] = {'and', 'serial'}, -- |name-list-style=
['affirmative'] = {'yes', 'true', 'y'}, -- |no-tracking=, |no-pp= -- Used by InternetArchiveBot
['afterword'] = {'afterword'}, -- |contribution=
['bot: unknown'] = {'bot: unknown'}, -- |url-status= -- Used by InternetArchiveBot
['cs1'] = {'cs1'}, -- |mode=
['cs2'] = {'cs2'}, -- |mode=
['dead'] = {'dead', 'deviated'}, -- |url-status= -- Used by InternetArchiveBot
['dmy'] = {'dmy'}, -- |df=
['dmy-all'] = {'dmy-all'}, -- |df=
etal = {'etal'}, -- |display-authors=, etc
['foreword'] = {'foreword'}, -- |contribution=
['free'] = {'free'}, -- |<id>-access= -- Used by InternetArchiveBot
['harv'] = {'harv'}, -- |ref=; this no longer supported; is_valid_parameter_value() called with <invert> = true
['introduction'] = {'introduction'}, -- |contribution=
['limited'] = {'limited'}, -- |url-access= -- Used by InternetArchiveBot
['live'] = {'live'}, -- |url-status= -- Used by InternetArchiveBot
['mdy'] = {'mdy'}, -- |df=
['mdy-all'] = {'mdy-all'}, -- |df=
['none'] = {'none'}, -- |postscript=, |ref=, |title=, |type= -- Used by InternetArchiveBot
['off'] = {'off'}, -- |title= (potentially also: |title-link=, |postscript=, |ref=, |type=)
['preface'] = {'preface'}, -- |contribution=
['registration'] = {'registration'}, -- |url-access= -- Used by InternetArchiveBot
['subscription'] = {'subscription'}, -- |url-access= -- Used by InternetArchiveBot
['unfit'] = {'unfit'}, -- |url-status= -- Used by InternetArchiveBot
['usurped'] = {'usurped'}, -- |url-status= -- Used by InternetArchiveBot
['vanc'] = {'vanc'}, -- |name-list-style=
['ymd'] = {'ymd'}, -- |df=
['ymd-all'] = {'ymd-all'}, -- |df=
-- ['yMd'] = {'yMd'}, -- |df=; not supported at en.wiki
-- ['yMd-all'] = {'yMd-all'}, -- |df=; not supported at en.wiki
}
--[[------------------------< X L A T E _ K E Y W O R D S >---------------------
this function builds a list, keywords_xlate{}, of the keywords found in keywords{} where the values from keywords{}
become the keys in keywords_xlate{} and the keys from keywords{} become the values in keywords_xlate{}:
['affirmative'] = {'yes', 'true', 'y'}, -- in keywords{}
becomes
['yes'] = 'affirmative', -- in keywords_xlate{}
['true'] = 'affirmative',
['y'] = 'affirmative',
the purpose of this function is to act as a translator between a non-English keyword and its English equivalent
that may be used in other modules of this suite
]]
local function xlate_keywords ()
local out_table = {}; -- output goes here
for k, keywords_t in pairs (keywords) do -- spin through the keywords table
for _, keyword in ipairs (keywords_t) do -- for each keyword
out_table[keyword] = k; -- create an entry in the output table where keyword is the key
end
end
return out_table;
end
local keywords_xlate = xlate_keywords (); -- the list of translated keywords
--[[----------------< M A K E _ K E Y W O R D S _ L I S T >---------------------
this function assembles, for parameter-value validation, the list of keywords appropriate to that parameter.
keywords_lists{}, is a table of tables from keywords{}
]]
local function make_keywords_list (keywords_lists)
local out_table = {}; -- output goes here
for _, keyword_list in ipairs (keywords_lists) do -- spin through keywords_lists{} and get a table of keywords
for _, keyword in ipairs (keyword_list) do -- spin through keyword_list{} and add each keyword, ...
table.insert (out_table, keyword); -- ... as plain text, to the output list
end
end
return out_table;
end
--[[----------------< K E Y W O R D S _ L I S T S >-----------------------------
this is a list of lists of valid keywords for the various parameters in [key].
Generally the keys in this table are the canonical en.wiki parameter names though
some are contrived because of use in multiple differently named parameters:
['yes_true_y'], ['id-access'].
The function make_keywords_list() extracts the individual keywords from the
appropriate list in keywords{}.
The lists in this table are used to validate the keyword assignment for the
parameters named in this table's keys.
]]
local keywords_lists = {
['yes_true_y'] = make_keywords_list ({keywords.affirmative}),
['contribution'] = make_keywords_list ({keywords.afterword, keywords.foreword, keywords.introduction, keywords.preface}),
['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all']}),
-- ['df'] = make_keywords_list ({keywords.dmy, keywords['dmy-all'], keywords.mdy, keywords['mdy-all'], keywords.ymd, keywords['ymd-all'], keywords.yMd, keywords['yMd-all']}), -- not supported at en.wiki
['mode'] = make_keywords_list ({keywords.cs1, keywords.cs2}),
['name-list-style'] = make_keywords_list ({keywords.amp, keywords['and'], keywords.vanc}),
['ref'] = make_keywords_list ({keywords.harv}), -- inverted check; |ref=harv no longer supported
['url-access'] = make_keywords_list ({keywords.subscription, keywords.limited, keywords.registration}),
['url-status'] = make_keywords_list ({keywords.dead, keywords.live, keywords.unfit, keywords.usurped, keywords['bot: unknown']}),
['id-access'] = make_keywords_list ({keywords.free}),
}
--[[--------------------------< C S 1 _ C O N F I G _ G E T >--------------------------------------------------
fetch and validate values from {{cs1 config}} template to fill <global_cs1_config_t>
no error messages; when errors are detected, the parameter value from {{cs1 config}} is blanked.
Supports all parameters and aliases associated with the metaparameters: DisplayAuthors, DisplayContributors,
DisplayEditors, DisplayInterviewers, DisplayTranslators, NameListStyle, and Mode. The DisplayWhatever metaparameters
accept numeric values only (|display-authors=etal and the like is not supported).
]]
local global_cs1_config_t = {}; -- TODO: add value returned from get_date_format() to this table?
local function get_cs1_config ()
if not content then -- nil content when we're in template
return nil; -- auto-formatting does not work in Template space so don't set global_df
end
local start = content:find('{{ *[Cc][Ss]1 config *[|}]'); -- <start> is offset into <content> when {{cs1 config}} found; nil else
if start then
local cs1_config_template = content:match ('%b{}', start); -- get the whole template
if not cs1_config_template then
return nil;
end
local params_t = mw.text.split (cs1_config_template:gsub ('^{{%s*', ''):gsub ('%s*}}$', ''), '%s*|%s*'); -- remove '{{' and '}}'; make a sequence of parameter/value pairs (split on the pipe)
table.remove (params_t, 1); -- remove the template name because it isn't a parameter/value pair
local config_meta_params_t = {'DisplayAuthors', 'DisplayContributors', 'DisplayEditors', 'DisplayInterviewers', 'DisplayTranslators', 'NameListStyle', 'Mode'};
local meta_param_map_t = {}; -- list of accepted parameter names usable in {{cs1 config}} goes here
for _, meta_param in ipairs (config_meta_params_t) do -- for i18n using <config_meta_params_t>, map template parameter names to their metaparameter equivalents
if 'table' == type (aliases[meta_param]) then -- if <meta_param> is a sequence,
for _, param in ipairs (aliases[meta_param]) do -- extract its contents
meta_param_map_t[param] = meta_param; -- and add to <meta_param_map_t>
end
else
meta_param_map_t[aliases[meta_param]] = meta_param; -- not a sequence so just add the parameter to <meta_param_map_t>
end
end
local keywords_t = {}; -- map valid keywords to their associate metaparameter; reverse form of <keyword_lists[key] for these metaparameters
for _, metaparam_t in ipairs ({{'NameListStyle', 'name-list-style'}, {'Mode', 'mode'}}) do -- only these metaparameter / keywords_lists key pairs
for _, keyword in ipairs (keywords_lists[metaparam_t[2]]) do -- spin through the list of keywords
keywords_t[keyword] = metaparam_t[1]; -- add [keyword] = metaparameter to the map
end
end
for _, param in ipairs (params_t) do -- spin through the {{cs1 config}} parameters and fill <global_cs1_config_t>
local k, v = param:match ('([^=]-)%s*=%s*(.+)'); -- <k> is the parameter name; <v> is parameter's assigned value
if k then
if k:find ('^display') then -- if <k> is one of the |display-<namelist>= parameters
if v:match ('%d+') then -- the assigned value must be digits; doesn't accept 'etal'
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the display param and its value to globals table
end
else
if keywords_t[v] == meta_param_map_t[k] then -- keywords_t[v] returns nil or the metaparam name; these must be the same
global_cs1_config_t[meta_param_map_t[k]]=v; -- add the parameter and its value to globals table
end
end
end
end
end
end
get_cs1_config (); -- fill <global_cs1_config_t>
--[[---------------------< S T R I P M A R K E R S >----------------------------
Common pattern definition location for stripmarkers so that we don't have to go
hunting for them if (when) MediaWiki changes their form.
]]
local stripmarkers = {
['any'] = '\127[^\127]*UNIQ%-%-(%a+)%-[%a%d]+%-QINU[^\127]*\127', -- capture returns name of stripmarker
['math'] = '\127[^\127]*UNIQ%-%-math%-[%a%d]+%-QINU[^\127]*\127' -- math stripmarkers used in coins_cleanup() and coins_replace_math_stripmarker()
}
--[[------------< I N V I S I B L E _ C H A R A C T E R S >---------------------
This table holds non-printing or invisible characters indexed either by name or
by Unicode group. Values are decimal representations of UTF-8 codes. The table
is organized as a table of tables because the Lua pairs keyword returns table
data in an arbitrary order. Here, we want to process the table from top to bottom
because the entries at the top of the table are also found in the ranges specified
by the entries at the bottom of the table.
Also here is a pattern that recognizes stripmarkers that begin and end with the
delete characters. The nowiki stripmarker is not an error but some others are
because the parameter values that include them become part of the template's
metadata before stripmarker replacement.
]]
local invisible_defs = {
del = '\127', -- used to distinguish between stripmarker and del char
zwj = '\226\128\141', -- used with capture because zwj may be allowed
}
local invisible_chars = {
{'replacement', '\239\191\189'}, -- U+FFFD, EF BF BD
{'zero width joiner', '('.. invisible_defs.zwj .. ')'}, -- U+200D, E2 80 8D; capture because zwj may be allowed
{'zero width space', '\226\128\139'}, -- U+200B, E2 80 8B
{'hair space', '\226\128\138'}, -- U+200A, E2 80 8A
{'soft hyphen', '\194\173'}, -- U+00AD, C2 AD
{'horizontal tab', '\009'}, -- U+0009 (HT), 09
{'line feed', '\010'}, -- U+000A (LF), 0A
{'no-break space', '\194\160'}, -- U+00A0 (NBSP), C2 A0
{'carriage return', '\013'}, -- U+000D (CR), 0D
{'stripmarker', stripmarkers.any}, -- stripmarker; may or may not be an error; capture returns the stripmaker type
{'delete', '('.. invisible_defs.del .. ')'}, -- U+007F (DEL), 7F; must be done after stripmarker test; capture to distinguish isolated del chars not part of stripmarker
{'C0 control', '[\000-\008\011\012\014-\031]'}, -- U+0000–U+001F (NULL–US), 00–1F (except HT, LF, CR (09, 0A, 0D))
{'C1 control', '[\194\128-\194\159]'}, -- U+0080–U+009F (XXX–APC), C2 80 – C2 9F
-- {'Specials', '[\239\191\185-\239\191\191]'}, -- U+FFF9-U+FFFF, EF BF B9 – EF BF BF
-- {'Private use area', '[\238\128\128-\239\163\191]'}, -- U+E000–U+F8FF, EE 80 80 – EF A3 BF
-- {'Supplementary Private Use Area-A', '[\243\176\128\128-\243\191\191\189]'}, -- U+F0000–U+FFFFD, F3 B0 80 80 – F3 BF BF BD
-- {'Supplementary Private Use Area-B', '[\244\128\128\128-\244\143\191\189]'}, -- U+100000–U+10FFFD, F4 80 80 80 – F4 8F BF BD
}
--[[
Indic script makes use of zero width joiner as a character modifier so zwj
characters must be left in. This pattern covers all of the unicode characters
for these languages:
Devanagari 0900–097F – https://unicode.org/charts/PDF/U0900.pdf
Devanagari extended A8E0–A8FF – https://unicode.org/charts/PDF/UA8E0.pdf
Bengali 0980–09FF – https://unicode.org/charts/PDF/U0980.pdf
Gurmukhi 0A00–0A7F – https://unicode.org/charts/PDF/U0A00.pdf
Gujarati 0A80–0AFF – https://unicode.org/charts/PDF/U0A80.pdf
Oriya 0B00–0B7F – https://unicode.org/charts/PDF/U0B00.pdf
Tamil 0B80–0BFF – https://unicode.org/charts/PDF/U0B80.pdf
Telugu 0C00–0C7F – https://unicode.org/charts/PDF/U0C00.pdf
Kannada 0C80–0CFF – https://unicode.org/charts/PDF/U0C80.pdf
Malayalam 0D00–0D7F – https://unicode.org/charts/PDF/U0D00.pdf
plus the not-necessarily Indic scripts for Sinhala and Burmese:
Sinhala 0D80-0DFF - https://unicode.org/charts/PDF/U0D80.pdf
Myanmar 1000-109F - https://unicode.org/charts/PDF/U1000.pdf
Myanmar extended A AA60-AA7F - https://unicode.org/charts/PDF/UAA60.pdf
Myanmar extended B A9E0-A9FF - https://unicode.org/charts/PDF/UA9E0.pdf
the pattern is used by has_invisible_chars() and coins_cleanup()
]]
local indic_script = '[\224\164\128-\224\181\191\224\163\160-\224\183\191\225\128\128-\225\130\159\234\167\160-\234\167\191\234\169\160-\234\169\191]';
-- list of emoji that use a zwj character (U+200D) to combine with another emoji
-- from: https://www.unicode.org/Public/18.0.0/emoji/emoji-zwj-sequences.txt; version: 18.0; 2026-01-09
-- table created by: [[:en:Module:Make emoji zwj table]]
local emoji_t = { -- indexes are decimal forms of the hex values in U+xxxx
[8596] = true, -- U+2194 ↔ left right arrow
[8597] = true, -- U+2195 ↕ up down arrow
[9760] = true, -- U+2620 ☠ skull and crossbones
[9792] = true, -- U+2640 ♀ female sign
[9794] = true, -- U+2642 ♂ male sign
[9877] = true, -- U+2695 ⚕ staff of aesculapius
[9878] = true, -- U+2696 ⚖ scales
[9895] = true, -- U+26A7 ⚧ male with stroke and male and female sign
[9992] = true, -- U+2708 ✈ airplane
[10052] = true, -- U+2744 ❄ snowflake
[10084] = true, -- U+2764 ❤ heavy black heart
[10145] = true, -- U+27A1 ➡ black rightwards arrow
[11035] = true, -- U+2B1B ⬛ black large square
[127752] = true, -- U+1F308 🌈 rainbow
[127787] = true, -- U+1F32B 🌫 fog
[127806] = true, -- U+1F33E 🌾 ear of rice
[127859] = true, -- U+1F373 🍳 cooking
[127868] = true, -- U+1F37C 🍼 baby bottle
[127876] = true, -- U+1F384 🎄 christmas tree
[127891] = true, -- U+1F393 🎓 graduation cap
[127908] = true, -- U+1F3A4 🎤 microphone
[127912] = true, -- U+1F3A8 🎨 artist palette
[127979] = true, -- U+1F3EB 🏫 school
[127981] = true, -- U+1F3ED 🏭 factory
[128048] = true, -- U+1F430 🐰 rabbit face
[128102] = true, -- U+1F466 👦 boy
[128103] = true, -- U+1F467 👧 girl
[128104] = true, -- U+1F468 👨 man
[128105] = true, -- U+1F469 👩 woman
[128139] = true, -- U+1F48B 💋 kiss mark
[128165] = true, -- U+1F4A5 💥 collision symbol
[128168] = true, -- U+1F4A8 💨 dash symbol
[128171] = true, -- U+1F4AB 💫 dizzy symbol
[128187] = true, -- U+1F4BB 💻 personal computer
[128188] = true, -- U+1F4BC 💼 brief case
[128293] = true, -- U+1F525 🔥 fire
[128295] = true, -- U+1F527 🔧 wrench
[128300] = true, -- U+1F52C 🔬 microscope
[128488] = true, -- U+1F5E8 🗨 left speech bubble
[128640] = true, -- U+1F680 🚀 rocket
[128658] = true, -- U+1F692 🚒 fire engine
[129001] = true, -- U+1F7E9 🟩 large green square
[129003] = true, -- U+1F7EB 🟫 large brown square
[129309] = true, -- U+1F91D 🤝 handshake
[129455] = true, -- U+1F9AF 🦯 probing cane
[129456] = true, -- U+1F9B0 🦰 emoji component red hair
[129457] = true, -- U+1F9B1 🦱 emoji component curly hair
[129458] = true, -- U+1F9B2 🦲 emoji component bald
[129459] = true, -- U+1F9B3 🦳 emoji component white hair
[129466] = true, -- U+1F9BA 🦺 safety vest
[129468] = true, -- U+1F9BC 🦼 motorized wheelchair
[129469] = true, -- U+1F9BD 🦽 manual wheelchair
[129489] = true, -- U+1F9D1 🧑 adult
[129490] = true, -- U+1F9D2 🧒 child
[129648] = true, -- U+1FA70 🩰 ballet shoes
[129657] = true, -- U+1FA79 🩹 adhesive bandage
[129775] = true, -- U+1FAEF fight cloud
[129778] = true, -- U+1FAF2 🫲 leftwards hand
}
--[[----------------------< L A N G U A G E S U P P O R T >-------------------
These tables and constants support various language-specific functionality.
]]
local this_wiki_code = lang_obj:getCode(); -- get this wiki's language code
if string.match (mw.site.server, 'wikidata') then
this_wiki_code = mw.getCurrentFrame():callParserFunction('int', {'lang'}); -- on Wikidata so use interface language setting instead
end
local mw_languages_by_tag_t = mw.language.fetchLanguageNames (this_wiki_code, 'all'); -- get a table of language tag/name pairs known to Wikimedia; used for interwiki tests
local mw_languages_by_name_t = {};
for k, v in pairs (mw_languages_by_tag_t) do -- build a 'reversed' table name/tag language pairs know to MediaWiki; used for |language=
v = mw.ustring.lower (v); -- lowercase for tag fetch; get name's proper case from mw_languages_by_tag_t[<tag>]
if mw_languages_by_name_t[v] then -- when name already in the table
if 2 == #k or 3 == #k then -- if tag does not have subtags
mw_languages_by_name_t[v] = k; -- prefer the shortest tag for this name
end
else -- here when name not in the table
mw_languages_by_name_t[v] = k; -- so add name and matching tag
end
end
local inter_wiki_map = {}; -- map of interwiki prefixes that are language-code prefixes
for k, v in pairs (mw.site.interwikiMap ('local')) do -- spin through the base interwiki map (limited to local)
if mw_languages_by_tag_t[v["prefix"]] then -- if the prefix matches a known language tag
inter_wiki_map[v["prefix"]] = true; -- add it to our local map
end
end
--[[--------------------< S C R I P T _ L A N G _ C O D E S >-------------------
This table is used to hold ISO 639-1 two-character and ISO 639-3 three-character
language codes that apply only to |script-title= and |script-chapter=
]]
local script_lang_codes = {
'ab', 'am', 'ar', 'as', 'az', 'be', 'bg', 'bn', 'bo', 'bs', 'ce', 'chr',
'cu', 'dv', 'dz', 'el', 'fa', 'grc', 'gu', 'he', 'hi', 'hy', 'ja', 'ka',
'kaa', 'kk', 'km', 'kn', 'ko', 'ku', 'ky', 'lo', 'mk', 'ml', 'mn', 'mni',
'mr', 'my', 'ne', 'or', 'ota', 'pa', 'ps', 'ru', 'sd', 'si', 'sr', 'syc',
'ta', 'te', 'tg', 'th', 'ti', 'tkr', 'tt', 'ug', 'uk', 'ur', 'uz', 'yi',
'yue', 'zh', 'zgh'
};
--[[---------------< L A N G U A G E R E M A P P I N G >----------------------
These tables hold language information that is different (correct) from MediaWiki's definitions
For each ['<tag>'] = 'language name' in lang_tag_remap{} there must be a matching ['language name'] = {'language name', '<tag>'} in lang_name_remap{}
lang_tag_remap{}:
key is always lowercase ISO 639-1, -2, -3 language tag or a valid lowercase IETF language tag
value is properly spelled and capitalized language name associated with <tag>
only one language name per <tag>;
key/value pair must have matching entry in lang_name_remap{}
lang_name_remap{}:
key is always lowercase language name
value is a table the holds correctly spelled and capitalized language name [1] and associated tag [2] (tag must match a tag key in lang_tag_remap{})
may have multiple keys referring to a common preferred name and tag; For example:
['kolsch'] and ['kölsch'] both refer to 'Kölsch' and 'ksh'
]]
local lang_tag_remap = { -- used for |language= and |script-title= / |script-chapter=
['als'] = 'Tosk Albanian', -- MediaWiki returns Alemannisch
['bh'] = 'Bihari', -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bla'] = 'Blackfoot', -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['bn'] = 'Bengali', -- MediaWiki returns Bangla
['ca-valencia'] = 'Valencian', -- IETF variant of Catalan
['fkv'] = 'Kven', -- MediaWiki returns Kvensk
['gsw'] = 'Swiss German',
['ilo'] = 'Ilocano', -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['ksh'] = 'Kölsch', -- MediaWiki: Colognian; use IANA/ISO 639 preferred name
['ksh-x-colog'] = 'Colognian', -- override MediaWiki ksh; no IANA/ISO 639 code for Colognian; IETF private code created at Module:Lang/data
['mis-x-ripuar'] = 'Ripuarian', -- override MediaWiki ksh; no IANA/ISO 639 code for Ripuarian; IETF private code created at Module:Lang/data
['nan-tw'] = 'Taiwanese Hokkien', -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese and support en.wiki preferred name
['sr-ec'] = 'Serbian (Cyrillic script)', -- MediaWiki returns српски (ћирилица)
['sr-el'] = 'Serbian (Latin script)', -- MediaWiki returns srpski (latinica)
['tet'] = 'Tetun', -- MediaWiki returns Tetum
}
local lang_name_remap = { -- used for |language=; names require proper capitalization; tags must be lowercase
['alemannic'] = {'Swiss German', 'gsw'}, -- ISO 639-2, -3 alternate for Swiss German; MediaWiki mediawiki returns Alemannic for gsw; en.wiki preferred name
['alemannisch'] = {'Swiss German', 'gsw'}, -- not an ISO or IANA language name; MediaWiki uses 'als' as a subdomain name for Alemannic Wikipedia: als.wikipedia.org
['bangla'] = {'Bengali', 'bn'}, -- MediaWiki returns Bangla (the endonym) but we want Bengali (the exonym); here we remap
['bengali'] = {'Bengali', 'bn'}, -- MediaWiki doesn't use exonym so here we provide correct language name and 639-1 code
['bhojpuri'] = {'Bhojpuri', 'bho'}, -- MediaWiki uses 'bh' as a subdomain name for Bhojpuri Wikipedia: bh.wikipedia.org
['bihari'] = {'Bihari', 'bh'}, -- MediaWiki replaces 'Bihari' with 'Bhojpuri' so 'Bihari' cannot be found
['blackfoot'] = {'Blackfoot', 'bla'}, -- MediaWiki/IANA/ISO 639: Siksika; use en.wiki preferred name
['colognian'] = {'Colognian', 'ksh-x-colog'}, -- MediaWiki preferred name for ksh
['ilocano'] = {'Ilocano', 'ilo'}, -- MediaWiki/IANA/ISO 639: Iloko; use en.wiki preferred name
['kolsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name (use non-diacritical o instead of umlaut ö)
['kölsch'] = {'Kölsch', 'ksh'}, -- use IANA/ISO 639 preferred name
['kven'] = {'Kven', 'fkv'}, -- Unicode CLDR have decided not to support English language name for these two...
['kvensk'] = {'Kven', 'fkv'}, -- ...they say to refer to IANA registry for English names
['ripuarian'] = {'Ripuarian', 'mis-x-ripuar'}, -- group of dialects; no code in MediaWiki or in IANA/ISO 639
['serbian (cyrillic script)'] = {'Serbian (Cyrillic script)', 'sr-cyrl'}, -- special case to get correct tag when |language=sr-ec
['serbian (latin script)'] = {'Serbian (Latin script)', 'sr-latn'}, -- special case to get correct tag when |language=sr-el
['swiss german'] = {'Swiss German', 'gsw'},
['taiwanese hokkien'] = {'Taiwanese Hokkien', 'nan-tw'}, -- make room for MediaWiki/IANA/ISO 639 nan: Min Nan Chinese
['tetum'] = {'Tetun', 'tet'},
['tetun'] = {'Tetun', 'tet'},
['tosk albanian'] = {'Tosk Albanian', 'als'}, -- MediaWiki replaces 'Tosk Albanian' with 'Alemannisch' so 'Tosk Albanian' cannot be found
['valencian'] = {'Valencian', 'ca-valencia'}, -- variant of Catalan; categorizes as Valencian
}
--[[---------------< P R O P E R T I E S _ C A T E G O R I E S >----------------
Properties categories. These are used for investigating qualities of citations.
]]
local prop_cats = {
['foreign-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is foreign-language name, $2 is ISO639-1 code
['foreign-lang-source-2'] = 'CS1 foreign language sources (ISO 639-2)|$1', -- |language= category; a cat for ISO639-2 languages; $1 is the ISO 639-2 code used as a sort key
['interproj-linked-name'] = 'CS1 interproject-linked names|$1', -- any author, editor, etc that has an interproject link; $1 is interproject tag used as a sort key
['interwiki-linked-name'] = 'CS1 interwiki-linked names|$1', -- any author, editor, etc that has an interwiki link; $1 is interwiki tag used as a sort key; yeilds to interproject
['local-lang-source'] = 'CS1 $1-language sources ($2)', -- |language= categories; $1 is local-language name, $2 is ISO639-1 code; not emitted when local_lang_cat_enable is false
['location-test'] = 'CS1 location test',
['long-vol'] = 'CS1: long volume value', -- probably temporary cat to identify scope of |volume= values longer than 4 characters
['script'] = 'CS1 uses $1-language script ($2)', -- |script-title=xx: has matching category; $1 is language name, $2 is language tag
['tracked-param'] = 'CS1 tracked parameter: $1', -- $1 is base (enumerators removed) parameter name
['unfit'] = 'CS1: unfit URL', -- |url-status=unfit or |url-status=usurped; used to be a maint cat
['vanc-accept'] = 'CS1:Vancouver names with accept markup', -- for |vauthors=/|veditors= with accept-as-written markup
['year-range-abbreviated'] = 'CS1: abbreviated year range', -- probably temporary cat to identify scope of |date=, |year= values using YYYY–YY form
}
--[[-------------------< T I T L E _ T Y P E S >--------------------------------
Here we map a template's CitationClass to TitleType (default values for |type= parameter)
]]
local title_types = {
['AV-media-notes'] = 'Media notes',
['document'] = 'Document',
['interview'] = 'Interview',
['mailinglist'] = 'Mailing list',
['map'] = 'Map',
['podcast'] = 'Podcast',
['pressrelease'] = 'Press release',
['report'] = 'Report',
['speech'] = 'Speech',
['techreport'] = 'Technical report',
['thesis'] = 'Thesis',
}
--[[--------------------------< B U I L D _ K N O W N _ F R E E _ D O I _ R E G I S T R A N T S _ T A B L E >--
build a table of doi registrants known to be free-to-read In a doi, the registrant ID is the series of digits
between the '10.' and the first '/': in doi 10.1100/sommat, 1100 is the registrant ID
see §3.2.2 DOI prefix of the Doi Handbook p. 43
https://www.doi.org/doi-handbook/DOI_Handbook_Final.pdf#page=43
]]
local function build_free_doi_registrants_table()
local registrants_t = {};
for _, v in ipairs ({
'1045', '1074', '1096', '1100', '1155', '1186', '1194', '1371', '1613', '1629', '1989', '1999', '2147', '2196', '3114', '3285', --for 10.1155/... ISRN prior to 2007 should not be flagged--
'3389', '3390', '3767', '3906', '3748', '3814', '3847', '3897', '4061', '4089', '4102', '4103', '4172', '4175', '4230', '4236', '4239',
'4240', '4249', '4251', '4252', '4253', '4254', '4291', '4292', '4312', '4329', '4330', '4331', '5070', '5074', '5086', '5194', '5210',
'5306', '5312', '5313', '5314', '5315', '5316', '5317', '5318', '5319', '5320', '5321', '5334', '5402', '5409', '5410', '5411',
'5412', '5492', '5493', '5494', '5495', '5496', '5497', '5498', '5499', '5500', '5501', '5527', '5528', '5662', '6064', '6219',
'7167', '7217', '7287', '7482', '7490', '7554', '7717', '7759', '7766', '9778',
'11131', '11569', '11647', '11648', '12688', '12703', '12715', '12942', '12998', '13105', '14256', '14293', '14303', '14502', '14720',
'15215', '15227', '15292', '15458', '15347', '15412', '15560', '16995', '17573', '17645', '18553', '18637', '18757', '19080', '19173',
'20419', '20944', '21037', '21105', '21468', '21767', '21425', '22261', '22323', '22459', '24105', '24196', '24404', '24413', '24966',
'26529', '26614', '26775', '26873', '30845', '32545', '34291', '34641', '35711', '35712', '35713', '35995', '36648', '37126', '37532',
'37871', '47128', '47622', '47959', '48438', '51741', '51746', '51935', '51936', '51937', '51938', '51939', '51940', '52165', '52437',
'52975', '53288', '53347', '54081', '54947', '55295', '55667', '55741', '55914', '56042', '57009', '58647', '58782', '59081', '59490',
'61375', '66183', '70587',
}) do
registrants_t[v] = true; -- build a k/v table of known free-to-read doi registrants
end
return registrants_t;
end
-- known free registrants identifiable by the doi suffix incipit
local extended_registrants_t = { -- doi suffix incipits are evaluated as lua patterns
['1001'] = {'jamanetworkopen', 'jamahealthforum'}, -- JAMA Network Open, JAMA Health Forum
['1002'] = {'1878-0261', '2056-4538', '2211-5463', '2475-8876', '2688-8319', 'aaai%.', 'aac2%.', 'ache%.', 'acm2%.', 'acn3%.', 'acr2%.', 'admi%.', 'adpr%.', 'adrr%.', 'adsr%.', 'advs%.', 'ael2%.', 'aelm%.', 'aesr%.', 'aff2%.', 'agf2%.', 'agg2%.', 'agm2%.', 'ags3%.', 'agt2%.', 'aidi%.', 'ail2%.', 'aisy%.', 'aiv2%.', 'alz%.', 'ame2%.', 'ams2%.', 'anbr%.', 'ansa%.', 'apj%.', 'app5%.', 'aps3%.', 'apxr%.', 'aro2%.', 'ars2%.', 'asl2%.', 'atn2%.', 'bco2%.', 'bes2%.', 'bmm2%.', 'bod2%.', 'brb3%.', 'brh2%.', 'brx2%.', 'bsa3%.', 'bte2%.', 'btm2%.', 'cai2%.', 'cam4%.', 'cbh2%.', 'ccr3%.', 'ccs3%.', 'cdt3%.', 'celc%.', 'cep4%.', 'ces2%.', 'cesm%.', 'ceur%.', 'cey2%.', 'cfch%.', 'cfp2%.', 'cin4%.', 'clc%.', 'clem%.', 'cli2%.', 'clt2%.', 'cmt2%.', 'cmtd%.', 'cnl2%.', 'cnr2%.', 'cns%.', 'cns3%.', 'cnx2%.', 'cre2%.', 'csc3%.', 'cso2%.', 'ctd2%.', 'cti2%.', 'ctm2%.', 'dad2%.', 'deo2%.', 'dep2%.', 'dni2%.', 'dro2%.', 'dug2%.', 'dvr2%.', 'eas2%.', 'ece2%.', 'ece3%.', 'ecog%.', 'ecs2%.', 'edm2%.', 'edn3%.', 'eem2%.', 'eer3%.', 'efd2%.', 'ejsc%.', 'elsa%.', 'elt2%.', 'eng2%.', 'eom2%.', 'epi4%.', 'epr2%.', 'ese3%.', 'exp%.', 'fbe2%.', 'fci2%.', 'fer3%.', 'fes3%.', 'fft2%.', 'fhu2%.', 'fle2%.', 'flm2%.', 'fob2%.', 'fpf2%.', 'fsh3%.', 'fsn3%.', 'gcb4%.', 'gch2%.', 'gdj3%.', 'geo2%.', 'ggn2%.', 'gin2%.', 'glr2%.', 'gps3%.', 'gtm2%.', 'hbm%.', 'hcs2%.', 'hem3%.', 'hkj2%.', 'hsr2%.', 'ibra%.', 'idm2%.', 'ifm2%.', 'iid3%.', 'iju5%.', 'ila2%.', 'imed%.', 'imm3%.', 'imo2%.', 'imt2%.', 'inc2%.', 'inc3%.', 'inf2%.', 'inm3%.', 'inmd%.', 'ird3%.', 'ise3%.', 'jaa2%.', 'jav%.', 'jbt%.', 'jcc5%.', 'jcla%.', 'jcsm%.', 'jcv2%.', 'jeo2%.', 'jev2%.', 'jex2%.', 'jfa2%.', 'jgf2%.', 'jgh3%.', 'jha2%.', 'jia2%.', 'jmd2%.', 'jmrs%.', 'joa3%.', 'jpr3%.', 'jsf2%.', 'jsp2%.', 'jvc2%.', 'kjm2%.', 'kot2%.', 'lci2%.', 'ldr%.', 'leap%.', 'leg3%.', 'lim2%.', 'lio2%.', 'loe2%.', 'lol2%.', 'lrh2%.', 'mame%.', 'mba2%.', 'mbo3%.', 'mco2%.', 'mdb2%.', 'mdr2%.', 'med4%.', 'mef2%.', 'met%.', 'metm%.', 'mgea%.', 'mgg3%.', 'mhs2%.', 'mlf2%.', 'mmr3%.', 'moda%.', 'mog2%.', 'mpr%.', 'mps2%.', 'msd2%.', 'nam2%.', 'nano%.', 'nap2%.', 'neo2%.', 'nep3%.', 'njb%.', 'nop2%.', 'npp2%.', 'npr2%.', 'ntls%.', 'open%.', 'orm2%.', 'osp4%.', 'oto2%.', 'pan3%.', 'pchj%.', 'pcn5%.', 'pdi3%.', 'ped4%.', 'pei3%.', 'pfm2%.', 'pgr2%.', 'phmt%.', 'pld3%.', 'pls2%.', 'pmf2%.', 'pne2%.', 'pnp%.', 'poh2%.', 'ppj2%.', 'ppp3%.', 'prm2%.', 'pro6%.', 'prp2%.', 'psp4%.', 'puh2%.', 'pul2%.', 'qub2%.', 'rai2%.', 'rar2%.', 'rco2%.', 'rcr2%.', 'rfc2%.', 'rmb2%.', 'rpm2%.', 'rse2%.', 'rvr2%.', 'sae2%.', 'sen2%.', 'sfp2%.', 'smb2%.', 'smm2%.', 'smmd%.', 'smo2%.', 'smsc%.', 'sst2%.', 'sst3%.', 'sstr%.', 'sus2%.', 'tch2%.', 'tcr4%.', 'tpg2%.', 'trc2%.', 'tre%.', 'uar2%.', 'ueg2%.', 'uro2%.', 'viw2%.', 'vms3%.', 'vro2%.', 'vzj2%.', 'we%.', 'wjo2%.', 'wlb3%.', 'wll2%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1007'] = {'s12543', 's40565'}, -- Fuzzy Information and Engineering, Journal of Modern Power Systems and Clean Energy
['1016'] = {'j%.aace', 'j%.aed', 'j%.aiopen', 'j%.animal', 'j%.apsb', -- AACE Endocrinology and Diabetes, AACE Endocrinology and Diabetes, AI Open, Animal, Acta Pharmaceutica Sinica B
'j%.addicn', 'j%.abrep', 'j%.eurpsy', 'j%.fob', 'j%.gpb', 'j%.heliyon', -- Addiction Neuroscience, Addictive Behaviors Reports, European Psychiatry, FEBS Open Bio, Genomics, Proteomics & Bioinformatics after 2015, Heliyon
'j%.mucimm%.', 'j%.nlp', 'j%.patter', 'j%.proche', 'j%.vgie', -- Mucosal Immunology, Natural Language Processing, Patterns, Procedia Chemistry, VideoGIE
's1004-4132', 's1007-0214', 's1672-0229', 's1933-0219'}, -- Journal of Systems Engineering and Electronics, Tsinghua Science and Technology, Genomics, Proteomics & Bioinformatics before 2015, Mucosal Immunology
['1017'] = {'apj%.', 'nlp', 'mdh', 'S09249338', 'S15574660'}, -- Natural Language Processing Journal, Medical History, European Psychiatry, Asia Pacific Journal
['1021'] = {'acscentsci%.', 'acs%.chas%.', 'acsomega%.', 'jacsau%.',
'acsbiomedchemau%.', 'acsengineeringau%.', 'acsenvironau%.',
'acsmaterialsau%.', 'acsmeasuresciau%.', 'acsnanoscienceau%.',
'acsorginorgau%.', 'acsphyschemau%.', 'acspolymersau%.',
'aps%.', 'cbe%.', 'cbmi%.', 'envhealth%.', 'ehp%.', 'photonsci%.',
'polymscitech%.', 'prechem%.'}, -- ACS journals
['1029'] = {'2025cn', '2025csj', '2025ea', '2025gc', '2025gh', '2025ms', '2025sw', '2025wr', '2026ef', '2026gl', '2026jh', 'aga2.70129'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1038'] = {'41541%.', '43246%.', 'asiamat%.', 'boneres%.', 'cddis%.', 'cddiscovery%.', 'celldisc%.', 'mi%.', 'ncomms', 'nutd%.', 'oncsis%.', 'srep', 's40494', 's41377', 's41392', 's41396', 's41398', 's41405', 's41407', 's41408', 's41439', 's41467', 's41514', 's41522', 's41523', 's41524', 's41525', 's41526', 's41528', 's41529', 's41531', 's41533', 's41534', 's41535', 's41536', 's41537', 's41538', 's41539', 's41540', 's41545', 's41598', 's41612', 's41698', 's41699', 's41746', 's42003', 's42004', 's42005', 's42949', 's43247', 's43705', 's43856', 's44168', 's44172', 's44182', 's44183', 's44184', 's44185', 's44259', 's44260', 's44264', 's44271', 's44276', 's44294', 's44296', 's44298', 's44303', 's44304', 's44306', 's44310', 's44323', 's44324', 's44325', 's44328', 's44333', 's44334', 's44335', 's44341', 's44355', 's44383', 's44384', 's44385', 's44386', 's44387', 's44400', 's44401', 's44406', 's44407', 's44431', 's44432', 's44433', 's44434', 's44435', 's44440', 's44453', 's44454', 's44455', 's44456', 's44458', 's44459', 's44482', 's44484', 's44485', 's44488', 's44513', 's44528', 'sdata%.'}, -- Nature journals (npj series, Communications series, and many others, see https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&diff=prev&oldid=1368822567 and https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&diff=next&oldid=1368822567)
['1046'] = {'j%.1365-8711', 'j%.1365-246x'}, -- MNRAS, GJI
['1049'] = {'aie2%.', 'blc2%.', 'bme2', 'bsb2%.', 'ccs2%.', 'cds2', 'cdt2', 'cim2%.', 'cit2%.', 'cje%.', 'cmu2%.', 'cps2%.', 'csy2%.', 'cth2%.', 'cvi2%.', 'dgt2%.', 'ein2%.', 'ell2%.', 'elp2%.', 'els2', 'ema3%.', 'enb2%.', 'enc2%.', 'esi2%.', 'gtd2%.', 'htl2%.', 'hve2%.', 'ipr2%.', 'ise2', 'itr2%.', 'mia2%.', 'mna2%.', 'nbt2', 'nde2%.', 'ntw2%.', 'ote2%.', 'pel2%.', 'qtc2%.', 'rpg2%.', 'rsn2%.', 'ses2%.', 'sfw2', 'sil2', 'smc2%.', 'smt2%.', 'stg2%.', 'syb2%.', 'tje2%.', 'wss2%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1051'] = {'0004-6361','parasite'}, -- Astronomy & Astrophysics, Parasite
['1057'] = {'s41599'}, -- Humanities and Social Sciences Communications
['1080'] = {'14399776'}, -- International Journal of Fluid Power
['1090'] = {'cams', 'ecgd', 's1088-4173', 'ert', 's1088-4165', 's2330-1511',-- Free AMS journals
'bproc', 's2330-0000', 'btran', 'noti'},
['1093'] = {'asjof', 'bjro', 'bjsopen', 'ehjopen', 'hropen ', 'jamiaopen', 'ofid', 'oxfclm', -- Aesthetic Surgery Journal Open Forum, BJR Open, BJS Open, European Heart Journal Open, Human Reproduction Open, JAMIA Open, Open Forum Infectious Diseases, Oxford Open Climate Change
'oodh', 'ooec', 'ooenergy', 'oxfimm', 'ooih', 'oxfmat', 'oons', --Oxford Open Digital Health, Oxford Open Economics, Oxford Open Energy, Oxford Open Immunology, Oxford Open Infrastructure and Health, Oxford Open Materials Science, Oxford Open Neuroscience
'qopen', 'schizbullopen', 'mnras', 'mnrasl', 'gji', 'pnasnexus',-- Q Open, Schizophrenia Bulletin Open, MNRAS, MNRAS Letters, GJI, PNAS Nexus
'rasti', 'ismeco', 'ismejo'}, -- RASTI, ISME Communications, ISME Journal
['1096'] = {'fba%.'}, -- FASEB BioAdvances
['1098'] = {'rsbm', 'rsob', 'rsos'}, -- Biographical Memoirs of Fellows of the Royal Society, Open Biology, Royal Society Open Science
['1099'] = {'acmi', 'mic', '00221287', 'mgen'}, -- Access Microbiology, Microbiology, Journal of General Microbiology, Microbial Genomics
['1107'] = {'S20569890', 'S20522525', 'S16005775', 'S24143146'}, -- Acta Crystallographica E, IUCrJ, Journal of Synchrotron Radiation, IUCrData
['1109'] = {'access%.', 'ieeedata%.', 'jeds%.', 'jispin%.', 'jmw%.', 'jphot%.', 'jsas%.', 'jstars%.', 'jsteap%.', 'jtehm%.', 'jxcdc%.', 'lls%.', 'lsmc%.', 'oajpe%.', 'ojap%.', 'ojcas%.', 'ojcoms%.', 'ojcs%.', 'ojcsys%.', 'ojemb%.', 'ojia%.', 'ojid%.', 'ojies%.', 'ojim%.', 'ojits%.', 'ojnano%.', 'ojpel%.', 'ojse%.', 'ojsp%.', 'ojsscs%.', 'ojuffc%.', 'ojvt%.', 'sr%.', 'tfr%.', 'tmlcn%.', 'tp%.', 'tqe%.', 'oa', 'oj'}, -- IEEE journals see [[User talk:DreamRimmer#Wikipedia:Bot requests/Archive 88#Web scrapping v4]]
['1111'] = {'1365-2435', '1442-1984', '1751-7915', '1753-0407', '1755-0998', '1758-2229', '1759-7714', '2041-210x', 'j%.1365-2966', 'j%.1745-3933', 'j%.1365-246X','acel%.', 'adb%.', 'anec%.', 'aogs%.', 'bor%.', 'bpa%.', 'cas%.', 'con4%.', 'cpr%.', 'crj%.', 'csp2%.', 'cts%.', 'ddi%.', 'ejed%.', 'ene%.', 'eva%.', 'gbb%.', 'gcbb%.', 'hex%.', 'irv%.', 'iwj%.', 'jch%.', 'jcmm%.', 'jdi%.', 'jfr3%.', 'jocd%.', 'jwas%.', 'mcn%.', 'mpp%.', 'myc%.', 'nrm%.', 'os%.', 'pbi%.', 'srt%.'}, -- Elsevier journals https://en.wikipedia.org/w/index.php?title=User_talk:DreamRimmer&oldid=1364310578#Wikipedia:Bot_requests/Archive_88#Web_scrapping_v2
['1112'] = {'tlm3%.'}, -- Transactions of the London Mathematical Society
['1113'] = {'ep'}, -- Experimental Physiology
['1128'] = {'asmcr', 'jmbe', 'mbio', 'mra', 'spectrum', 'msphere', 'msystems'}, --ASM Case Reports, Journal of Microbiology & Biology Education, mBio, Microbiology Resource Announcements, Microbiology Spectrum, mSphere, mSystems
['1130'] = {'GES'}, -- Geosphere
['1136'] = {'bmjopen'}, -- BMJ Open
['1140'] = {'epjconf', 'epjds'}, -- EPJ Web of Conferences, EPJ Data Science
['1161'] = {'jaha%.'},
['1162'] = {'qss'}, -- Quantitative Science Studies
['1176'] = {'appi%.prcp%.'},
['1177'] = {'21582440', '23328584'}, -- SAGE Open, AERA Open
['1192'] = {'bjo', 'j%.eurpsy'}, -- BJPsych Open, European Psychiatry
['1210'] = {'jendso','jcemcr'}, -- Journal of the Endocrine Society, JCEM Case Reports
['1215'] = {'21573689', '21573698'}, -- L&O Fluids
['1242'] = {'bio', 'dmm'}, -- Biology Open, Disease Models & Mechanisms
['1257'] = {'jep'}, -- Journal of Economic Perspectives
['1587'] = {'comex%.', 'transcom%.'}, -- IEICE Communications Express, IEICE Transactions on Communications
['1590'] = {'0102-3306', 's0074-0276'}, -- Acta Botanica Brasilica, Memórias do Instituto Oswaldo Cruz
['1631'] = {'eng%.'}, -- ENGINEERING Information Technology & Electronic Engineering
['2106'] = {'JBJS.OA'}, -- JBJS Open Access
['2903'] = {'j%.efsa%.'},
['3322'] = {'caac%.'},
['3982'] = {'qw', 'te'},
['4171'] = {'dm','mag'}, -- Documenta Mathematica, EMS Magazine
['4319'] = {'lo%.', 'lol%.', 'lom%.'}, -- L&O, L&O e-Lectures, L&O Methods
['5852'] = {'ejt'}, -- European Journal of Taxonomy
['7155'] = {'jgaa'}, -- Journal of Graph Algorithms and Applications
['7758'] = {'rsf'}, -- RSJ Journal
['11158'] = {'saasp'}, -- Systematic and Applied Acarology Special Publications
['11646'] = {'megataxa', 'mesozoic'}, -- Megataxa, Mesozoic
['13052'] = {'jcsm2245-1439%.', 'jmm1550-4646%.'}, -- Journal of Cyber Security and Mobility, Journal of Mobile Multimedia
['14231'] = {'ag'}, -- Algebraic Geometry
['14814'] = {'phy2%.'},
['15302'] = {'vr%.'},
['15446'] = {'abc'}, -- Acta Biológica Colombiana
['17239'] = {'jowr'}, -- Journal of Writing Research
['17775'] = {'cseejpes%.'}, -- CSEE Journal of Power and Energy Systems
['22073'] = {'pja'}, -- Persian Journal of Acarology
['23919'] = {'aise%.', 'chain%.', 'cjee%.', 'csms%.', 'etr%.', -- See [[User talk:DreamRimmer#Wikipedia:Bot requests/Archive 88#Web scrapping v4]]
'hyper%.', 'ics%.', 'ienergy%.', 'jsc%.',
'metaresource%.', 'saiee%.', 'tup-icn%.', 'ursirsb%.'},
['24295'] = {'cpsstpea%.'}, -- CPSS Transactions on Power Electronics and Applications
['24310'] = {'abm'}, -- Acta Botanica Malacitana
['24425'] = {'agp'}, -- Acta Geologica Polonica
['26599'] = {'bdma%.', 'cai%.', 'ijcs%.', 'jicv%.'}, -- Big Data Mining and Analytics, Cybernetics and Intelligence, International Journal of Crowd Science, Journal of Intelligent and Connected Vehicles
['30941'] = {'cestems%.'}, -- CES Transactions on Electrical Machines and Systems
['35249'] = {'rche'}, -- Revista Chilena de Entomología
['37520'] = {'fi'}, -- Fossil Imprint
['53562'] = {'ajcb'} -- Asian Journal of Conservation Biology
}
--[[===================<< E R R O R M E S S A G I N G >>======================
]]
--[[----------< E R R O R M E S S A G E S U P P L E M E N T S >-------------
I18N for those messages that are supplemented with additional specific text that
describes the reason for the error
TODO: merge this with special_case_translations{}?
]]
local err_msg_supl = {
['char'] = 'invalid character', -- |isbn=, |sbn=
['check'] = 'checksum', -- |isbn=, |sbn=
empty_str = '(empty string)', -- empty unknown parameter check when cite has |=
['flag'] = 'flag', -- |archive-url=
['form'] = 'invalid form', -- |isbn=, |sbn=
['group'] = 'invalid group id', -- |isbn=
['initials'] = 'initials', -- Vancouver
['invalid language code'] = 'invalid language code', -- |script-<param>=
['journal'] = 'journal', -- |bibcode=
['length'] = 'length', -- |isbn=, |bibcode=, |sbn=
['liveweb'] = 'liveweb', -- |archive-url=
['missing comma'] = 'missing comma', -- Vancouver
['missing prefix'] = 'missing prefix', -- |script-<param>=
['missing title part'] = 'missing title part', -- |script-<param>=
['name'] = 'name', -- Vancouver
['non-Latin char'] = 'non-Latin character', -- Vancouver
['path'] = 'path', -- |archive-url=
['prefix'] = 'invalid prefix', -- |isbn=
['punctuation'] = 'punctuation', -- Vancouver
['save'] = 'save command', -- |archive-url=
['suffix'] = 'suffix', -- Vancouver
['timestamp'] = 'timestamp', -- |archive-url=
['unknown language code'] = 'unknown language code', -- |script-<param>=
['value'] = 'value', -- |bibcode=
['year'] = 'year', -- |bibcode=
}
--[[--------------< E R R O R _ C O N D I T I O N S >---------------------------
Error condition table. This table has two sections: errors at the top, maintenance
at the bottom. Maint 'messaging' does not have a 'message' (message=nil)
The following contains a list of IDs for various error conditions defined in the
code. For each ID, we specify a text message to display, an error category to
include, and whether the error message should be wrapped as a hidden comment.
Anchor changes require identical changes to matching anchor in Help:CS1 errors
TODO: rename error_conditions{} to something more generic; create separate error
and maint tables inside that?
]]
local error_conditions = {
err_accessdate_missing_url = {
message = '<code class="cs1-code">|access-date=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'accessdate_missing_url',
category = 'CS1 errors: access-date without URL',
hidden = false
},
err_apostrophe_markup = {
message = 'Italic or bold markup not allowed in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'apostrophe_markup',
category = 'CS1 errors: markup',
hidden = false
},
err_archive_date_missing_url = {
message = '<code class="cs1-code">|archive-date=</code> requires <code class="cs1-code">|archive-url=</code>',
anchor = 'archive_date_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_date_url_ts_mismatch = {
message = '<code class="cs1-code">|archive-date=</code> / <code class="cs1-code">|archive-url=</code> timestamp mismatch; $1 suggested',
anchor = 'archive_date_url_ts_mismatch',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_date = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|archive-date=</code>',
anchor = 'archive_missing_date',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_missing_url = {
message = '<code class="cs1-code">|archive-url=</code> requires <code class="cs1-code">|url=</code>',
anchor = 'archive_missing_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_archive_url = {
message = '<code class="cs1-code">|archive-url=</code> is malformed: $1', -- $1 is error message detail
anchor = 'archive_url',
category = 'CS1 errors: archive-url',
hidden = false
},
err_arxiv_missing = {
message = '<code class="cs1-code">|arxiv=</code> required',
anchor = 'arxiv_missing',
category = 'CS1 errors: arXiv', -- same as bad arxiv
hidden = false
},
err_asintld_missing_asin = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|asin=</code>', -- $1 is parameter name
anchor = 'asintld_missing_asin',
category = 'CS1 errors: ASIN TLD',
hidden = false
},
err_bad_arxiv = {
message = 'Check <code class="cs1-code">|arxiv=</code> value',
anchor = 'bad_arxiv',
category = 'CS1 errors: arXiv',
hidden = false
},
err_bad_asin = {
message = 'Check <code class="cs1-code">|asin=</code> value',
anchor = 'bad_asin',
category ='CS1 errors: ASIN',
hidden = false
},
err_bad_asin_tld = {
message = 'Check <code class="cs1-code">|asin-tld=</code> value',
anchor = 'bad_asin_tld',
category ='CS1 errors: ASIN TLD',
hidden = false
},
err_bad_bibcode = {
message = 'Check <code class="cs1-code">|bibcode=</code> $1', -- $1 is error message detail
anchor = 'bad_bibcode',
category = 'CS1 errors: bibcode',
hidden = false
},
err_bad_biorxiv = {
message = 'Check <code class="cs1-code">|biorxiv=</code> value',
anchor = 'bad_biorxiv',
category = 'CS1 errors: bioRxiv',
hidden = false
},
err_bad_citeseerx = {
message = 'Check <code class="cs1-code">|citeseerx=</code> value',
anchor = 'bad_citeseerx',
category = 'CS1 errors: citeseerx',
hidden = false
},
err_bad_date = {
message = 'Check date values in: $1', -- $1 is a parameter name list
anchor = 'bad_date',
category = 'CS1 errors: dates',
hidden = false
},
err_bad_doi = {
message = 'Check <code class="cs1-code">|doi=</code> value',
anchor = 'bad_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_bad_hdl = {
message = 'Check <code class="cs1-code">|hdl=</code> value',
anchor = 'bad_hdl',
category = 'CS1 errors: HDL',
hidden = false
},
err_bad_isbn = {
message = 'Check <code class="cs1-code">|isbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_isbn',
category = 'CS1 errors: ISBN',
hidden = false
},
err_bad_ismn = {
message = 'Check <code class="cs1-code">|ismn=</code> value',
anchor = 'bad_ismn',
category = 'CS1 errors: ISMN',
hidden = false
},
err_bad_issn = {
message = 'Check <code class="cs1-code">|$1issn=</code> value', -- $1 is 'e' or '' for eissn or issn
anchor = 'bad_issn',
category = 'CS1 errors: ISSN',
hidden = false
},
err_bad_jfm = {
message = 'Check <code class="cs1-code">|jfm=</code> value',
anchor = 'bad_jfm',
category = 'CS1 errors: JFM',
hidden = false
},
err_bad_jstor = {
message = 'Check <code class="cs1-code">|jstor=</code> value',
anchor = 'bad_jstor',
category = 'CS1 errors: JSTOR',
hidden = false
},
err_bad_lccn = {
message = 'Check <code class="cs1-code">|lccn=</code> value',
anchor = 'bad_lccn',
category = 'CS1 errors: LCCN',
hidden = false
},
err_bad_medrxiv = {
message = 'Check <code class="cs1-code">|medrxiv=</code> value',
anchor = 'bad_medrxiv',
category = 'CS1 errors: medRxiv',
hidden = false
},
err_bad_mr = {
message = 'Check <code class="cs1-code">|mr=</code> value',
anchor = 'bad_mr',
category = 'CS1 errors: MR',
hidden = false
},
err_bad_oclc = {
message = 'Check <code class="cs1-code">|oclc=</code> value',
anchor = 'bad_oclc',
category = 'CS1 errors: OCLC',
hidden = false
},
err_bad_ol = {
message = 'Check <code class="cs1-code">|ol=</code> value',
anchor = 'bad_ol',
category = 'CS1 errors: OL',
hidden = false
},
err_bad_osti = {
message = 'Check <code class="cs1-code">|osti=</code> value',
anchor = 'bad_osti',
category = 'CS1 errors: OSTI',
hidden = false
},
err_bad_paramlink = { -- for |title-link=, |author/editor/translator-link=, |series-link=, |episode-link=
message = 'Check <code class="cs1-code">|$1=</code> value', -- $1 is parameter name
anchor = 'bad_paramlink',
category = 'CS1 errors: parameter link',
hidden = false
},
err_bad_pmc = {
message = 'Check <code class="cs1-code">|pmc=</code> value',
anchor = 'bad_pmc',
category = 'CS1 errors: PMC',
hidden = false
},
err_bad_pmid = {
message = 'Check <code class="cs1-code">|pmid=</code> value',
anchor = 'bad_pmid',
category = 'CS1 errors: PMID',
hidden = false
},
err_bad_rfc = {
message = 'Check <code class="cs1-code">|rfc=</code> value',
anchor = 'bad_rfc',
category = 'CS1 errors: RFC',
hidden = false
},
err_bad_s2cid = {
message = 'Check <code class="cs1-code">|s2cid=</code> value',
anchor = 'bad_s2cid',
category = 'CS1 errors: S2CID',
hidden = false
},
err_bad_sbn = {
message = 'Check <code class="cs1-code">|sbn=</code> value: $1', -- $1 is error message detail
anchor = 'bad_sbn',
category = 'CS1 errors: SBN',
hidden = false
},
err_bad_ssrn = {
message = 'Check <code class="cs1-code">|ssrn=</code> value',
anchor = 'bad_ssrn',
category = 'CS1 errors: SSRN',
hidden = false
},
err_bad_url = {
message = 'Check $1 value', -- $1 is parameter name
anchor = 'bad_url',
category = 'CS1 errors: URL',
hidden = false
},
err_bad_usenet_id = {
message = 'Check <code class="cs1-code">|message-id=</code> value',
anchor = 'bad_message_id',
category = 'CS1 errors: message-id',
hidden = false
},
err_bad_zbl = {
message = 'Check <code class="cs1-code">|zbl=</code> value',
anchor = 'bad_zbl',
category = 'CS1 errors: Zbl',
hidden = false
},
err_bare_url_missing_title = {
message = '$1 missing title', -- $1 is parameter name
anchor = 'bare_url_missing_title',
category = 'CS1 errors: bare URL',
hidden = false
},
err_biorxiv_missing = {
message = '<code class="cs1-code">|biorxiv=</code> required',
anchor = 'biorxiv_missing',
category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv
hidden = false
},
err_chapter_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'chapter_ignored',
category = 'CS1 errors: chapter ignored',
hidden = false
},
err_citation_missing_title = {
message = 'Missing or empty <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'citation_missing_title',
category = 'CS1 errors: missing title',
hidden = false
},
err_citeseerx_missing = {
message = '<code class="cs1-code">|citeseerx=</code> required',
anchor = 'citeseerx_missing',
category = 'CS1 errors: citeseerx', -- same as bad citeseerx
hidden = false
},
err_cite_web_url = { -- this error applies to cite web and to cite podcast
message = 'Missing or empty <code class="cs1-code">|url=</code>',
anchor = 'cite_web_url',
category = 'CS1 errors: requires URL',
hidden = false
},
err_class_ignored = {
message = '<code class="cs1-code">|class=</code> ignored',
anchor = 'class_ignored',
category = 'CS1 errors: class',
hidden = false
},
err_contributor_ignored = {
message = '<code class="cs1-code">|contributor=</code> ignored',
anchor = 'contributor_ignored',
category = 'CS1 errors: contributor',
hidden = false
},
err_contributor_missing_required_param = {
message = '<code class="cs1-code">|contributor=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'contributor_missing_required_param',
category = 'CS1 errors: contributor',
hidden = false
},
err_deprecated_params = {
message = 'Cite uses deprecated parameter <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'deprecated_params',
category = 'CS1 errors: deprecated parameters',
hidden = false
},
err_disp_name = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name; $2 is the assigned value
anchor = 'disp_name',
category = 'CS1 errors: display-names',
hidden = false,
},
err_doibroken_missing_doi = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|doi=</code>', -- $1 is parameter name
anchor = 'doibroken_missing_doi',
category = 'CS1 errors: DOI',
hidden = false
},
err_embargo_missing_pmc = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|pmc=</code>', -- $1 is parameter name
anchor = 'embargo_missing_pmc',
category = 'CS1 errors: PMC embargo',
hidden = false
},
err_empty_citation = {
message = 'Empty citation',
anchor = 'empty_citation',
category = 'CS1 errors: empty citation',
hidden = false
},
err_etal = {
message = 'Explicit use of et al. in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'explicit_et_al',
category = 'CS1 errors: explicit use of et al.',
hidden = false
},
err_extra_text_edition = {
message = '<code class="cs1-code">|edition=</code> has extra text',
anchor = 'extra_text_edition',
category = 'CS1 errors: extra text: edition',
hidden = false,
},
err_extra_text_issue = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_issue',
category = 'CS1 errors: extra text: issue',
hidden = false,
},
err_extra_text_pages = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_pages',
category = 'CS1 errors: extra text: pages',
hidden = false,
},
err_extra_text_volume = {
message = '<code class="cs1-code">|$1=</code> has extra text', -- $1 is parameter name
anchor = 'extra_text_volume',
category = 'CS1 errors: extra text: volume',
hidden = false,
},
err_first_missing_last = {
message = '<code class="cs1-code">|$1=</code> missing <code class="cs1-code">|$2=</code>', -- $1 is first alias, $2 is matching last alias
anchor = 'first_missing_last',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_format_missing_url = {
message = '<code class="cs1-code">|$1=</code> requires <code class="cs1-code">|$2=</code>', -- $1 is format parameter $2 is url parameter
anchor = 'format_missing_url',
category = 'CS1 errors: format without URL',
hidden = false
},
err_generic_name = {
message = '<code class="cs1-code">|$1=</code> has generic name', -- $1 is parameter name
anchor = 'generic_name',
category = 'CS1 errors: generic name',
hidden = false,
},
err_generic_title = {
message = 'Cite uses generic title',
anchor = 'generic_title',
category = 'CS1 errors: generic title',
hidden = false,
},
err_invalid_isbn_date = {
message = 'ISBN / Date incompatibility',
anchor = 'invalid_isbn_date',
category = 'CS1 errors: ISBN date',
hidden = true
},
err_invalid_param_val = {
message = 'Invalid <code class="cs1-code">|$1=$2</code>', -- $1 is parameter name $2 is parameter value
anchor = 'invalid_param_val',
category = 'CS1 errors: invalid parameter value',
hidden = false
},
err_invisible_char = {
message = '$1 in $2 at position $3', -- $1 is invisible char $2 is parameter name $3 is position number
anchor = 'invisible_char',
category = 'CS1 errors: invisible characters',
hidden = false
},
err_medrxiv_missing = {
message = '<code class="cs1-code">|medrxiv=</code> required',
anchor = 'medrxiv_missing',
category = 'CS1 errors: medRxiv', -- same as bad medRxiv
hidden = false
},
err_missing_name = {
message = 'Missing <code class="cs1-code">|$1$2=</code>', -- $1 is modified NameList; $2 is enumerator
anchor = 'missing_name',
category = 'CS1 errors: missing name', -- author, contributor, editor, interviewer, translator
hidden = false
},
err_missing_periodical = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical periodical parameter name for cite $1
anchor = 'missing_periodical',
category = 'CS1 errors: missing periodical',
hidden = false
},
err_missing_pipe = {
message = 'Missing pipe in: <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'missing_pipe',
category = 'CS1 errors: missing pipe',
hidden = false
},
err_missing_publisher = {
message = 'Cite $1 requires <code class="cs1-code">|$2=</code>', -- $1 is cs1 template name; $2 is canonical publisher parameter name for cite $1
anchor = 'missing_publisher',
category = 'CS1 errors: missing publisher',
hidden = false
},
err_numeric_names = {
message = '<code class="cs1-code">|$1=</code> has numeric name', -- $1 is parameter name',
anchor = 'numeric_names',
category = 'CS1 errors: numeric name',
hidden = false,
},
err_param_access_requires_param = {
message = '<code class="cs1-code">|$1-access=</code> requires <code class="cs1-code">|$1=</code>', -- $1 is parameter name
anchor = 'param_access_requires_param',
category = 'CS1 errors: param-access',
hidden = false
},
err_param_has_ext_link = {
message = 'External link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_ext_link',
category = 'CS1 errors: external links',
hidden = false
},
err_param_has_twl_url = {
message = 'Wikipedia Library link in <code class="cs1-code">$1</code>', -- $1 is parameter name
anchor = 'param_has_twl_url',
category = 'CS1 errors: URL',
hidden = false
},
err_param_unknown_empty = {
message = 'Cite has empty unknown parameter$1: $2', -- $1 is 's' or empty space; $2 is emty unknown param list
anchor = 'param_unknown_empty',
category = 'CS1 errors: empty unknown parameters',
hidden = false
},
err_parameter_ignored = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'parameter_ignored',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_parameter_ignored_suggest = {
message = 'Unknown parameter <code class="cs1-code">|$1=</code> ignored (<code class="cs1-code">|$2=</code> suggested)', -- $1 is unknown parameter $2 is suggested parameter name
anchor = 'parameter_ignored_suggest',
category = 'CS1 errors: unsupported parameter',
hidden = false
},
err_periodical_ignored = {
message = '<code class="cs1-code">|$1=</code> ignored', -- $1 is parameter name
anchor = 'periodical_ignored',
category = 'CS1 errors: periodical ignored',
hidden = false
},
err_redundant_parameters = {
message = 'More than one of $1 specified', -- $1 is error message detail
anchor = 'redundant_parameters',
category = 'CS1 errors: redundant parameter',
hidden = false
},
err_script_parameter = {
message = 'Invalid <code class="cs1-code">|$1=</code>: $2', -- $1 is parameter name $2 is script language code or error detail
anchor = 'script_parameter',
category = 'CS1 errors: script parameters',
hidden = false
},
err_ssrn_missing = {
message = '<code class="cs1-code">|ssrn=</code> required',
anchor = 'ssrn_missing',
category = 'CS1 errors: SSRN',
hidden = false
},
err_text_ignored = {
message = 'Text "$1" ignored', -- $1 is ignored text
anchor = 'text_ignored',
category = 'CS1 errors: unrecognized parameter',
hidden = false
},
err_trans_missing_title = {
message = '<code class="cs1-code">|trans-$1=</code> requires <code class="cs1-code">|$1=</code> or <code class="cs1-code">|script-$1=</code>', -- $1 is base parameter name
anchor = 'trans_missing_title',
category = 'CS1 errors: translated title',
hidden = false
},
err_url_suppressed = {
message = '<code class="cs1-code">|url=</code> suppressed',
anchor = 'url_suppressed',
category = 'CS1 errors: url suppressed',
hidden = false
},
err_vancouver = {
message = 'Vancouver style error: $1 in name $2', -- $1 is error detail, $2 is the nth name
anchor = 'vancouver',
category = 'CS1 errors: Vancouver style',
hidden = false
},
err_wikilink_in_url = {
message = 'URL–wikilink conflict', -- uses ndash
anchor = 'wikilink_in_url',
category = 'CS1 errors: URL–wikilink conflict', -- uses ndash
hidden = false
},
--[[--------------------------< M A I N T >-------------------------------------
maint messages do not have a message (message = nil); otherwise the structure
is the same as error messages
]]
maint_archive_origin = {
message = nil,
anchor = 'archive_origin',
category = 'CS1 maint: archive origin',
hidden = true,
},
maint_archived_copy = {
message = nil,
anchor = 'archived_copy',
category = 'CS1 maint: archived copy as title',
hidden = true,
},
maint_bibcode = {
message = nil,
anchor = 'bibcode',
category = 'CS1 maint: bibcode',
hidden = true,
},
maint_location_no_publisher = { -- cite book, conference, encyclopedia; citation as book cite or encyclopedia cite
message = nil,
anchor = 'location_no_publisher',
category = 'CS1 maint: location missing publisher',
hidden = true,
},
maint_bot_unknown = {
message = nil,
anchor = 'bot:_unknown',
category = 'CS1 maint: bot: original URL status unknown',
hidden = true,
},
maint_date_auto_xlated = { -- date auto-translation not supported by en.wiki
message = nil,
anchor = 'date_auto_xlated',
category = 'CS1 maint: date auto-translated',
hidden = true,
},
maint_date_format = {
message = nil,
anchor = 'date_format',
category = 'CS1 maint: date format',
hidden = true,
},
maint_date_year = {
message = nil,
anchor = 'date_year',
category = 'CS1 maint: date and year',
hidden = true,
},
maint_deprecated_archive = {
message = nil,
anchor = 'deprecated_archive',
category = 'CS1 maint: deprecated archival service',
hidden = true,
},
maint_doi_ignore = {
message = nil,
anchor = 'doi_ignore',
category = 'CS1 maint: ignored DOI errors',
hidden = true,
},
maint_doi_inactive = {
message = nil,
anchor = 'doi_inactive',
category = 'CS1 maint: DOI inactive',
hidden = true,
},
maint_doi_inactive_dated = {
message = nil,
anchor = 'doi_inactive_dated',
category = 'CS1 maint: DOI inactive as of $2$3$1', -- $1 is year, $2 is month-name or empty string, $3 is space or empty string
hidden = true,
},
maint_doi_unflagged_free = {
message = nil,
anchor = 'doi_unflagged_free',
category = 'CS1 maint: unflagged free DOI',
hidden = true,
},
maint_extra_punct = {
message = nil,
anchor = 'extra_punct',
category = 'CS1 maint: extra punctuation',
hidden = true,
},
maint_id_limit_load_fail = { -- applies to all cs1|2 templates on a page;
message = nil, -- maint message (category link) never emitted
anchor = 'id_limit_load_fail',
category = 'CS1 maint: ID limit load fail',
hidden = true,
},
maint_isbn_ignore = {
message = nil,
anchor = 'ignore_isbn_err',
category = 'CS1 maint: ignored ISBN errors',
hidden = true,
},
maint_issn_ignore = {
message = nil,
anchor = 'ignore_issn',
category = 'CS1 maint: ignored ISSN errors',
hidden = true,
},
maint_jfm_format = {
message = nil,
anchor = 'jfm_format',
category = 'CS1 maint: JFM format',
hidden = true,
},
maint_location = {
message = nil,
anchor = 'location',
category = 'CS1 maint: location',
hidden = true,
},
maint_misc_url = {
message = nil,
anchor = 'misc_url',
category = 'CS1 maint: miscellaneous url',
hidden = true,
},
maint_missing_class = {
message = nil,
anchor = 'missing_class',
category = 'CS1 maint: missing class',
hidden = true,
},
maint_mr_format = {
message = nil,
anchor = 'mr_format',
category = 'CS1 maint: MR format',
hidden = true,
},
maint_mult_names = {
message = nil,
anchor = 'mult_names',
category = 'CS1 maint: multiple names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_numeric_names = {
message = nil,
anchor = 'numeric_names',
category = 'CS1 maint: numeric names: $1', -- $1 is '<name>s list'; gets value from special_case_translation table
hidden = true,
},
maint_others = {
message = nil,
anchor = 'others',
category = 'CS1 maint: others',
hidden = true,
},
maint_others_avm = {
message = nil,
anchor = 'others_avm',
category = 'CS1 maint: others in cite AV media (notes)',
hidden = true,
},
maint_overridden_setting = {
message = nil,
anchor = 'overridden',
category = 'CS1 maint: overridden setting',
hidden = true,
},
maint_page_art_num = {
message = nil,
anchor = 'page_art_num',
category = 'CS1 maint: article number as page number',
hidden = true,
},
maint_periodical_has_isbn = {
message = nil,
anchor = 'periodical_has_isbn',
category = 'CS1 maint: periodical has ISBN',
hidden = true,
},
maint_pmc_embargo = {
message = nil,
anchor = 'embargo',
category = 'CS1 maint: PMC embargo expired',
hidden = true,
},
maint_pmc_format = {
message = nil,
anchor = 'pmc_format',
category = 'CS1 maint: PMC format',
hidden = true,
},
maint_postscript = {
message = nil,
anchor = 'postscript',
category = 'CS1 maint: postscript',
hidden = true,
},
maint_publisher_location = {
message = nil,
anchor = 'publisher_location',
category = 'CS1 maint: publisher location',
hidden = true,
},
maint_ref_duplicates_default = {
message = nil,
anchor = 'ref_default',
category = 'CS1 maint: ref duplicates default',
hidden = true,
},
maint_shortened_archive_url = {
message = nil,
anchor = 'shortened_archive_url',
category = 'CS1 maint: shortened archive url',
hidden = true,
},
maint_unknown_lang = {
message = nil,
anchor = 'unknown_lang',
category = 'CS1 maint: unrecognized language',
hidden = true,
},
maint_untitled = {
message = nil,
anchor = 'untitled',
category = 'CS1 maint: untitled periodical',
hidden = true,
},
maint_url_status = {
message = nil,
anchor = 'url_status',
category = 'CS1 maint: url-status',
hidden = true,
},
maint_work_isbn = {
message = nil,
anchor = 'work_isbn',
category = 'CS1 maint: work parameter with ISBN',
hidden = true,
},
maint_year= {
message = nil,
anchor = 'year',
category = 'CS1 maint: year',
hidden = true,
},
maint_zbl = {
message = nil,
anchor = 'zbl',
category = 'CS1 maint: Zbl',
hidden = true,
},
}
--[[--------------------------< I D _ L I M I T S _ D A T A _ T >----------------------------------------------
fetch id limits for certain identifiers from c:Data:CS1/Identifier limits.tab. This source is a json tabular
data file maintained at wikipedia commons. Convert the json format to a table of k/v pairs.
The values from <id_limits_data_t> are used to set handle.id_limit.
From 2025-02-21, MediaWiki is broken. Use this link to edit the tablular data file:
https://commons.wikimedia.org/w/index.php?title=Data:CS1/Identifier_limits.tab&action=edit
See Phab:T389105
]]
local id_limits_data_t;
local id_limits_data_load_fail = false; -- flag; assume that we will be successful when loading json id limit tabular data
local use_commons_data = true; -- set to false if your wiki does not have access to mediawiki commons; then,
if false == use_commons_data then -- update this table from https://commons.wikimedia.org/wiki/Data:CS1/Identifier_limits.tab; last update: 2026-08-02
id_limits_data_t = {['OCLC'] = 11160000000, ['OSTI'] = 23010000, ['PMC'] = 13500000, ['PMID'] = 42900000, ['RFC'] = 9300, ['SSRN'] = 7500000, ['S2CID'] = 290000000}; -- this table must be maintained locally
else -- here for wikis that do have access to mediawiki commons
local load_fail_limit = 99999999999; -- very high number to avoid error messages on load failure
id_limits_data_t = {['OCLC'] = load_fail_limit, ['OSTI'] = load_fail_limit, ['PMC'] = load_fail_limit, ['PMID'] = load_fail_limit, ['RFC'] = load_fail_limit, ['SSRN'] = load_fail_limit, ['S2CID'] = load_fail_limit};
if mw.ext.data == nil then
id_limits_data_load_fail = true; -- safeguard against Lua errors if mw.ext.data is not available for some reason
else
local tab_data_t = mw.ext.data.get ('CS1/Identifier limits.tab'); -- attempt to load the tabular data from commons into <tab_data_t>
if false == tab_data_t then -- undocumented 'feature': mw.ext.data.get() sometimes returns false
id_limits_data_load_fail = true; -- set the flag so that Module:Citation/CS1 can create an unannotated maint category
else
for _, limit_t in ipairs (tab_data_t.data) do -- overwrite default <load_fail_limit> values from the data table in the tabular data
id_limits_data_t[limit_t[1]] = limit_t[2]; -- <limit[1]> is identifier; <limit[2]> is upper limit for that identifier
end
end
end
end
--[[--------------------------< I D _ H A N D L E R S >--------------------------------------------------------
The following contains a list of values for various defined identifiers. For each
identifier we specify a variety of information necessary to properly render the
identifier in the citation.
parameters: a list of parameter aliases for this identifier; first in the list is the canonical form
link: Wikipedia article name
redirect: a local redirect to a local Wikipedia article name; at en.wiki, 'ISBN (identifier)' is a redirect to 'International Standard Book Number'
q: Wikidata q number for the identifier
label: the label preceding the identifier; label is linked to a Wikipedia article (in this order):
redirect from id_handlers['<id>'].redirect when use_identifier_redirects is true
Wikidata-supplied article name for the local wiki from id_handlers['<id>'].q
local article name from id_handlers['<id>'].link
prefix: the first part of a URL that will be concatenated with a second part which usually contains the identifier
suffix: optional third part to be added after the identifier
encode: true if URI should be percent-encoded; otherwise false
COinS: identifier link or keyword for use in COinS:
for identifiers registered at info-uri.info use: info:.... where '...' is the appropriate identifier label
for identifiers that have COinS keywords, use the keyword: rft.isbn, rft.issn, rft.eissn
for |asin= and |ol=, which require assembly, use the keyword: url
for others make a URL using the value in prefix/suffix and #label, use the keyword: pre (not checked; any text other than 'info', 'rft', or 'url' works here)
set to nil to leave the identifier out of the COinS
separator: character or text between label and the identifier in the rendered citation
id_limit: for those identifiers with established limits, this property holds the upper limit
access: use this parameter to set the access level for all instances of this identifier.
the value must be a valid access level for an identifier (see ['id-access'] in this file).
custom_access: to enable custom access level for an identifier, set this parameter
to the parameter that should control it (normally 'id-access')
]]
local id_handlers = {
['ARXIV'] = {
parameters = {'arxiv', 'eprint'},
link = 'arXiv',
redirect = 'arXiv (identifier)',
q = 'Q118398',
label = 'arXiv',
prefix = 'https://arxiv.org/abs/',
encode = false,
COinS = 'info:arxiv',
separator = ':',
access = 'free', -- free to read
},
['ASIN'] = {
parameters = { 'asin', 'ASIN' },
link = 'Amazon Standard Identification Number',
redirect = 'ASIN (identifier)',
q = 'Q1753278',
label = 'ASIN',
prefix = 'https://www.amazon.',
COinS = 'url',
separator = ' ',
encode = false;
},
['BIBCODE'] = {
parameters = {'bibcode'},
link = 'Bibcode',
redirect = 'Bibcode (identifier)',
q = 'Q25754',
label = 'Bibcode',
prefix = 'https://scixplorer.org/abs/',
encode = false,
COinS = 'info:bibcode',
separator = ':',
custom_access = 'bibcode-access',
},
['BIORXIV'] = {
parameters = {'biorxiv'},
link = 'bioRxiv',
redirect = 'bioRxiv (identifier)',
q = 'Q19835482',
label = 'bioRxiv',
prefix = 'https://doi.org/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['CITESEERX'] = {
parameters = {'citeseerx'},
link = 'CiteSeerX',
redirect = 'CiteSeerX (identifier)',
q = 'Q2715061',
label = 'CiteSeerX',
prefix = 'https://citeseerx.ist.psu.edu/viewdoc/summary?doi=',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = true,
separator = ' ',
},
['DOI'] = { -- Used by InternetArchiveBot
parameters = { 'doi', 'DOI'},
link = 'Digital object identifier',
redirect = 'doi (identifier)',
q = 'Q25670',
label = 'doi',
prefix = 'https://doi.org/',
COinS = 'info:doi',
separator = ':',
encode = true,
custom_access = 'doi-access',
},
['EISSN'] = {
parameters = {'eissn', 'EISSN'},
link = 'International Standard Serial Number#Electronic ISSN',
redirect = 'eISSN (identifier)',
q = 'Q46339674',
label = 'eISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.eissn',
encode = false,
separator = ' ',
},
['HDL'] = {
parameters = { 'hdl', 'HDL' },
link = 'Handle System',
redirect = 'hdl (identifier)',
q = 'Q3126718',
label = 'hdl',
prefix = 'https://hdl.handle.net/',
COinS = 'info:hdl',
separator = ':',
encode = true,
custom_access = 'hdl-access',
},
['ISBN'] = { -- Used by InternetArchiveBot
parameters = {'isbn', 'ISBN'},
link = 'International Standard Book Number',
redirect = 'ISBN (identifier)',
q = 'Q33057',
label = 'ISBN',
prefix = 'Special:BookSources/',
COinS = 'rft.isbn',
separator = ' ',
},
['ISMN'] = {
parameters = {'ismn', 'ISMN'},
link = 'International Standard Music Number',
redirect = 'ISMN (identifier)',
q = 'Q1666938',
label = 'ISMN',
prefix = '', -- not currently used;
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['ISSN'] = {
parameters = {'issn', 'ISSN'},
link = 'International Standard Serial Number',
redirect = 'ISSN (identifier)',
q = 'Q131276',
label = 'ISSN',
prefix = 'https://search.worldcat.org/issn/',
COinS = 'rft.issn',
encode = false,
separator = ' ',
},
['JFM'] = {
parameters = {'jfm', 'JFM'},
link = 'Jahrbuch über die Fortschritte der Mathematik',
redirect = 'JFM (identifier)',
q = '',
label = 'JFM',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['JSTOR'] = {
parameters = {'jstor', 'JSTOR'},
link = 'JSTOR',
redirect = 'JSTOR (identifier)',
q = 'Q1420342',
label = 'JSTOR',
prefix = 'https://www.jstor.org/stable/',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
custom_access = 'jstor-access',
},
['LCCN'] = {
parameters = {'lccn', 'LCCN'},
link = 'Library of Congress Control Number',
redirect = 'LCCN (identifier)',
q = 'Q620946',
label = 'LCCN',
prefix = 'https://lccn.loc.gov/',
COinS = 'info:lccn',
encode = false,
separator = ' ',
},
['MEDRXIV'] = {
parameters = {'medrxiv'},
link = 'medRxiv',
redirect = 'medRxiv (identifier)',
q = 'Q58465838',
label = 'medRxiv',
prefix = 'https://www.medrxiv.org/content/',
COinS = 'pre', -- use prefix value
access = 'free', -- free to read
encode = false,
separator = ' ',
},
['MR'] = {
parameters = {'mr', 'MR'},
link = 'Mathematical Reviews',
redirect = 'MR (identifier)',
q = 'Q211172',
label = 'MR',
prefix = 'https://mathscinet.ams.org/mathscinet-getitem?mr=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
['OCLC'] = {
parameters = {'oclc', 'OCLC'},
link = 'OCLC',
redirect = 'OCLC (identifier)',
q = 'Q190593',
label = 'OCLC',
prefix = 'https://search.worldcat.org/oclc/',
COinS = 'info:oclcnum',
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OCLC or 0,
},
['OL'] = {
parameters = { 'ol', 'OL' },
link = 'Open Library',
redirect = 'OL (identifier)',
q = 'Q1201876',
label = 'OL',
prefix = 'https://openlibrary.org/',
COinS = 'url',
separator = ' ',
encode = true,
custom_access = 'ol-access',
},
['OSTI'] = {
parameters = {'osti', 'OSTI'},
link = 'Office of Scientific and Technical Information',
redirect = 'OSTI (identifier)',
q = 'Q2015776',
label = 'OSTI',
prefix = 'https://www.osti.gov/biblio/',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.OSTI or 0,
custom_access = 'osti-access',
},
['PMC'] = {
parameters = {'pmc', 'PMC'},
link = 'PubMed Central',
redirect = 'PMC (identifier)',
q = 'Q229883',
label = 'PMC',
prefix = 'https://www.ncbi.nlm.nih.gov/pmc/articles/PMC',
suffix = '',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.PMC or 0,
access = 'free', -- free to read
},
['PMID'] = {
parameters = {'pmid', 'PMID'},
link = 'PubMed Identifier',
redirect = 'PMID (identifier)',
q = 'Q2082879',
label = 'PMID',
prefix = 'https://pubmed.ncbi.nlm.nih.gov/',
COinS = 'info:pmid',
encode = false,
separator = ' ',
id_limit = id_limits_data_t.PMID or 0,
},
['RFC'] = {
parameters = {'rfc', 'RFC'},
link = 'Request for Comments',
redirect = 'RFC (identifier)',
q = 'Q212971',
label = 'RFC',
prefix = 'https://tools.ietf.org/html/rfc',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.RFC or 0,
access = 'free', -- free to read
},
['SBN'] = {
parameters = {'sbn', 'SBN'},
link = 'Standard Book Number', -- redirect to International_Standard_Book_Number#History
redirect = 'SBN (identifier)',
label = 'SBN',
prefix = 'Special:BookSources/0-', -- prefix has leading zero necessary to make 9-digit sbn a 10-digit isbn
COinS = nil, -- nil because we can't use pre or rft or info:
separator = ' ',
},
['SSRN'] = {
parameters = {'ssrn', 'SSRN'},
link = 'Social Science Research Network',
redirect = 'SSRN (identifier)',
q = 'Q7550801',
label = 'SSRN',
prefix = 'https://papers.ssrn.com/sol3/papers.cfm?abstract_id=',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
id_limit = id_limits_data_t.SSRN or 0,
custom_access = 'ssrn-access',
},
['S2CID'] = {
parameters = {'s2cid', 'S2CID'},
link = 'Semantic Scholar',
redirect = 'S2CID (identifier)',
q = 'Q22908627',
label = 'S2CID',
prefix = 'https://api.semanticscholar.org/CorpusID:',
COinS = 'pre', -- use prefix value
encode = false,
separator = ' ',
id_limit = id_limits_data_t.S2CID or 0,
custom_access = 's2cid-access',
},
['USENETID'] = {
parameters = {'message-id'},
link = 'Usenet',
redirect = 'Usenet (identifier)',
q = 'Q193162',
label = 'Usenet:',
prefix = 'news:',
encode = false,
COinS = 'pre', -- use prefix value
separator = ' ',
},
['ZBL'] = {
parameters = {'zbl', 'ZBL' },
link = 'Zentralblatt MATH',
redirect = 'Zbl (identifier)',
q = 'Q190269',
label = 'Zbl',
prefix = 'https://zbmath.org/?format=complete&q=an:',
COinS = 'pre', -- use prefix value
encode = true,
separator = ' ',
},
}
--[[--------------------------< E X P O R T S >---------------------------------
]]
return {
use_identifier_redirects = use_identifier_redirects, -- booleans defined in the settings at the top of this module
local_lang_cat_enable = local_lang_cat_enable,
date_name_auto_xlate_enable = date_name_auto_xlate_enable,
date_digit_auto_xlate_enable = date_digit_auto_xlate_enable,
enable_sort_keys = enable_sort_keys,
suppress_archive_today_urls = suppress_archive_today_urls,
-- tables and variables created when this module is loaded
dependencies_t = dependencies_t, -- used to suppress parameters dependent on url-holding parameters holding archive.today urls
enum_needs_xlation = '1' ~= date_names.xlate_digits['1'], -- to avoid unnecessary enumerator translation
global_df = get_date_format (), -- this line can be replaced with "global_df = 'dmy-all'," to have all dates auto translated to dmy format.
global_cs1_config_t = global_cs1_config_t, -- global settings from {{cs1 config}}
id_limits_data_load_fail = id_limits_data_load_fail, -- true when commons tabular identifier-limit data fails to load
known_free_doi_registrants_t = build_free_doi_registrants_table(),
punct_skip = build_skip_table (punct_skip, punct_meta_params),
url_skip = build_skip_table (url_skip, url_meta_params),
archive_today_tlds_t = {['today'] = true, ['ph'] = true, ['is'] = true, ['md'] = true, ['li'] = true, ['fo'] = true, ['vn'] = true}; -- used by is_archive_today_url()
name_space_sort_keys = name_space_sort_keys,
aliases = aliases,
special_case_translation = special_case_translation,
date_names = date_names,
err_msg_supl = err_msg_supl,
error_conditions = error_conditions,
et_al_patterns = et_al_patterns,
extended_registrants_t = extended_registrants_t,
id_handlers = id_handlers,
keywords_lists = keywords_lists,
keywords_xlate = keywords_xlate,
stripmarkers = stripmarkers,
invisible_chars = invisible_chars,
invisible_defs = invisible_defs,
indic_script = indic_script,
emoji_t = emoji_t,
messages = messages,
presentation = presentation,
prop_cats = prop_cats,
script_lang_codes = script_lang_codes,
lang_tag_remap = lang_tag_remap,
lang_name_remap = lang_name_remap,
this_wiki_code = this_wiki_code,
title_types = title_types,
uncategorized_namespaces = uncategorized_namespaces_t,
uncategorized_subpages = uncategorized_subpages,
templates_using_volume = templates_using_volume,
templates_using_issue = templates_using_issue,
templates_not_using_page = templates_not_using_page,
vol_iss_pg_patterns = vol_iss_pg_patterns,
single_letter_2nd_lvl_domains_t = single_letter_2nd_lvl_domains_t,
url_access_map_t = url_access_map_t,
inter_wiki_map = inter_wiki_map,
mw_languages_by_tag_t = mw_languages_by_tag_t,
mw_languages_by_name_t = mw_languages_by_name_t,
citation_class_map_t = citation_class_map_t,
citation_issue_t = citation_issue_t,
citation_no_volume_t = citation_no_volume_t,
}
mtf0w1ow8dokpa8ltsmoqupkxr4vaq4
Module:Citation/CS1/COinS
828
12887
124169
118678
2026-11-07T20:03:18Z
en>Trappist the monk
0
synch from sandbox;
124169
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup; -- functions in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< M A K E _ C O I N S _ T I T L E >----------------------------------------------
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn't corrupted with strings
of %27%27...
]]
local function make_coins_title (title, script)
title = has_accept_as_written (title);
if is_set (title) then
title = strip_apostrophe_markup (title); -- strip any apostrophe markup
else
title = ''; -- if not set, make sure title is an empty string
end
if is_set (script) then
script = script:gsub ('^%l%l%s*:%s*', ''); -- remove language prefix if present (script value may now be empty string)
script = strip_apostrophe_markup (script); -- strip any apostrophe markup
else
script = ''; -- if not set, make sure script is an empty string
end
if is_set (title) and is_set (script) then
script = ' ' .. script; -- add a space before we concatenate
end
return title .. script; -- return the concatenation
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of Lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other Lua magic pattern characters
return argument;
end
--[[--------------------------< G E T _ C O I N S _ P A G E S >------------------------------------------------
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.
]]
local function get_coins_pages (pages)
local pattern;
if not is_set (pages) then return pages; end -- if no page numbers then we're done
while true do
pattern = pages:match("%[(%w*:?//[^ ]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the URL and following space(s): "[url "
if nil == pattern then break; end -- no more URLs
pattern = escape_lua_magic_chars (pattern); -- pattern is not a literal string; escape Lua's magic pattern characters
pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible
end
pages = pages:gsub("[%[%]]", ""); -- remove the brackets
pages = pages:gsub("–", "-" ); -- replace endashes with hyphens
pages = pages:gsub("&%w+;", "-" ); -- and replace HTML entities (– etc.) with hyphens; do we need to replace numerical entities like   and the like?
pages = pages:gsub ('%b<>', ''); -- remove html-like tags; spans are added to <Pages> by utilities.hyphen_to_dash() which should not appear in COinS metadata
return pages;
end
--[=[-------------------------< C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R >------------------
There are three options for math markup rendering that depend on the editor's math preference settings. These
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are
PNG images
TeX source
MathML with SVG or PNG fallback
All three are heavy with HTML and CSS which doesn't belong in the metadata.
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings
of the last editor to save the page.
This function gets the rendered form of an equation according to the editor's preference before the page is saved. It
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial
value. To replace multipe equations it is necessary to call this function from within a loop.
]=]
local function coins_replace_math_stripmarker (value)
local stripmarker = cfg.stripmarkers['math'];
local rendering = value:match (stripmarker); -- is there a math stripmarker
if not rendering then -- when value doesn't have a math stripmarker, abandon this test
return false, value;
end
rendering = mw.text.unstripNoWiki (rendering); -- convert stripmarker into rendered value (or nil? ''? when math render error)
if rendering:match ('alt="[^"]+"') then -- if PNG math option
rendering = rendering:match ('alt="([^"]+)"'); -- extract just the math text
elseif rendering:match ('$%s+.+%s+%$') then -- if TeX math option; $ is legit character that is escapes as \$
rendering = rendering:match ('$%s+(.+)%s+%$') -- extract just the math text
elseif rendering:match ('<annotation[^>]+>.+</annotation>') then -- if MathML math option
rendering = rendering:match ('<annotation[^>]+>(.+)</annotation>') -- extract just the math text
else
return false, value; -- had math stripmarker but not one of the three defined forms
end
return true, value:gsub (stripmarker, rendering, 1);
end
--[[--------------------------< C O I N S _ C L E A N U P >----------------------------------------------------
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.
2015-12-10: there is a bug in mw.text.unstripNoWiki (). It replaces math stripmarkers with the appropriate content
when it shouldn't. See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible
characters table?
]]
local function coins_cleanup (value)
local replaced = true; -- default state to get the do loop running
while replaced do -- loop until all math stripmarkers replaced
replaced, value = coins_replace_math_stripmarker (value); -- replace math stripmarker with text representation of the equation
end
value = value:gsub (cfg.stripmarkers['math'], "MATH RENDER ERROR"); -- one or more couldn't be replaced; insert vague error message
value = mw.text.unstrip (value); -- replace nowiki stripmarkers with their content, and kill other stripmarkers
value = value:gsub ('<span class="nowrap" style="padding%-left:0%.1em;">'(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s
value = value:gsub (' ', ' '); -- replace entity with plain space
value = value:gsub ('\226\128\138', ' '); -- replace hair space with plain space
if not mw.ustring.find (value, cfg.indic_script) then -- don't remove zero-width joiner characters from indic script
value = value:gsub ('‍', ''); -- remove ‍ entities
value = mw.ustring.gsub (value, '[\226\128\141\226\128\139\194\173]', ''); -- remove zero-width joiner, zero-width space, soft hyphen
end
value = value:gsub ('[\009\010\013 ]+', ' '); -- replace horizontal tab, line feed, carriage return with plain space
value = mw.text.decode(value, true) -- decode HTML entities
return value;
end
--[[--------------------------< C O I N S >--------------------------------------------------------------------
COinS metadata (see <http://ocoins.info/>) allows automated tools to parse the citation information.
]]
local function COinS(data, class)
if 'table' ~= type(data) or nil == next(data) then
return '';
end
for k, v in pairs (data) do -- spin through all of the metadata parameter values
if 'ID_list' ~= k and 'Authors' ~= k then -- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)
data[k] = coins_cleanup (v);
end
end
local ctx_ver = "Z39.88-2004";
-- treat table strictly as an array with only set values.
local OCinSoutput = setmetatable( {}, {
__newindex = function(self, key, value)
if is_set(value) then
rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( remove_wiki_link( value ) ) } );
end
end
});
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn', 'journal', 'news', 'magazine'}) or
(in_array (class, {'conference', 'interview', 'map', 'press release', 'web'}) and is_set(data.Periodical)) or
('citation' == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; -- journal metadata identifier
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) then -- set genre according to the type of citation template we are rendering
OCinSoutput["rft.genre"] = "preprint"; -- cite arxiv, cite biorxiv, cite citeseerx, cite medrxiv, cite ssrn
elseif 'conference' == class then
OCinSoutput["rft.genre"] = "conference"; -- cite conference (when Periodical set)
elseif 'web' == class then
OCinSoutput["rft.genre"] = "unknown"; -- cite web (when Periodical set)
else
OCinSoutput["rft.genre"] = "article"; -- journal and other 'periodical' articles
end
OCinSoutput["rft.jtitle"] = data.Periodical; -- journal only
OCinSoutput["rft.atitle"] = data.Title; -- 'periodical' article titles
-- these used only for periodicals
OCinSoutput["rft.ssn"] = data.Season; -- keywords: winter, spring, summer, fall
OCinSoutput["rft.quarter"] = data.Quarter; -- single digits 1->first quarter, etc.
OCinSoutput["rft.chron"] = data.Chron; -- free-form date components
OCinSoutput["rft.volume"] = data.Volume; -- does not apply to books
OCinSoutput["rft.issue"] = data.Issue;
OCinSoutput['rft.artnum'] = data.ArticleNumber; -- {{cite journal}} only
OCinSoutput["rft.pages"] = data.Pages; -- also used in book metadata
elseif 'thesis' ~= class then -- all others except cite thesis are treated as 'book' metadata; genre distinguishes
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; -- book metadata identifier
if 'report' == class or 'techreport' == class then -- cite report and cite techreport
OCinSoutput["rft.genre"] = "report";
elseif 'conference' == class then -- cite conference when Periodical not set
OCinSoutput["rft.genre"] = "conference";
OCinSoutput["rft.atitle"] = data.Chapter; -- conference paper as chapter in proceedings (book)
elseif in_array (class, {'book', 'citation', 'encyclopaedia', 'interview', 'map'}) then
if is_set (data.Chapter) then
OCinSoutput["rft.genre"] = "bookitem";
OCinSoutput["rft.atitle"] = data.Chapter; -- book chapter, encyclopedia article, interview in a book, or map title
else
if 'map' == class or 'interview' == class then
OCinSoutput["rft.genre"] = 'unknown'; -- standalone map or interview
else
OCinSoutput["rft.genre"] = 'book'; -- book and encyclopedia
end
end
else -- {'audio-visual', 'AV-media-notes', 'DVD-notes', 'episode', 'interview', 'mailinglist', 'map', 'newsgroup', 'podcast', 'press release', 'serial', 'sign', 'speech', 'web'}
OCinSoutput["rft.genre"] = "unknown";
end
OCinSoutput["rft.btitle"] = data.Title; -- book only
OCinSoutput["rft.place"] = data.PublicationPlace; -- book only
OCinSoutput["rft.series"] = data.Series; -- book only
OCinSoutput["rft.pages"] = data.Pages; -- book, journal
OCinSoutput["rft.edition"] = data.Edition; -- book only
OCinSoutput["rft.pub"] = data.PublisherName; -- book and dissertation
else -- cite thesis
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:dissertation"; -- dissertation metadata identifier
OCinSoutput["rft.title"] = data.Title; -- dissertation (also patent but that is not yet supported)
OCinSoutput["rft.degree"] = data.Degree; -- dissertation only
OCinSoutput['rft.inst'] = data.PublisherName; -- book and dissertation
end
-- NB. Not currently supported are "info:ofi/fmt:kev:mtx:patent", "info:ofi/fmt:kev:mtx:dc", "info:ofi/fmt:kev:mtx:sch_svc", "info:ofi/fmt:kev:mtx:ctx"
-- and now common parameters (as much as possible)
OCinSoutput["rft.date"] = data.Date; -- book, journal, dissertation
for k, v in pairs( data.ID_list ) do -- what to do about these? For now assume that they are common to all?
if k == 'ISBN' then v = v:gsub( "[^-0-9X]", "" ); end
local id = cfg.id_handlers[k].COinS;
if string.sub( id or "", 1, 4 ) == 'info' then -- for ids that are in the info:registry
OCinSoutput["rft_id"] = table.concat{ id, "/", v };
elseif string.sub (id or "", 1, 3 ) == 'rft' then -- for isbn, issn, eissn, etc. that have defined COinS keywords
OCinSoutput[ id ] = v;
elseif 'url' == id then -- for urls that are assembled in ~/Identifiers; |asin= and |ol=
OCinSoutput["rft_id"] = table.concat ({data.ID_list[k], "#id-name=", cfg.id_handlers[k].label});
elseif id then -- when cfg.id_handlers[k].COinS is not nil so urls created here
OCinSoutput["rft_id"] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or '', "#id-name=", cfg.id_handlers[k].label }; -- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)
end
end
local last, first;
for k, v in ipairs( data.Authors ) do
last, first = coins_cleanup (v.last), coins_cleanup (v.first or ''); -- replace any nowiki stripmarkers, non-printing or invisible characters
if k == 1 then -- for the first author name only
if is_set(last) and is_set(first) then -- set these COinS values if |first= and |last= specify the first author name
OCinSoutput["rft.aulast"] = last; -- book, journal, dissertation
OCinSoutput["rft.aufirst"] = first; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation -- otherwise use this form for the first name
end
else -- for all other authors
if is_set(last) and is_set(first) then
OCinSoutput["rft.au"] = table.concat{ last, ", ", first }; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation
end
-- TODO: At present we do not report "et al.". Add anything special if this condition applies?
end
end
OCinSoutput.rft_id = data.URL;
OCinSoutput.rfr_id = table.concat{ "info:sid/", string.match (mw.site.server, "[^/]*$" ), ":", data.RawPage };
-- TODO: Add optional extra info:
-- rfr_dat=#REVISION<version> (referrer private data)
-- ctx_id=<data.RawPage>#<ref> (identifier for the context object)
-- ctx_tim=<ts> (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)
-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)
OCinSoutput = setmetatable( OCinSoutput, nil );
-- sort with version string always first, and combine.
-- table.sort( OCinSoutput );
table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"
return table.concat(OCinSoutput, "&");
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
remove_wiki_link = utilities_page_ptr.remove_wiki_link;
strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
make_coins_title = make_coins_title,
get_coins_pages = get_coins_pages,
COinS = COinS,
set_selected_modules = set_selected_modules,
}
c3cf0jrk7cgctay7otxhzxbnb7fbxol
124170
124169
2026-11-09T20:20:37Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Citation/CS1/COinS]]
124169
Scribunto
text/plain
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local has_accept_as_written, is_set, in_array, remove_wiki_link, strip_apostrophe_markup; -- functions in Module:Citation/CS1/Utilities
local cfg; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
--[[--------------------------< M A K E _ C O I N S _ T I T L E >----------------------------------------------
Makes a title for COinS from Title and / or ScriptTitle (or any other name-script pairs)
Apostrophe markup (bold, italics) is stripped from each value so that the COinS metadata isn't corrupted with strings
of %27%27...
]]
local function make_coins_title (title, script)
title = has_accept_as_written (title);
if is_set (title) then
title = strip_apostrophe_markup (title); -- strip any apostrophe markup
else
title = ''; -- if not set, make sure title is an empty string
end
if is_set (script) then
script = script:gsub ('^%l%l%s*:%s*', ''); -- remove language prefix if present (script value may now be empty string)
script = strip_apostrophe_markup (script); -- strip any apostrophe markup
else
script = ''; -- if not set, make sure script is an empty string
end
if is_set (title) and is_set (script) then
script = ' ' .. script; -- add a space before we concatenate
end
return title .. script; -- return the concatenation
end
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of Lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other Lua magic pattern characters
return argument;
end
--[[--------------------------< G E T _ C O I N S _ P A G E S >------------------------------------------------
Extract page numbers from external wikilinks in any of the |page=, |pages=, or |at= parameters for use in COinS.
]]
local function get_coins_pages (pages)
local pattern;
if not is_set (pages) then return pages; end -- if no page numbers then we're done
while true do
pattern = pages:match("%[(%w*:?//[^ ]+%s+)[%w%d].*%]"); -- pattern is the opening bracket, the URL and following space(s): "[url "
if nil == pattern then break; end -- no more URLs
pattern = escape_lua_magic_chars (pattern); -- pattern is not a literal string; escape Lua's magic pattern characters
pages = pages:gsub(pattern, ""); -- remove as many instances of pattern as possible
end
pages = pages:gsub("[%[%]]", ""); -- remove the brackets
pages = pages:gsub("–", "-" ); -- replace endashes with hyphens
pages = pages:gsub("&%w+;", "-" ); -- and replace HTML entities (– etc.) with hyphens; do we need to replace numerical entities like   and the like?
pages = pages:gsub ('%b<>', ''); -- remove html-like tags; spans are added to <Pages> by utilities.hyphen_to_dash() which should not appear in COinS metadata
return pages;
end
--[=[-------------------------< C O I N S _ R E P L A C E _ M A T H _ S T R I P M A R K E R >------------------
There are three options for math markup rendering that depend on the editor's math preference settings. These
settings are at [[Special:Preferences#mw-prefsection-rendering]] and are
PNG images
TeX source
MathML with SVG or PNG fallback
All three are heavy with HTML and CSS which doesn't belong in the metadata.
Without this function, the metadata saved in the raw wikitext contained the rendering determined by the settings
of the last editor to save the page.
This function gets the rendered form of an equation according to the editor's preference before the page is saved. It
then searches the rendering for the text equivalent of the rendered equation and replaces the rendering with that so
that the page is saved without extraneous HTML/CSS markup and with a reasonably readable text form of the equation.
When a replacement is made, this function returns true and the value with replacement; otherwise false and the initial
value. To replace multipe equations it is necessary to call this function from within a loop.
]=]
local function coins_replace_math_stripmarker (value)
local stripmarker = cfg.stripmarkers['math'];
local rendering = value:match (stripmarker); -- is there a math stripmarker
if not rendering then -- when value doesn't have a math stripmarker, abandon this test
return false, value;
end
rendering = mw.text.unstripNoWiki (rendering); -- convert stripmarker into rendered value (or nil? ''? when math render error)
if rendering:match ('alt="[^"]+"') then -- if PNG math option
rendering = rendering:match ('alt="([^"]+)"'); -- extract just the math text
elseif rendering:match ('$%s+.+%s+%$') then -- if TeX math option; $ is legit character that is escapes as \$
rendering = rendering:match ('$%s+(.+)%s+%$') -- extract just the math text
elseif rendering:match ('<annotation[^>]+>.+</annotation>') then -- if MathML math option
rendering = rendering:match ('<annotation[^>]+>(.+)</annotation>') -- extract just the math text
else
return false, value; -- had math stripmarker but not one of the three defined forms
end
return true, value:gsub (stripmarker, rendering, 1);
end
--[[--------------------------< C O I N S _ C L E A N U P >----------------------------------------------------
Cleanup parameter values for the metadata by removing or replacing invisible characters and certain HTML entities.
2015-12-10: there is a bug in mw.text.unstripNoWiki (). It replaces math stripmarkers with the appropriate content
when it shouldn't. See https://phabricator.wikimedia.org/T121085 and Wikipedia_talk:Lua#stripmarkers_and_mw.text.unstripNoWiki.28.29
TODO: move the replacement patterns and replacement values into a table in /Configuration similar to the invisible
characters table?
]]
local function coins_cleanup (value)
local replaced = true; -- default state to get the do loop running
while replaced do -- loop until all math stripmarkers replaced
replaced, value = coins_replace_math_stripmarker (value); -- replace math stripmarker with text representation of the equation
end
value = value:gsub (cfg.stripmarkers['math'], "MATH RENDER ERROR"); -- one or more couldn't be replaced; insert vague error message
value = mw.text.unstrip (value); -- replace nowiki stripmarkers with their content, and kill other stripmarkers
value = value:gsub ('<span class="nowrap" style="padding%-left:0%.1em;">'(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s
value = value:gsub (' ', ' '); -- replace entity with plain space
value = value:gsub ('\226\128\138', ' '); -- replace hair space with plain space
if not mw.ustring.find (value, cfg.indic_script) then -- don't remove zero-width joiner characters from indic script
value = value:gsub ('‍', ''); -- remove ‍ entities
value = mw.ustring.gsub (value, '[\226\128\141\226\128\139\194\173]', ''); -- remove zero-width joiner, zero-width space, soft hyphen
end
value = value:gsub ('[\009\010\013 ]+', ' '); -- replace horizontal tab, line feed, carriage return with plain space
value = mw.text.decode(value, true) -- decode HTML entities
return value;
end
--[[--------------------------< C O I N S >--------------------------------------------------------------------
COinS metadata (see <http://ocoins.info/>) allows automated tools to parse the citation information.
]]
local function COinS(data, class)
if 'table' ~= type(data) or nil == next(data) then
return '';
end
for k, v in pairs (data) do -- spin through all of the metadata parameter values
if 'ID_list' ~= k and 'Authors' ~= k then -- except the ID_list and Author tables (author nowiki stripmarker done when Author table processed)
data[k] = coins_cleanup (v);
end
end
local ctx_ver = "Z39.88-2004";
-- treat table strictly as an array with only set values.
local OCinSoutput = setmetatable( {}, {
__newindex = function(self, key, value)
if is_set(value) then
rawset( self, #self+1, table.concat{ key, '=', mw.uri.encode( remove_wiki_link( value ) ) } );
end
end
});
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn', 'journal', 'news', 'magazine'}) or
(in_array (class, {'conference', 'interview', 'map', 'press release', 'web'}) and is_set(data.Periodical)) or
('citation' == class and is_set(data.Periodical) and not is_set (data.Encyclopedia)) then
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; -- journal metadata identifier
if in_array (class, {'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) then -- set genre according to the type of citation template we are rendering
OCinSoutput["rft.genre"] = "preprint"; -- cite arxiv, cite biorxiv, cite citeseerx, cite medrxiv, cite ssrn
elseif 'conference' == class then
OCinSoutput["rft.genre"] = "conference"; -- cite conference (when Periodical set)
elseif 'web' == class then
OCinSoutput["rft.genre"] = "unknown"; -- cite web (when Periodical set)
else
OCinSoutput["rft.genre"] = "article"; -- journal and other 'periodical' articles
end
OCinSoutput["rft.jtitle"] = data.Periodical; -- journal only
OCinSoutput["rft.atitle"] = data.Title; -- 'periodical' article titles
-- these used only for periodicals
OCinSoutput["rft.ssn"] = data.Season; -- keywords: winter, spring, summer, fall
OCinSoutput["rft.quarter"] = data.Quarter; -- single digits 1->first quarter, etc.
OCinSoutput["rft.chron"] = data.Chron; -- free-form date components
OCinSoutput["rft.volume"] = data.Volume; -- does not apply to books
OCinSoutput["rft.issue"] = data.Issue;
OCinSoutput['rft.artnum'] = data.ArticleNumber; -- {{cite journal}} only
OCinSoutput["rft.pages"] = data.Pages; -- also used in book metadata
elseif 'thesis' ~= class then -- all others except cite thesis are treated as 'book' metadata; genre distinguishes
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; -- book metadata identifier
if 'report' == class or 'techreport' == class then -- cite report and cite techreport
OCinSoutput["rft.genre"] = "report";
elseif 'conference' == class then -- cite conference when Periodical not set
OCinSoutput["rft.genre"] = "conference";
OCinSoutput["rft.atitle"] = data.Chapter; -- conference paper as chapter in proceedings (book)
elseif in_array (class, {'book', 'citation', 'encyclopaedia', 'interview', 'map'}) then
if is_set (data.Chapter) then
OCinSoutput["rft.genre"] = "bookitem";
OCinSoutput["rft.atitle"] = data.Chapter; -- book chapter, encyclopedia article, interview in a book, or map title
else
if 'map' == class or 'interview' == class then
OCinSoutput["rft.genre"] = 'unknown'; -- standalone map or interview
else
OCinSoutput["rft.genre"] = 'book'; -- book and encyclopedia
end
end
else -- {'audio-visual', 'AV-media-notes', 'DVD-notes', 'episode', 'interview', 'mailinglist', 'map', 'newsgroup', 'podcast', 'press release', 'serial', 'sign', 'speech', 'web'}
OCinSoutput["rft.genre"] = "unknown";
end
OCinSoutput["rft.btitle"] = data.Title; -- book only
OCinSoutput["rft.place"] = data.PublicationPlace; -- book only
OCinSoutput["rft.series"] = data.Series; -- book only
OCinSoutput["rft.pages"] = data.Pages; -- book, journal
OCinSoutput["rft.edition"] = data.Edition; -- book only
OCinSoutput["rft.pub"] = data.PublisherName; -- book and dissertation
else -- cite thesis
OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:dissertation"; -- dissertation metadata identifier
OCinSoutput["rft.title"] = data.Title; -- dissertation (also patent but that is not yet supported)
OCinSoutput["rft.degree"] = data.Degree; -- dissertation only
OCinSoutput['rft.inst'] = data.PublisherName; -- book and dissertation
end
-- NB. Not currently supported are "info:ofi/fmt:kev:mtx:patent", "info:ofi/fmt:kev:mtx:dc", "info:ofi/fmt:kev:mtx:sch_svc", "info:ofi/fmt:kev:mtx:ctx"
-- and now common parameters (as much as possible)
OCinSoutput["rft.date"] = data.Date; -- book, journal, dissertation
for k, v in pairs( data.ID_list ) do -- what to do about these? For now assume that they are common to all?
if k == 'ISBN' then v = v:gsub( "[^-0-9X]", "" ); end
local id = cfg.id_handlers[k].COinS;
if string.sub( id or "", 1, 4 ) == 'info' then -- for ids that are in the info:registry
OCinSoutput["rft_id"] = table.concat{ id, "/", v };
elseif string.sub (id or "", 1, 3 ) == 'rft' then -- for isbn, issn, eissn, etc. that have defined COinS keywords
OCinSoutput[ id ] = v;
elseif 'url' == id then -- for urls that are assembled in ~/Identifiers; |asin= and |ol=
OCinSoutput["rft_id"] = table.concat ({data.ID_list[k], "#id-name=", cfg.id_handlers[k].label});
elseif id then -- when cfg.id_handlers[k].COinS is not nil so urls created here
OCinSoutput["rft_id"] = table.concat{ cfg.id_handlers[k].prefix, v, cfg.id_handlers[k].suffix or '', "#id-name=", cfg.id_handlers[k].label }; -- others; provide a URL and indicate identifier name as #fragment (human-readable, but transparent to browsers)
end
end
local last, first;
for k, v in ipairs( data.Authors ) do
last, first = coins_cleanup (v.last), coins_cleanup (v.first or ''); -- replace any nowiki stripmarkers, non-printing or invisible characters
if k == 1 then -- for the first author name only
if is_set(last) and is_set(first) then -- set these COinS values if |first= and |last= specify the first author name
OCinSoutput["rft.aulast"] = last; -- book, journal, dissertation
OCinSoutput["rft.aufirst"] = first; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation -- otherwise use this form for the first name
end
else -- for all other authors
if is_set(last) and is_set(first) then
OCinSoutput["rft.au"] = table.concat{ last, ", ", first }; -- book, journal, dissertation
elseif is_set(last) then
OCinSoutput["rft.au"] = last; -- book, journal, dissertation
end
-- TODO: At present we do not report "et al.". Add anything special if this condition applies?
end
end
OCinSoutput.rft_id = data.URL;
OCinSoutput.rfr_id = table.concat{ "info:sid/", string.match (mw.site.server, "[^/]*$" ), ":", data.RawPage };
-- TODO: Add optional extra info:
-- rfr_dat=#REVISION<version> (referrer private data)
-- ctx_id=<data.RawPage>#<ref> (identifier for the context object)
-- ctx_tim=<ts> (timestamp in format yyyy-mm-ddThh:mm:ssTZD or yyyy-mm-dd)
-- ctx_enc=info:ofi/enc:UTF-8 (character encoding)
OCinSoutput = setmetatable( OCinSoutput, nil );
-- sort with version string always first, and combine.
-- table.sort( OCinSoutput );
table.insert( OCinSoutput, 1, "ctx_ver=" .. ctx_ver ); -- such as "Z39.88-2004"
return table.concat(OCinSoutput, "&");
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table and imported functions table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr)
cfg = cfg_table_ptr;
has_accept_as_written = utilities_page_ptr.has_accept_as_written; -- import functions from selected Module:Citation/CS1/Utilities module
is_set = utilities_page_ptr.is_set;
in_array = utilities_page_ptr.in_array;
remove_wiki_link = utilities_page_ptr.remove_wiki_link;
strip_apostrophe_markup = utilities_page_ptr.strip_apostrophe_markup;
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
make_coins_title = make_coins_title,
get_coins_pages = get_coins_pages,
COinS = COinS,
set_selected_modules = set_selected_modules,
}
c3cf0jrk7cgctay7otxhzxbnb7fbxol
Module:Navbox/styles.css
828
12955
124183
116756
2026-09-27T20:46:50Z
en>Izno
0
please test and verify your changes before adding to a page deployed this far. notably, your large copy-paste error here
116755
sanitized-css
text/css
/* {{pp|small=y}} */
.navbox {
box-sizing: border-box;
border: 1px solid #a2a9b1;
width: 100%;
clear: both;
font-size: 88%;
text-align: center;
padding: 1px;
margin: 1em auto 0; /* Prevent preceding content from clinging to navboxes */
}
.navbox .navbox {
margin-top: 0; /* No top margin for nested navboxes */
}
.navbox + .navbox-styles + .navbox,
/* category positions are wrapped in an "empty" span in Parsoid [[phab:T378906]] */
.navbox + span.mw-empty-elt + .navbox-styles + .navbox {
margin-top: -1px; /* Single pixel border between adjacent navboxes */
}
.navbox-inner,
.navbox-subgroup {
width: 100%;
}
.navbox-group,
.navbox-title,
.navbox-abovebelow {
padding: 0.25em 1em;
line-height: 1.5em;
text-align: center;
}
.navbox-group {
white-space: nowrap;
/* @noflip */
text-align: right;
}
.navbox,
.navbox-subgroup {
background-color: #fdfdfd;
color:inherit;
}
.navbox-list {
line-height: 1.5em;
border-color: #fdfdfd; /* Must match background color */
}
.navbox-list-with-group {
text-align: left;
border-left-width: 2px;
border-left-style: solid;
}
/* cell spacing for navbox cells */
/* Borders above 2nd, 3rd, etc. rows */
/* TODO: figure out how to replace tr as structure;
* with div structure it should be just a matter of first-child */
tr + tr > .navbox-abovebelow,
tr + tr > .navbox-group,
tr + tr > .navbox-image,
tr + tr > .navbox-list {
border-top: 2px solid #fdfdfd; /* Must match background color */
}
.navbox-title {
background-color: #ccf; /* Level 1 color */
color:inherit;
}
.navbox-abovebelow,
.navbox-group,
.navbox-subgroup .navbox-title {
background-color: #ddf; /* Level 2 color */
color:inherit;
}
.navbox-subgroup .navbox-group,
.navbox-subgroup .navbox-abovebelow {
background-color: #e6e6ff; /* Level 3 color */
color:inherit;
}
.navbox-even {
background-color: #f7f7f7;
color:inherit;
}
.navbox-odd {
background-color: transparent;
color:inherit;
}
/* TODO: figure out how to remove reliance on td as structure */
.navbox .hlist td dl,
.navbox .hlist td ol,
.navbox .hlist td ul,
.navbox td.hlist dl,
.navbox td.hlist ol,
.navbox td.hlist ul {
padding: 0.125em 0;
}
.navbox .navbar {
display: block;
font-size: 100%;
}
.navbox-title .navbar {
/* @noflip */
float: left;
/* @noflip */
text-align: left;
/* @noflip */
margin-right: 0.5em;
}
/** T367463 */
body.skin--responsive .navbox-image img {
max-width: none !important;
}
@media print {
body.ns-0 .navbox {
display: none !important;
}
}
ku94g873nj9xaasowc6yies69ls74c5
124184
124183
2026-11-09T20:20:39Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Navbox/styles.css]]
116755
sanitized-css
text/css
/* {{pp|small=y}} */
.navbox {
box-sizing: border-box;
border: 1px solid #a2a9b1;
width: 100%;
clear: both;
font-size: 88%;
text-align: center;
padding: 1px;
margin: 1em auto 0; /* Prevent preceding content from clinging to navboxes */
}
.navbox .navbox {
margin-top: 0; /* No top margin for nested navboxes */
}
.navbox + .navbox-styles + .navbox,
/* category positions are wrapped in an "empty" span in Parsoid [[phab:T378906]] */
.navbox + span.mw-empty-elt + .navbox-styles + .navbox {
margin-top: -1px; /* Single pixel border between adjacent navboxes */
}
.navbox-inner,
.navbox-subgroup {
width: 100%;
}
.navbox-group,
.navbox-title,
.navbox-abovebelow {
padding: 0.25em 1em;
line-height: 1.5em;
text-align: center;
}
.navbox-group {
white-space: nowrap;
/* @noflip */
text-align: right;
}
.navbox,
.navbox-subgroup {
background-color: #fdfdfd;
color:inherit;
}
.navbox-list {
line-height: 1.5em;
border-color: #fdfdfd; /* Must match background color */
}
.navbox-list-with-group {
text-align: left;
border-left-width: 2px;
border-left-style: solid;
}
/* cell spacing for navbox cells */
/* Borders above 2nd, 3rd, etc. rows */
/* TODO: figure out how to replace tr as structure;
* with div structure it should be just a matter of first-child */
tr + tr > .navbox-abovebelow,
tr + tr > .navbox-group,
tr + tr > .navbox-image,
tr + tr > .navbox-list {
border-top: 2px solid #fdfdfd; /* Must match background color */
}
.navbox-title {
background-color: #ccf; /* Level 1 color */
color:inherit;
}
.navbox-abovebelow,
.navbox-group,
.navbox-subgroup .navbox-title {
background-color: #ddf; /* Level 2 color */
color:inherit;
}
.navbox-subgroup .navbox-group,
.navbox-subgroup .navbox-abovebelow {
background-color: #e6e6ff; /* Level 3 color */
color:inherit;
}
.navbox-even {
background-color: #f7f7f7;
color:inherit;
}
.navbox-odd {
background-color: transparent;
color:inherit;
}
/* TODO: figure out how to remove reliance on td as structure */
.navbox .hlist td dl,
.navbox .hlist td ol,
.navbox .hlist td ul,
.navbox td.hlist dl,
.navbox td.hlist ol,
.navbox td.hlist ul {
padding: 0.125em 0;
}
.navbox .navbar {
display: block;
font-size: 100%;
}
.navbox-title .navbar {
/* @noflip */
float: left;
/* @noflip */
text-align: left;
/* @noflip */
margin-right: 0.5em;
}
/** T367463 */
body.skin--responsive .navbox-image img {
max-width: none !important;
}
@media print {
body.ns-0 .navbox {
display: none !important;
}
}
ku94g873nj9xaasowc6yies69ls74c5
Module:Wd
828
13418
124179
116958
2026-11-05T22:01:06Z
en>Janhrach
0
update from sandbox [[Module talk:Wd#Proposed update: customizable snak-->param rendering, related changes, misc. bugfixes]]
124179
Scribunto
text/plain
-- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]].
require("strict")
local p = {}
local module_arg = ...
local i18n
local i18nPath
local function loadI18n(aliasesP, frame)
local title
if frame then
-- current module invoked by page/template, get its title from frame
title = frame:getTitle()
else
-- current module included by other module, get its title from ...
title = module_arg
end
if not i18n then
i18nPath = title .. "/i18n"
i18n = require(i18nPath).init(aliasesP)
end
end
p.claimCommands = {
property = "property",
properties = "properties",
qualifier = "qualifier",
qualifiers = "qualifiers",
reference = "reference",
references = "references"
}
p.generalCommands = {
label = "label",
title = "title",
description = "description",
alias = "alias",
aliases = "aliases",
badge = "badge",
badges = "badges"
}
p.flags = {
linked = "linked",
short = "short",
raw = "raw",
multilanguage = "multilanguage",
unit = "unit",
-------------
preferred = "preferred",
normal = "normal",
deprecated = "deprecated",
best = "best",
future = "future",
current = "current",
former = "former",
edit = "edit",
editAtEnd = "edit@end",
mdy = "mdy",
single = "single",
sourced = "sourced"
}
p.args = {
eid = "eid",
page = "page",
date = "date",
globalSiteId = "globalSiteId"
}
local aliasesP = {
coord = "P625",
-----------------------
image = "P18",
author = "P50",
authorNameString = "P2093",
publisher = "P123",
importedFrom = "P143",
wikimediaImportURL = "P4656",
statedIn = "P248",
pages = "P304",
language = "P407",
wikimediaLanguageCode = "P424",
hasPart = "P527",
publicationDate = "P577",
startTime = "P580",
endTime = "P582",
chapter = "P792",
retrieved = "P813",
referenceURL = "P854",
sectionVerseOrParagraph = "P958",
archiveURL = "P1065",
title = "P1476",
formatterURL = "P1630",
quote = "P1683",
shortName = "P1813",
definingFormula = "P2534",
archiveDate = "P2960",
inferredFrom = "P3452",
typeOfReference = "P3865",
column = "P3903",
subjectNamedAs = "P1810",
wikidataProperty = "P1687",
publishedIn = "P1433",
lastUpdate = "P5017"
}
local aliasesQ = {
percentage = "Q11229",
prolepticJulianCalendar = "Q1985786",
citeWeb = "Q5637226",
citeQ = "Q22321052"
}
local parameters = {
property = "%p",
qualifier = "%q",
reference = "%r",
alias = "%a",
badge = "%b",
separator = "%s",
general = "%x"
}
local formats = {
property = "%p[%s][%r]",
qualifier = "%q[%s][%r]",
reference = "%r",
propertyWithQualifier = "%p[ <span style=\"font-size:85\\%\">(%q)</span>][%s][%r]",
alias = "%a[%s]",
badge = "%b[%s]"
}
local hookNames = { -- {level_1, level_2}
[parameters.property] = {"getProperty"},
[parameters.reference] = {"getReferences", "getReference"},
[parameters.qualifier] = {"getAllQualifiers"},
[parameters.qualifier.."\\d"] = {"getQualifiers", "getQualifier"},
[parameters.alias] = {"getAlias"},
[parameters.badge] = {"getBadge"}
}
-- default value objects, should NOT be mutated but instead copied
local defaultSeparators = {
["sep"] = {" "},
["sep%s"] = {","},
["sep%q"] = {"; "},
["sep%q\\d"] = {", "},
["sep%r"] = nil, -- none
["punc"] = nil -- none
}
local rankTable = {
["preferred"] = 1,
["normal"] = 2,
["deprecated"] = 3
}
local function replaceAlias(id)
if aliasesP[id] then
id = aliasesP[id]
end
return id
end
local function errorText(code, ...)
local text = i18n["errors"][code]
if arg then text = mw.ustring.format(text, unpack(arg)) end
return text
end
local function throwError(errorMessage, ...)
error(errorText(errorMessage, unpack(arg)))
end
local function replaceDecimalMark(num)
return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1)
end
local function padZeros(num, numDigits)
local numZeros
local negative = false
if num < 0 then
negative = true
num = num * -1
end
num = tostring(num)
numZeros = numDigits - num:len()
for _ = 1, numZeros do
num = "0"..num
end
if negative then
num = "-"..num
end
return num
end
local function replaceSpecialChar(chr)
if chr == '_' then
-- replace underscores with spaces
return ' '
else
return chr
end
end
local function replaceSpecialChars(str)
local chr
local esc = false
local strOut = ""
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
esc = true
else
strOut = strOut .. replaceSpecialChar(chr)
end
else
strOut = strOut .. chr
esc = false
end
end
return strOut
end
local function buildWikilink(target, label)
if not label or target == label then
return "[[" .. target .. "]]"
else
return "[[" .. target .. "|" .. label .. "]]"
end
end
-- used to make frame.args mutable, to replace #frame.args (which is always 0)
-- with the actual amount and to simply copy tables
local function copyTable(tIn)
if not tIn then
return nil
end
local tOut = {}
for i, v in pairs(tIn) do
tOut[i] = v
end
return tOut
end
-- used to merge output arrays together;
-- note that it currently mutates the first input array
local function mergeArrays(a1, a2)
for i = 1, #a2 do
a1[#a1 + 1] = a2[i]
end
return a1
end
local function split(str, del)
local out = {}
local i, j = str:find(del)
if i and j then
out[1] = str:sub(1, i - 1)
out[2] = str:sub(j + 1)
else
out[1] = str
end
return out
end
local function parseWikidataURL(url)
local id
if url:match('^http[s]?://') then
id = split(url, "Q")
if id[2] then
return "Q" .. id[2]
end
end
return nil
end
local function parseDate(dateStr, precision)
precision = precision or "d"
local i, j, index, ptr
local parts = {nil, nil, nil}
if dateStr == nil then
return parts[1], parts[2], parts[3] -- year, month, day
end
-- 'T' for snak values, '/' for outputs with '/Julian' attached
i, j = dateStr:find("[T/]")
if i then
dateStr = dateStr:sub(1, i-1)
end
local from = 1
if dateStr:sub(1,1) == "-" then
-- this is a negative number, look further ahead
from = 2
end
index = 1
ptr = 1
i, j = dateStr:find("-", from)
if i then
-- year
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) -- explicitly give base 10 to prevent error
if parts[index] == -0 then
parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead
end
if precision == "y" then
-- we're done
return parts[1], parts[2], parts[3] -- year, month, day
end
index = index + 1
ptr = i + 1
i, j = dateStr:find("-", ptr)
if i then
-- month
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)
if precision == "m" then
-- we're done
return parts[1], parts[2], parts[3] -- year, month, day
end
index = index + 1
ptr = i + 1
end
end
if dateStr:sub(ptr) ~= "" then
-- day if we have month, month if we have year, or year
parts[index] = tonumber(dateStr:sub(ptr), 10)
end
return parts[1], parts[2], parts[3] -- year, month, day
end
local function datePrecedesDate(aY, aM, aD, bY, bM, bD)
if aY == nil or bY == nil then
return nil
end
aM = aM or 1
aD = aD or 1
bM = bM or 1
bD = bD or 1
if aY < bY then
return true
end
if aY > bY then
return false
end
if aM < bM then
return true
end
if aM > bM then
return false
end
if aD < bD then
return true
end
return false
end
local function getHookName(param, index)
if hookNames[param] then
return hookNames[param][index]
elseif param:len() > 2 then
return hookNames[param:sub(1, 2).."\\d"][index]
else
return nil
end
end
local function alwaysTrue()
return true
end
-- The following function parses a format string.
--
-- The example below shows how a parsed string is structured in memory.
-- Variables other than 'str' and 'child' are left out for clarity's sake.
--
-- Example:
-- "A %p B [%s[%q1]] C [%r] D"
--
-- Structure:
-- [
-- {
-- str = "A "
-- },
-- {
-- str = "%p"
-- },
-- {
-- str = " B ",
-- child =
-- [
-- {
-- str = "%s",
-- child =
-- [
-- {
-- str = "%q1"
-- }
-- ]
-- }
-- ]
-- },
-- {
-- str = " C ",
-- child =
-- [
-- {
-- str = "%r"
-- }
-- ]
-- },
-- {
-- str = " D"
-- }
-- ]
--
local function parseFormat(str)
local chr, esc, param, root, cur, prev, new
local params = {}
local function newObject(array)
local obj = {} -- new object
obj.str = ""
array[#array + 1] = obj -- array{object}
obj.parent = array
return obj
end
local function endParam()
if param > 0 then
if cur.str ~= "" then
cur.str = "%"..cur.str
cur.param = true
params[cur.str] = true
cur.parent.req[cur.str] = true
prev = cur
cur = newObject(cur.parent)
end
param = 0
end
end
root = {} -- array
root.req = {}
cur = newObject(root)
prev = nil
esc = false
param = 0
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
endParam()
esc = true
elseif chr == '%' then
endParam()
if cur.str ~= "" then
cur = newObject(cur.parent)
end
param = 2
elseif chr == '[' then
endParam()
if prev and cur.str == "" then
table.remove(cur.parent)
cur = prev
end
cur.child = {} -- new array
cur.child.req = {}
cur.child.parent = cur
cur = newObject(cur.child)
elseif chr == ']' then
endParam()
if cur.parent.parent then
new = newObject(cur.parent.parent.parent)
if cur.str == "" then
table.remove(cur.parent)
end
cur = new
end
else
if param > 1 then
param = param - 1
elseif param == 1 then
if not chr:match('%d') then
endParam()
end
end
cur.str = cur.str .. replaceSpecialChar(chr)
end
else
cur.str = cur.str .. chr
esc = false
end
prev = nil
end
endParam()
-- make sure that at least one required parameter has been defined
if not next(root.req) then
throwError("missing-required-parameter")
end
-- make sure that the separator parameter "%s" is not amongst the required parameters
if root.req[parameters.separator] then
throwError("extra-required-parameter", parameters.separator)
end
return root, params
end
local function sortOnRank(claims)
local rankPos
local ranks = {{}, {}, {}, {}} -- preferred, normal, deprecated, (default)
local sorted = {}
for _, v in ipairs(claims) do
rankPos = rankTable[v.rank] or 4
ranks[rankPos][#ranks[rankPos] + 1] = v
end
sorted = ranks[1]
sorted = mergeArrays(sorted, ranks[2])
sorted = mergeArrays(sorted, ranks[3])
return sorted
end
local function isValueInTable(searchedItem, inputTable)
for _, item in pairs(inputTable) do
if item == searchedItem then
return true
end
end
return false
end
local Config = {}
-- allows for recursive calls
function Config:new()
local cfg = {}
setmetatable(cfg, self)
self.__index = self
cfg.separators = {
-- single value objects wrapped in arrays so that we can pass by reference
["sep"] = {copyTable(defaultSeparators["sep"])},
["sep%s"] = {copyTable(defaultSeparators["sep%s"])},
["sep%q"] = {copyTable(defaultSeparators["sep%q"])},
["sep%r"] = {copyTable(defaultSeparators["sep%r"])},
["punc"] = {copyTable(defaultSeparators["punc"])}
}
cfg.entity = nil
cfg.entityID = nil
cfg.propertyID = nil
cfg.propertyValue = nil
cfg.qualifierIDs = {}
cfg.qualifierIDsAndValues = {}
cfg.bestRank = true
cfg.ranks = {true, true, false} -- preferred = true, normal = true, deprecated = false
cfg.foundRank = #cfg.ranks
cfg.flagBest = false
cfg.flagRank = false
cfg.periods = {true, true, true} -- future = true, current = true, former = true
cfg.flagPeriod = false
cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))} -- today as {year, month, day}
cfg.mdyDate = false
cfg.singleClaim = false
cfg.sourcedOnly = false
cfg.editable = false
cfg.editAtEnd = false
cfg.inSitelinks = false
cfg.langCode = mw.language.getContentLanguage().code
cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode)
cfg.langObj = mw.language.new(cfg.langCode)
cfg.siteID = mw.wikibase.getGlobalSiteId()
cfg.states = {}
cfg.states.qualifiersCount = 0
cfg.curState = nil
cfg.prefetchedRefs = nil
return cfg
end
local State = {}
function State:new(cfg, type)
local stt = {}
setmetatable(stt, self)
self.__index = self
stt.conf = cfg
stt.type = type
stt.results = {}
stt.parsedFormat = {}
stt.separator = {}
stt.movSeparator = {}
stt.puncMark = {}
stt.linked = false
stt.rawValue = false
stt.shortName = false
stt.anyLanguage = false
stt.unitOnly = false
stt.singleValue = false
return stt
end
-- if id == nil then item connected to current page is used
function Config:getLabel(id, raw, link, short)
local label = nil
local prefix, title= "", nil
if not id then
id = mw.wikibase.getEntityIdForCurrentPage()
if not id then
return ""
end
end
id = id:upper() -- just to be sure
if raw then
-- check if given id actually exists
if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then
label = id
end
prefix, title = "d:Special:EntityPage/", label -- may be nil
else
-- try short name first if requested
if short then
label = p._property{aliasesP.shortName, [p.args.eid] = id} -- get short name
if label == "" then
label = nil
end
end
-- get label
if not label then
label = mw.wikibase.getLabel(id)
end
end
if not label then
label = ""
elseif link then
-- build a link if requested
if not title then
if id:sub(1,1) == "Q" then
title = mw.wikibase.getSitelink(id)
elseif id:sub(1,1) == "P" then
-- properties have no sitelink, link to Wikidata instead
prefix, title = "d:Special:EntityPage/", id
end
end
label = mw.text.nowiki(label) -- escape raw label text so it cannot be wikitext markup
if title then
label = buildWikilink(prefix .. title, label)
end
end
return label
end
function Config:getEditIcon()
local value = ""
local prefix = ""
local front = " "
local back = ""
if self.entityID:sub(1,1) == "P" then
prefix = "Property:"
end
if self.editAtEnd then
front = '<span style="float:'
if self.langObj:isRTL() then
front = front .. 'left'
else
front = front .. 'right'
end
front = front .. '">'
back = '</span>'
end
value = "[[File:OOjs UI icon edit-ltr-progressive.svg|frameless|text-top|10px|alt=" .. i18n['info']['edit-on-wikidata'] .. "|link=https://www.wikidata.org/wiki/" .. prefix .. self.entityID .. "?uselang=" .. self.langCode
if self.propertyID then
value = value .. "#" .. self.propertyID
elseif self.inSitelinks then
value = value .. "#sitelinks-wikipedia"
end
value = value .. "|" .. i18n['info']['edit-on-wikidata'] .. "]]"
return front .. value .. back
end
-- used to create the final output string when it's all done, so that for references the
-- function extensionTag("ref", ...) is only called when they really ended up in the final output
function Config:concatValues(valuesArray)
local outString = ""
local j, skip
for i = 1, #valuesArray do
-- check if this is a reference
if valuesArray[i].refHash then
j = i - 1
skip = false
-- skip this reference if it is part of a continuous row of references that already contains the exact same reference
while valuesArray[j] and valuesArray[j].refHash do
if valuesArray[i].refHash == valuesArray[j].refHash then
skip = true
break
end
j = j - 1
end
if not skip then
-- add <ref> tag with the reference's hash as its name (to deduplicate references)
outString = outString .. mw.getCurrentFrame():extensionTag("ref", valuesArray[i][1], {name = valuesArray[i].refHash})
end
else
outString = outString .. valuesArray[i][1]
end
end
return outString
end
function Config:convertUnit(unit, raw, link, short, unitOnly)
local space = " "
local label = ""
local itemID
if unit == "" or unit == "1" then
return nil
end
if unitOnly then
space = ""
end
itemID = parseWikidataURL(unit)
if itemID then
if itemID == aliasesQ.percentage then
return "%"
else
label = self:getLabel(itemID, raw, link, short)
if label ~= "" then
return space .. label
end
end
end
return ""
end
function State:getValue(snak)
return self.conf:getValue(snak, self.rawValue, self.linked, self.shortName, self.anyLanguage, self.unitOnly, false, self.type:sub(1,2))
end
function Config:getValue(snak, raw, link, short, anyLang, unitOnly, noSpecial, type)
if snak.snaktype == 'value' then
local datatype = snak.datavalue.type
local subtype = snak.datatype
local datavalue = snak.datavalue.value
if datatype == 'string' then
if subtype == 'url' and link then
-- create link explicitly
if raw then
-- will render as a linked number like [1]
return "[" .. datavalue .. "]"
else
return "[" .. datavalue .. " " .. datavalue .. "]"
end
elseif subtype == 'commonsMedia' then
if link then
return buildWikilink("c:File:" .. datavalue, datavalue)
elseif not raw then
return "[[File:" .. datavalue .. "]]"
else
return datavalue
end
elseif subtype == 'geo-shape' and link then
return buildWikilink("c:" .. datavalue, datavalue)
elseif subtype == 'math' and not raw then
local attribute = nil
if (type == parameters.property or (type == parameters.qualifier and self.propertyID == aliasesP.hasPart)) and snak.property == aliasesP.definingFormula then
attribute = {qid = self.entityID}
end
return mw.getCurrentFrame():extensionTag("math", datavalue, attribute)
elseif subtype == 'external-id' and link then
local url = p._property{p.flags.raw, aliasesP.formatterURL, [p.args.eid] = snak.property} -- get formatter URL
if url ~= "" then
url = mw.ustring.gsub(url, "$1", datavalue)
return "[" .. url .. " " .. datavalue .. "]"
else
return datavalue
end
else
return datavalue
end
elseif datatype == 'monolingualtext' then
if anyLang or datavalue['language'] == self.langCode then
return datavalue['text']
else
return nil
end
elseif datatype == 'quantity' then
local value = ""
local unit
if not unitOnly then
-- get value and strip + signs from front
value = mw.ustring.gsub(datavalue['amount'], "^%+(.+)$", "%1")
if raw then
return value
end
-- replace decimal mark based on locale
value = replaceDecimalMark(value)
-- add delimiters for readability
value = i18n.addDelimiters(value)
end
unit = self:convertUnit(datavalue['unit'], raw, link, short, unitOnly)
if unit then
value = value .. unit
end
return value
elseif datatype == 'time' then
local y, m, d, p, yDiv, yRound, yFull, value, calendarID, dateStr
local yFactor = 1
local sign = 1
local prefix = ""
local suffix = ""
local mayAddCalendar = false
local calendar = ""
local precision = datavalue['precision']
if precision == 11 then
p = "d"
elseif precision == 10 then
p = "m"
else
p = "y"
yFactor = 10^(9-precision)
end
y, m, d = parseDate(datavalue['time'], p)
if y < 0 then
sign = -1
y = y * sign
end
-- if precision is tens/hundreds/thousands/millions/billions of years
if precision <= 8 then
yDiv = y / yFactor
-- if precision is tens/hundreds/thousands of years
if precision >= 6 then
mayAddCalendar = true
if precision <= 7 then
-- round centuries/millenniums up (e.g. 20th century or 3rd millennium)
yRound = math.ceil(yDiv)
if not raw then
if precision == 6 then
suffix = i18n['datetime']['suffixes']['millennium']
else
suffix = i18n['datetime']['suffixes']['century']
end
suffix = i18n.getOrdinalSuffix(yRound) .. suffix
else
-- if not verbose, take the first year of the century/millennium
-- (e.g. 1901 for 20th century or 2001 for 3rd millennium)
yRound = (yRound - 1) * yFactor + 1
end
else
-- precision == 8
-- round decades down (e.g. 2010s)
yRound = math.floor(yDiv) * yFactor
if not raw then
prefix = i18n['datetime']['prefixes']['decade-period']
suffix = i18n['datetime']['suffixes']['decade-period']
end
end
if raw and sign < 0 then
-- if BCE then compensate for "counting backwards"
-- (e.g. -2019 for 2010s BCE, -2000 for 20th century BCE or -3000 for 3rd millennium BCE)
yRound = yRound + yFactor - 1
end
else
local yReFactor, yReDiv, yReRound
-- round to nearest for tens of thousands of years or more
yRound = math.floor(yDiv + 0.5)
if yRound == 0 then
if precision <= 2 and y ~= 0 then
yReFactor = 1e6
yReDiv = y / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to millions of years only if we have a whole number of them
precision = 3
yFactor = yReFactor
yRound = yReRound
end
end
if yRound == 0 then
-- otherwise, take the unrounded (original) number of years
precision = 5
yFactor = 1
yRound = y
mayAddCalendar = true
end
end
if precision >= 1 and y ~= 0 then
yFull = yRound * yFactor
yReFactor = 1e9
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to billions of years if we're in that range
precision = 0
yFactor = yReFactor
yRound = yReRound
else
yReFactor = 1e6
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to millions of years if we're in that range
precision = 3
yFactor = yReFactor
yRound = yReRound
end
end
end
if not raw then
if precision == 3 then
suffix = i18n['datetime']['suffixes']['million-years']
elseif precision == 0 then
suffix = i18n['datetime']['suffixes']['billion-years']
else
yRound = yRound * yFactor
if yRound == 1 then
suffix = i18n['datetime']['suffixes']['year']
else
suffix = i18n['datetime']['suffixes']['years']
end
end
else
yRound = yRound * yFactor
end
end
else
yRound = y
mayAddCalendar = true
end
if mayAddCalendar then
calendarID = parseWikidataURL(datavalue['calendarmodel'])
if calendarID and calendarID == aliasesQ.prolepticJulianCalendar then
if not raw then
if link then
calendar = " ("..buildWikilink(i18n['datetime']['julian-calendar'], i18n['datetime']['julian'])..")"
else
calendar = " ("..i18n['datetime']['julian']..")"
end
else
calendar = "/"..i18n['datetime']['julian']
end
end
end
if not raw then
local ce = nil
if sign < 0 then
ce = i18n['datetime']['BCE']
elseif precision <= 5 then
ce = i18n['datetime']['CE']
end
if ce then
if link then
ce = buildWikilink(i18n['datetime']['common-era'], ce)
end
suffix = suffix .. " " .. ce
end
value = tostring(yRound)
if m then
dateStr = self.langObj:formatDate("F", "1-"..m.."-1")
if d then
if self.mdyDate then
dateStr = dateStr .. " " .. d .. ","
else
dateStr = d .. " " .. dateStr
end
end
value = dateStr .. " " .. value
end
value = prefix .. value .. suffix .. calendar
else
value = padZeros(yRound * sign, 4)
if m then
value = value .. "-" .. padZeros(m, 2)
if d then
value = value .. "-" .. padZeros(d, 2)
end
end
value = value .. calendar
end
return value
elseif datatype == 'globecoordinate' then
-- logic from https://github.com/DataValues/Geo (v4.0.1)
local precision, unitsPerDegree, numDigits, strFormat, value, globe
local latitude, latConv, latValue, latLink
local longitude, lonConv, lonValue, lonLink
local latDirection, latDirectionN, latDirectionS, latDirectionEN
local lonDirection, lonDirectionE, lonDirectionW, lonDirectionEN
local degSymbol, minSymbol, secSymbol, separator
local latDegrees = nil
local latMinutes = nil
local latSeconds = nil
local lonDegrees = nil
local lonMinutes = nil
local lonSeconds = nil
local latDegSym = ""
local latMinSym = ""
local latSecSym = ""
local lonDegSym = ""
local lonMinSym = ""
local lonSecSym = ""
local latDirectionEN_N = "N"
local latDirectionEN_S = "S"
local lonDirectionEN_E = "E"
local lonDirectionEN_W = "W"
if not raw then
latDirectionN = i18n['coord']['latitude-north']
latDirectionS = i18n['coord']['latitude-south']
lonDirectionE = i18n['coord']['longitude-east']
lonDirectionW = i18n['coord']['longitude-west']
degSymbol = i18n['coord']['degrees']
minSymbol = i18n['coord']['minutes']
secSymbol = i18n['coord']['seconds']
separator = i18n['coord']['separator']
else
latDirectionN = latDirectionEN_N
latDirectionS = latDirectionEN_S
lonDirectionE = lonDirectionEN_E
lonDirectionW = lonDirectionEN_W
degSymbol = "/"
minSymbol = "/"
secSymbol = "/"
separator = "/"
end
latitude = datavalue['latitude']
longitude = datavalue['longitude']
if latitude < 0 then
latDirection = latDirectionS
latDirectionEN = latDirectionEN_S
latitude = math.abs(latitude)
else
latDirection = latDirectionN
latDirectionEN = latDirectionEN_N
end
if longitude < 0 then
lonDirection = lonDirectionW
lonDirectionEN = lonDirectionEN_W
longitude = math.abs(longitude)
else
lonDirection = lonDirectionE
lonDirectionEN = lonDirectionEN_E
end
precision = datavalue['precision']
if not precision or precision <= 0 then
precision = 1 / 3600 -- precision not set (correctly), set to arcsecond
end
-- remove insignificant detail
latitude = math.floor(latitude / precision + 0.5) * precision
longitude = math.floor(longitude / precision + 0.5) * precision
if precision >= 1 - (1 / 60) and precision < 1 then
precision = 1
elseif precision >= (1 / 60) - (1 / 3600) and precision < (1 / 60) then
precision = 1 / 60
end
if precision >= 1 then
unitsPerDegree = 1
elseif precision >= (1 / 60) then
unitsPerDegree = 60
else
unitsPerDegree = 3600
end
numDigits = math.ceil(-math.log10(unitsPerDegree * precision))
if numDigits <= 0 then
numDigits = tonumber("0") -- for some reason, 'numDigits = 0' may actually store '-0', so parse from string instead
end
strFormat = "%." .. numDigits .. "f"
if precision >= 1 then
latDegrees = strFormat:format(latitude)
lonDegrees = strFormat:format(longitude)
if not raw then
latDegSym = replaceDecimalMark(latDegrees) .. degSymbol
lonDegSym = replaceDecimalMark(lonDegrees) .. degSymbol
else
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol
end
else
latConv = math.floor(latitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
lonConv = math.floor(longitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
if precision >= (1 / 60) then
latMinutes = latConv
lonMinutes = lonConv
else
latSeconds = latConv
lonSeconds = lonConv
latMinutes = math.floor(latSeconds / 60)
lonMinutes = math.floor(lonSeconds / 60)
latSeconds = strFormat:format(latSeconds - (latMinutes * 60))
lonSeconds = strFormat:format(lonSeconds - (lonMinutes * 60))
if not raw then
latSecSym = replaceDecimalMark(latSeconds) .. secSymbol
lonSecSym = replaceDecimalMark(lonSeconds) .. secSymbol
else
latSecSym = latSeconds .. secSymbol
lonSecSym = lonSeconds .. secSymbol
end
end
latDegrees = math.floor(latMinutes / 60)
lonDegrees = math.floor(lonMinutes / 60)
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol
latMinutes = latMinutes - (latDegrees * 60)
lonMinutes = lonMinutes - (lonDegrees * 60)
if precision >= (1 / 60) then
latMinutes = strFormat:format(latMinutes)
lonMinutes = strFormat:format(lonMinutes)
if not raw then
latMinSym = replaceDecimalMark(latMinutes) .. minSymbol
lonMinSym = replaceDecimalMark(lonMinutes) .. minSymbol
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
end
latValue = latDegSym .. latMinSym .. latSecSym .. latDirection
lonValue = lonDegSym .. lonMinSym .. lonSecSym .. lonDirection
value = latValue .. separator .. lonValue
if link then
globe = parseWikidataURL(datavalue['globe'])
if globe then
globe = mw.wikibase.getLabelByLang(globe, "en"):lower()
else
globe = "earth"
end
latLink = table.concat({latDegrees, latMinutes, latSeconds}, "_")
lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_")
value = "[https://geohack.toolforge.org/geohack.php?language="..self.langCode.."¶ms="..latLink.."_"..latDirectionEN.."_"..lonLink.."_"..lonDirectionEN.."_globe:"..globe.." "..value.."]"
end
return value
elseif datatype == 'wikibase-entityid' then
local label
local itemID = datavalue['numeric-id']
if subtype == 'wikibase-item' then
itemID = "Q" .. itemID
elseif subtype == 'wikibase-property' then
itemID = "P" .. itemID
else
return '<strong class="error">' .. errorText('unknown-data-type', subtype) .. '</strong>'
end
label = self:getLabel(itemID, raw, link, short)
if label == "" then
label = nil
end
return label
else
return '<strong class="error">' .. errorText('unknown-data-type', datatype) .. '</strong>'
end
elseif snak.snaktype == 'somevalue' and not noSpecial then
if raw then
return " " -- single space represents 'somevalue'
else
return i18n['values']['unknown']
end
elseif snak.snaktype == 'novalue' and not noSpecial then
if raw then
return "" -- empty string represents 'novalue'
else
return i18n['values']['none']
end
else
return nil
end
end
function Config:getSingleRawQualifier(claim, qualifierID)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[qualifierID] end
if qualifiers and qualifiers[1] then
return self:getValue(qualifiers[1], true) -- raw = true
else
return nil
end
end
function Config:snakEqualsValue(snak, value)
local snakValue = self:getValue(snak, true) -- raw = true
if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper() end
return snakValue == value
end
function Config:setRank(rank)
local rankPos
if rank == p.flags.best then
self.bestRank = true
self.flagBest = true -- mark that 'best' flag was given
return
end
if rank:sub(1,9) == p.flags.preferred then
rankPos = 1
elseif rank:sub(1,6) == p.flags.normal then
rankPos = 2
elseif rank:sub(1,10) == p.flags.deprecated then
rankPos = 3
else
return
end
-- one of the rank flags was given, check if another one was given before
if not self.flagRank then
self.ranks = {false, false, false} -- no other rank flag given before, so unset ranks
self.bestRank = self.flagBest -- unsets bestRank only if 'best' flag was not given before
self.flagRank = true -- mark that a rank flag was given
end
if rank:sub(-1) == "+" then
for i = rankPos, 1, -1 do
self.ranks[i] = true
end
elseif rank:sub(-1) == "-" then
for i = rankPos, #self.ranks do
self.ranks[i] = true
end
else
self.ranks[rankPos] = true
end
end
function Config:setPeriod(period)
local periodPos
if period == p.flags.future then
periodPos = 1
elseif period == p.flags.current then
periodPos = 2
elseif period == p.flags.former then
periodPos = 3
else
return
end
-- one of the period flags was given, check if another one was given before
if not self.flagPeriod then
self.periods = {false, false, false} -- no other period flag given before, so unset periods
self.flagPeriod = true -- mark that a period flag was given
end
self.periods[periodPos] = true
end
function Config:qualifierMatches(claim, id, value)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[id] end
if qualifiers then
for _, v in pairs(qualifiers) do
if self:snakEqualsValue(v, value) then
return true
end
end
elseif value == "" then
-- if the qualifier is not present then treat it the same as the special value 'novalue'
return true
end
return false
end
function Config:rankMatches(rankPos)
if self.bestRank then
return (self.ranks[rankPos] and self.foundRank >= rankPos)
else
return self.ranks[rankPos]
end
end
function Config:timeMatches(claim)
local startTime = nil
local startTimeY = nil
local startTimeM = nil
local startTimeD = nil
local endTime = nil
local endTimeY = nil
local endTimeM = nil
local endTimeD = nil
if self.periods[1] and self.periods[2] and self.periods[3] then
-- any time
return true
end
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
if startTime and startTime ~= "" and startTime ~= " " then
startTimeY, startTimeM, startTimeD = parseDate(startTime)
end
endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
if endTime and endTime ~= "" and endTime ~= " " then
endTimeY, endTimeM, endTimeD = parseDate(endTime)
end
if startTimeY ~= nil and endTimeY ~= nil and datePrecedesDate(endTimeY, endTimeM, endTimeD, startTimeY, startTimeM, startTimeD) then
-- invalidate end time if it precedes start time
endTimeY = nil
endTimeM = nil
endTimeD = nil
end
if self.periods[1] then
-- future
if startTimeY and datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD) then
return true
end
end
if self.periods[2] then
-- current
if (startTimeY == nil or not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD)) and
(endTimeY == nil or datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD)) then
return true
end
end
if self.periods[3] then
-- former
if endTimeY and not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD) then
return true
end
end
return false
end
function Config:processFlag(flag)
if not flag then
return false
end
if flag == p.flags.linked then
self.curState.linked = true
return true
elseif flag == p.flags.raw then
self.curState.rawValue = true
if self.curState == self.states[parameters.reference] then
-- raw reference values end with periods and require a separator (other than none)
self.separators["sep%r"][1] = {" "}
end
return true
elseif flag == p.flags.short then
self.curState.shortName = true
return true
elseif flag == p.flags.multilanguage then
self.curState.anyLanguage = true
return true
elseif flag == p.flags.unit then
self.curState.unitOnly = true
return true
elseif flag == p.flags.mdy then
self.mdyDate = true
return true
elseif flag == p.flags.single then
self.singleClaim = true
return true
elseif flag == p.flags.sourced then
self.sourcedOnly = true
return true
elseif flag == p.flags.edit then
self.editable = true
return true
elseif flag == p.flags.editAtEnd then
self.editable = true
self.editAtEnd = true
return true
elseif flag == p.flags.best or flag:match('^'..p.flags.preferred..'[+-]?$') or flag:match('^'..p.flags.normal..'[+-]?$') or flag:match('^'..p.flags.deprecated..'[+-]?$') then
self:setRank(flag)
return true
elseif flag == p.flags.future or flag == p.flags.current or flag == p.flags.former then
self:setPeriod(flag)
return true
elseif flag == "" then
-- ignore empty flags and carry on
return true
else
return false
end
end
function Config:processFlagOrCommand(flag)
local param = ""
if not flag then
return false
end
if flag == p.claimCommands.property or flag == p.claimCommands.properties then
param = parameters.property
elseif flag == p.claimCommands.qualifier or flag == p.claimCommands.qualifiers then
self.states.qualifiersCount = self.states.qualifiersCount + 1
param = parameters.qualifier .. self.states.qualifiersCount
self.separators["sep"..param] = {copyTable(defaultSeparators["sep%q\\d"])}
elseif flag == p.claimCommands.reference or flag == p.claimCommands.references then
param = parameters.reference
else
return self:processFlag(flag)
end
if self.states[param] then
return false
end
-- create a new state for each command
self.states[param] = State:new(self, param)
-- use "%x" as the general parameter name
self.states[param].parsedFormat = parseFormat(parameters.general) -- will be overwritten for param=="%p"
-- set the separator
self.states[param].separator = self.separators["sep"..param] -- will be nil for param=="%p", which will be set separately
if flag == p.claimCommands.property or flag == p.claimCommands.qualifier or flag == p.claimCommands.reference then
self.states[param].singleValue = true
end
self.curState = self.states[param]
return true
end
function Config:processSeparators(args)
local sep
for i, v in pairs(self.separators) do
if args[i] then
sep = replaceSpecialChars(args[i])
if sep ~= "" then
self.separators[i][1] = {sep}
else
self.separators[i][1] = nil
end
end
end
end
function Config:setFormatAndSeparators(state, parsedFormat)
state.parsedFormat = parsedFormat
state.separator = self.separators["sep"]
state.movSeparator = self.separators["sep"..parameters.separator]
state.puncMark = self.separators["punc"]
end
-- determines if a claim has references by prefetching them from the claim using getReferences,
-- which applies some filtering that determines if a reference is actually returned,
-- and caches the references for later use
function State:isSourced(claim)
self.conf.prefetchedRefs = self:getReferences(claim)
return (#self.conf.prefetchedRefs > 0)
end
function State:resetCaches()
-- any prefetched references of the previous claim must not be used
self.conf.prefetchedRefs = nil
end
function State:claimMatches(claim)
local matches, rankPos
-- first of all, reset any cached values used for the previous claim
self:resetCaches()
-- if a property value was given, check if it matches the claim's property value
if self.conf.propertyValue then
matches = self.conf:snakEqualsValue(claim.mainsnak, self.conf.propertyValue)
else
matches = true
end
-- if any qualifier values were given, check if each matches one of the claim's qualifier values
for i, v in pairs(self.conf.qualifierIDsAndValues) do
matches = (matches and self.conf:qualifierMatches(claim, i, v))
end
-- check if the claim's rank and time period match
rankPos = rankTable[claim.rank] or 4
matches = (matches and self.conf:rankMatches(rankPos) and self.conf:timeMatches(claim))
-- if only claims with references must be returned, check if this one has any
if self.conf.sourcedOnly then
matches = (matches and self:isSourced(claim)) -- prefetches and caches references
end
return matches, rankPos
end
function State:out()
local result -- collection of arrays with value objects
local valuesArray -- array with value objects
local sep = nil -- value object
local out = {} -- array with value objects
local function walk(formatTable, result)
local valuesArray = {} -- array with value objects
for i, v in pairs(formatTable.req) do
if not result[i] or not result[i][1] then
-- we've got no result for a parameter that is required on this level,
-- so skip this level (and its children) by returning an empty result
return {}
end
end
for _, v in ipairs(formatTable) do
if v.param then
valuesArray = mergeArrays(valuesArray, result[v.str])
elseif v.str ~= "" then
valuesArray[#valuesArray + 1] = {v.str}
end
if v.child then
valuesArray = mergeArrays(valuesArray, walk(v.child, result))
end
end
return valuesArray
end
-- iterate through the results from back to front, so that we know when to add separators
for i = #self.results, 1, -1 do
result = self.results[i]
-- if there is already some output, then add the separators
if #out > 0 then
sep = self.separator[1] -- fixed separator
result[parameters.separator] = {self.movSeparator[1]} -- movable separator
else
sep = nil
result[parameters.separator] = {self.puncMark[1]} -- optional punctuation mark
end
valuesArray = walk(self.parsedFormat, result)
if #valuesArray > 0 then
if sep then
valuesArray[#valuesArray + 1] = sep
end
out = mergeArrays(valuesArray, out)
end
end
-- reset state before next iteration
self.results = {}
return out
end
-- level 1 hook
function State:getProperty(claim)
local value = {self:getValue(claim.mainsnak)} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getQualifiers(claim, param)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[self.conf.qualifierIDs[param]] end
if qualifiers then
-- iterate through claim's qualifier statements to collect their values;
-- return array with multiple value objects
return self.conf.states[param]:iterate(qualifiers, {[parameters.general] = hookNames[parameters.qualifier.."\\d"][2], count = 1}) -- pass qualifier state with level 2 hook
else
return {} -- return empty array
end
end
-- level 2 hook
function State:getQualifier(snak)
local value = {self:getValue(snak)} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getAllQualifiers(claim, param, result, hooks)
local out = {} -- array with value objects
local sep = self.conf.separators["sep"..parameters.qualifier][1] -- value object
-- iterate through the output of the separate "qualifier(s)" commands
for i = 1, self.conf.states.qualifiersCount do
-- if a hook has not been called yet, call it now
if not result[parameters.qualifier..i] then
self:callHook(parameters.qualifier..i, hooks, claim, result)
end
-- if there is output for this particular "qualifier(s)" command, then add it
if result[parameters.qualifier..i] and result[parameters.qualifier..i][1] then
-- if there is already some output, then add the separator
if #out > 0 and sep then
out[#out + 1] = sep
end
out = mergeArrays(out, result[parameters.qualifier..i])
end
end
return out
end
-- level 1 hook
function State:getReferences(claim)
if self.conf.prefetchedRefs then
-- return references that have been prefetched by isSourced
return self.conf.prefetchedRefs
end
if claim.references then
-- iterate through claim's reference statements to collect their values;
-- return array with multiple value objects
return self.conf.states[parameters.reference]:iterate(claim.references, {[parameters.general] = hookNames[parameters.reference][2], count = 1}) -- pass reference state with level 2 hook
else
return {} -- return empty array
end
end
-- level 2 hook
function State:getReference(statement)
local citeParamMapping = i18n['cite']['param-mapping']
local citeConfig = i18n['cite']['config']
local citeTypes = i18n['cite']['output-types']
-- for each citation type, there will be an associative array that associates lists of rendered properties
-- to citation-template parameters
local candidateParams = {}
-- like above, but only associates one rendered property to each parameter; if the above variable
-- contains more strings for a parameter, the strings will be assigned to numbered params (e.g. "author1")
local citeParams = {}
local citeErrors = {}
local referenceEmpty = true -- will be set to false if at least one parameter is left unremoved
local version = 13 -- increment this each time the below logic is changed to avoid conflict errors
if not statement.snaks then
return {}
end
-- don't use bot-added references referencing Wikimedia projects or containing "inferred from" (such references are not usable on Wikipedia)
if statement.snaks[aliasesP.importedFrom] or statement.snaks[aliasesP.wikimediaImportURL] or statement.snaks[aliasesP.inferredFrom] then
return {}
end
-- don't include "type of reference"
if statement.snaks[aliasesP.typeOfReference] then
statement.snaks[aliasesP.typeOfReference] = nil
end
-- don't include "image" to prevent littering
if statement.snaks[aliasesP.image] then
statement.snaks[aliasesP.image] = nil
end
-- initialize candidateParams and citeParams
for _, citeType in ipairs(citeTypes) do
candidateParams[citeType] = {}
citeParams[citeType] = {}
end
-- fill candidateParams
for _, citeType in ipairs(citeTypes) do
-- This will contain value--priority pairs for each param name.
local candidateValuesAndPriorities = {}
-- fill candidateValuesAndPriorities
for refProperty in pairs(statement.snaks) do
if citeErrors[citeType] then
break
end
repeat -- just a simple wrapper to emulate "continue"
-- set mappingKey
local mappingKey
if statement.snaks[refProperty][1].datatype == 'external-id' then
mappingKey = "external-id"
else
mappingKey = refProperty
end
local paramName = citeParamMapping[citeType][mappingKey]
-- skip properties with empty parameter name
if paramName == "" then
break -- skip this property for this value of citeType
end
-- handle unknown properties in the reference
if not paramName then
referenceEmpty = false
local propertyWikitext = "[[d:Special:EntityPage/" .. refProperty .. "|" .. self.conf:getLabel(refProperty) .. " (" .. refProperty .. ")]]"
local error_message = errorText("unknown-property-in-ref", propertyWikitext)
assert(error_message) -- Should not be nil
citeErrors[citeType] = error_message
break
end
-- set processedProperty
local processedProperty
local raw = false -- if the value is wanted raw
if isValueInTable(paramName, citeConfig[citeType]["raw-value-params"] or {}) then
raw = true
end
local customRenderer = nil
if citeConfig[citeType]["customRenderers"] then
customRenderer = citeConfig[citeType]["customRenderers"][paramName]
end
if isValueInTable(paramName, citeConfig[citeType]["numbered-params"] or {}) then
-- Multiple values may be given.
processedProperty = self:getReferenceDetails(statement.snaks, refProperty, raw, self.linked, true, customRenderer) -- anyLang = true
else
-- If multiple values are given, all but the first suitable one are discarted.
processedProperty = {self:getReferenceDetail(statement.snaks, refProperty, raw, self.linked and (statement.snaks[refProperty][1].datatype ~= 'url'), true, customRenderer)} -- link = true/false, anyLang = true
end
if #processedProperty == 0 then
break
end
referenceEmpty = false
-- add an empty entry to candidateValuesAndPriorities, if there isn't one already
if not candidateValuesAndPriorities[paramName] then
candidateValuesAndPriorities[paramName] = {}
end
-- find the priority of refProperty
-- (the actual index is mappingKey, not refProperty, because of external IDs)
local thisPropertyPriority = -1
local thisParamPrioritization = (citeConfig[citeType]["prioritization"] or {})[paramName]
if thisParamPrioritization then
for i_priority, i_key in ipairs(thisParamPrioritization) do
if i_key == mappingKey then
thisPropertyPriority = i_priority
end
end
end
for _, propertyValue in pairs(processedProperty) do
table.insert(
candidateValuesAndPriorities[paramName],
{propertyValue, thisPropertyPriority}
)
end
until true
end
-- fill candidateParams[citeType]
if not citeErrors[citeType] then
local compareValuePriorities = function(pair1, pair2)
if pair1[2] == -1 and pair2[2] ~= -1 then
return false
end
if pair1[2] ~= -1 and pair2[2] == -1 then
return true
end
return pair1[2] < pair2[2]
end
-- fill candidateParams[citeType][paramName] for each used param
for paramName, _ in pairs(candidateValuesAndPriorities) do
table.sort(candidateValuesAndPriorities[paramName], compareValuePriorities)
candidateParams[citeType][paramName] = {}
for _, valuePriorityPair in ipairs(candidateValuesAndPriorities[paramName]) do
table.insert(candidateParams[citeType][paramName], valuePriorityPair[1])
end
end
end
end
-- fill citeParams
for _, citeType in ipairs(citeTypes) do
for paramName, paramValues in pairs(candidateParams[citeType]) do
if #paramValues == 1 or not isValueInTable(paramName, citeConfig[citeType]["numbered-params"] or {}) then
citeParams[citeType][paramName] = paramValues[1]
else
-- There is more than one value for this parameter - the values will
-- go into separate numbered parameters (e.g. "author1", "author2")
for paramNum, paramValue in pairs(paramValues) do
citeParams[citeType][paramName .. paramNum] = paramValue
end
end
end
end
-- handle missing mandatory parameters for the templates
for _, citeType in ipairs(citeTypes) do
for _, requiredCiteParam in pairs(citeConfig[citeType]["mandatory-params"] or {}) do
if not citeParams[citeType][requiredCiteParam] then -- The required param is not present.
if citeErrors[citeType] then -- Do not override the previous error, if it exists.
break
end
local error_message = errorText("missing-mandatory-param", requiredCiteParam)
assert(error_message) -- Should not be nil
citeErrors[citeType] = error_message
end
end
end
local citeTypeToUse = nil
-- choose the output template
for _, citeType in ipairs(citeTypes) do
if not citeErrors[citeType] then
citeTypeToUse = citeType
break
end
end
-- set refContent
local refContent = ""
if citeTypeToUse then
local templateToUse = citeConfig[citeTypeToUse]["template"]
local paramsToUse = citeParams[citeTypeToUse]
if not templateToUse or templateToUse == "" then
throwError("no-such-reference-template", tostring(templateToUse), i18nPath, citeTypeToUse)
end
-- if this module is being substituted then build a regular template call, otherwise expand the template
if mw.isSubsting() then
for i, v in pairs(paramsToUse) do
refContent = refContent .. "|" .. i .. "=" .. v
end
refContent = "{{" .. templateToUse .. refContent .. "}}"
else
xpcall(
function () refContent = mw.getCurrentFrame():expandTemplate{title=templateToUse, args=paramsToUse} end,
function () throwError("no-such-reference-template", templateToUse, i18nPath, citeTypeToUse) end
)
end
-- If the citation couldn't be displayed using any template, but is not empty (barring ignored propeties), throw an error.
elseif not referenceEmpty then
refContent = errorText("malformed-reference-header")
for _, citeType in ipairs(citeTypes) do
local templateWikitext = "<nowiki>{{</nowiki>[[Template:" .. citeConfig[citeType]["template"] .. "|" .. citeConfig[citeType]["template"] .. "]]<nowiki>}}</nowiki>"
refContent = refContent .. errorText("template-failure-reason", templateWikitext, citeErrors[citeType])
end
refContent = refContent .. errorText("malformed-reference-footer")
end
-- wrap refContent
local ref = {}
if refContent ~= "" then
ref = {refContent}
if not self.rawValue then
-- this should become a <ref> tag, so save the reference's hash for later
ref.refHash = "wikidata-" .. statement.hash .. "-v" .. (tonumber(i18n['version']) + version)
end
return {ref}
else
return {}
end
end
-- gets a detail of one particular type for a reference
function State:getReferenceDetail(snaks, dType, raw, link, anyLang, customRenderer)
local switchLang = anyLang
local value = nil
if not snaks[dType] then
return nil
end
-- if anyLang, first try the local language and otherwise any language
repeat
for _, v in ipairs(snaks[dType]) do
local defaultRenderer = function ()
return self.conf:getValue(v, raw, link, false, anyLang and not switchLang, false, true) -- noSpecial = true
end
if customRenderer then
value = customRenderer(
v, dType,
defaultRenderer,
p._properties,
function (...) return self.conf:getValue(unpack(arg)) end,
snaks
)
else
value = defaultRenderer()
end
if value then
break
end
end
if value or not anyLang then
break
end
switchLang = not switchLang
until anyLang and switchLang
return value
end
-- gets the details of one particular type for a reference
function State:getReferenceDetails(snaks, dType, raw, link, anyLang, customRenderer)
local values = {}
if not snaks[dType] then
return {}
end
for _, v in ipairs(snaks[dType]) do
local defaultRenderer = function ()
return self.conf:getValue(v, raw, link, false, anyLang, false, true) -- noSpecial = true
end
local value
if customRenderer then
value = customRenderer(
v, dType,
defaultRenderer,
p._properties,
function (...) return self.conf:getValue(unpack(arg)) end,
snaks
)
else
value = defaultRenderer()
end
-- if value is nil then it will not be added to the table
values[#values + 1] = value
end
return values
end
-- level 1 hook
function State:getAlias(object)
local value = object.value
local title = nil
if value and self.linked then
if self.conf.entityID:sub(1,1) == "Q" then
title = mw.wikibase.getSitelink(self.conf.entityID)
elseif self.conf.entityID:sub(1,1) == "P" then
title = "d:Property:" .. self.conf.entityID
end
if title then
value = buildWikilink(title, value)
end
end
value = {value} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getBadge(value)
value = self.conf:getLabel(value, self.rawValue, self.linked, self.shortName)
if value == "" then
value = nil
end
value = {value} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
function State:callHook(param, hooks, statement, result)
-- call a parameter's hook if it has been defined and if it has not been called before
if not result[param] and hooks[param] then
local valuesArray = self[hooks[param]](self, statement, param, result, hooks) -- array with value objects
-- add to the result
if #valuesArray > 0 then
result[param] = valuesArray
result.count = result.count + 1
else
result[param] = {} -- an empty array to indicate that we've tried this hook already
return true -- miss == true
end
end
return false
end
-- iterate through claims, claim's qualifiers or claim's references to collect values
function State:iterate(statements, hooks, matchHook)
matchHook = matchHook or alwaysTrue
local matches = false
local rankPos = nil
local result, gotRequired
for _, v in ipairs(statements) do
-- rankPos will be nil for non-claim statements (e.g. qualifiers, references, etc.)
matches, rankPos = matchHook(self, v)
if matches then
result = {count = 0} -- collection of arrays with value objects
local function walk(formatTable)
local miss
for i2, v2 in pairs(formatTable.req) do
-- call a hook, adding its return value to the result
miss = self:callHook(i2, hooks, v, result)
if miss then
-- we miss a required value for this level, so return false
return false
end
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point breaks the loop
return true
end
end
for _, v2 in ipairs(formatTable) do
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point prevents further childs from being processed
return true
end
if v2.child then
walk(v2.child)
end
end
return true
end
gotRequired = walk(self.parsedFormat)
-- only append the result if we got values for all required parameters on the root level
if gotRequired then
-- if we have a rankPos (only with matchHook() for complete claims), then update the foundRank
if rankPos and self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos
end
-- append the result
self.results[#self.results + 1] = result
-- break if we only need a single value
if self.singleValue then
break
end
end
end
end
return self:out()
end
local function getEntityId(arg, eid, page, allowOmitPropPrefix, globalSiteId)
local id = nil
local prop = nil
if arg then
if arg:sub(1,1) == ":" then
page = arg
eid = nil
elseif arg:sub(1,1):upper() == "Q" or arg:sub(1,9):lower() == "property:" or allowOmitPropPrefix then
eid = arg
page = nil
else
prop = arg
end
end
if eid then
if eid:sub(1,9):lower() == "property:" then
id = replaceAlias(mw.text.trim(eid:sub(10)))
if id:sub(1,1):upper() ~= "P" then
id = ""
end
else
id = replaceAlias(eid)
end
elseif page then
if page:sub(1,1) == ":" then
page = mw.text.trim(page:sub(2))
end
id = mw.wikibase.getEntityIdForTitle(page, globalSiteId) or ""
end
if not id then
id = mw.wikibase.getEntityIdForCurrentPage() or ""
end
id = id:upper()
if not mw.wikibase.isValidEntityId(id) then
id = ""
end
return id, prop
end
local function nextArg(args)
local arg = args[args.pointer]
if arg then
args.pointer = args.pointer + 1
return mw.text.trim(arg)
else
return nil
end
end
local function claimCommand(args, funcName)
local cfg = Config:new()
cfg:processFlagOrCommand(funcName) -- process first command (== function name)
local lastArg, parsedFormat, formatParams, claims, value
local hooks = {count = 0}
-- set the date if given;
-- must come BEFORE processing the flags
if args[p.args.date] then
cfg.atDate = {parseDate(args[p.args.date])}
cfg.periods = {false, true, false} -- change default time constraint to 'current'
end
-- process flags and commands
repeat
lastArg = nextArg(args)
until not cfg:processFlagOrCommand(lastArg)
-- get the entity ID from either the positional argument, the eid argument or the page argument
cfg.entityID, cfg.propertyID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], false, args[p.args.globalSiteId])
if cfg.entityID == "" then
return "" -- we cannot continue without a valid entity ID
end
cfg.entity = mw.wikibase.getEntity(cfg.entityID)
if not cfg.propertyID then
cfg.propertyID = nextArg(args)
end
cfg.propertyID = replaceAlias(cfg.propertyID)
if not cfg.entity or not cfg.propertyID then
return "" -- we cannot continue without an entity or a property ID
end
cfg.propertyID = cfg.propertyID:upper()
if not cfg.entity.claims or not cfg.entity.claims[cfg.propertyID] then
return "" -- there is no use to continue without any claims
end
claims = cfg.entity.claims[cfg.propertyID]
if cfg.states.qualifiersCount > 0 then
-- do further processing if "qualifier(s)" command was given
if #args - args.pointer + 1 > cfg.states.qualifiersCount then
-- claim ID or literal value has been given
cfg.propertyValue = nextArg(args)
end
for i = 1, cfg.states.qualifiersCount do
-- check if given qualifier ID is an alias and add it
cfg.qualifierIDs[parameters.qualifier..i] = replaceAlias(nextArg(args) or ""):upper()
end
elseif cfg.states[parameters.reference] then
-- do further processing if "reference(s)" command was given
cfg.propertyValue = nextArg(args)
end
-- check for special property value 'somevalue' or 'novalue'
if cfg.propertyValue then
cfg.propertyValue = replaceSpecialChars(cfg.propertyValue)
if cfg.propertyValue ~= "" and mw.text.trim(cfg.propertyValue) == "" then
cfg.propertyValue = " " -- single space represents 'somevalue', whereas empty string represents 'novalue'
else
cfg.propertyValue = mw.text.trim(cfg.propertyValue)
end
end
-- parse the desired format, or choose an appropriate format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
elseif cfg.states.qualifiersCount > 0 then -- "qualifier(s)" command given
if cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier)
else
parsedFormat, formatParams = parseFormat(formats.qualifier)
end
elseif cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.property)
else -- "reference(s)" command given
parsedFormat, formatParams = parseFormat(formats.reference)
end
-- if a "qualifier(s)" command and no "propert(y|ies)" command has been given, make the movable separator a semicolon
if cfg.states.qualifiersCount > 0 and not cfg.states[parameters.property] then
cfg.separators["sep"..parameters.separator][1] = {";"}
end
-- if only "reference(s)" has been given, set the default separator to none (except when raw)
if cfg.states[parameters.reference] and not cfg.states[parameters.property] and cfg.states.qualifiersCount == 0
and not cfg.states[parameters.reference].rawValue then
cfg.separators["sep"][1] = nil
end
-- if exactly one "qualifier(s)" command has been given, make "sep%q" point to "sep%q1" to make them equivalent
if cfg.states.qualifiersCount == 1 then
cfg.separators["sep"..parameters.qualifier] = cfg.separators["sep"..parameters.qualifier.."1"]
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hooks that should be called (getProperty, getQualifiers, getReferences);
-- only define a hook if both its command ("propert(y|ies)", "reference(s)", "qualifier(s)") and its parameter ("%p", "%r", "%q1", "%q2", "%q3") have been given
for i, v in pairs(cfg.states) do
-- e.g. 'formatParams["%q1"] or formatParams["%q"]' to define hook even if "%q1" was not defined to be able to build a complete value for "%q"
if formatParams[i] or formatParams[i:sub(1, 2)] then
hooks[i] = getHookName(i, 1)
hooks.count = hooks.count + 1
end
end
-- the "%q" parameter is not attached to a state, but is a collection of the results of multiple states (attached to "%q1", "%q2", "%q3", ...);
-- so if this parameter is given then this hook must be defined separately, but only if at least one "qualifier(s)" command has been given
if formatParams[parameters.qualifier] and cfg.states.qualifiersCount > 0 then
hooks[parameters.qualifier] = getHookName(parameters.qualifier, 1)
hooks.count = hooks.count + 1
end
-- create a state for "properties" if it doesn't exist yet, which will be used as a base configuration for each claim iteration;
-- must come AFTER defining the hooks
if not cfg.states[parameters.property] then
cfg.states[parameters.property] = State:new(cfg, parameters.property)
-- if the "single" flag has been given then this state should be equivalent to "property" (singular)
if cfg.singleClaim then
cfg.states[parameters.property].singleValue = true
end
end
-- if the "sourced" flag has been given then create a state for "reference" if it doesn't exist yet, using default values,
-- which must exist in order to be able to determine if a claim has any references;
-- must come AFTER defining the hooks
if cfg.sourcedOnly and not cfg.states[parameters.reference] then
cfg:processFlagOrCommand(p.claimCommands.reference) -- use singular "reference" to minimize overhead
end
-- set the parsed format and the separators (and optional punctuation mark);
-- must come AFTER creating the additonal states
cfg:setFormatAndSeparators(cfg.states[parameters.property], parsedFormat)
-- process qualifier matching values, analogous to cfg.propertyValue
for i, v in pairs(args) do
i = tostring(i)
if i:match('^[Pp]%d+$') or aliasesP[i] then
v = replaceSpecialChars(v)
-- check for special qualifier value 'somevalue'
if v ~= "" and mw.text.trim(v) == "" then
v = " " -- single space represents 'somevalue'
end
cfg.qualifierIDsAndValues[replaceAlias(i):upper()] = v
end
end
-- first sort the claims on rank to pre-define the order of output (preferred first, then normal, then deprecated)
claims = sortOnRank(claims)
-- then iterate through the claims to collect values
value = cfg:concatValues(cfg.states[parameters.property]:iterate(claims, hooks, State.claimMatches)) -- pass property state with level 1 hooks and matchHook
-- if desired, add a clickable icon that may be used to edit the returned values on Wikidata
if cfg.editable and value ~= "" then
value = value .. cfg:getEditIcon()
end
return value
end
local function generalCommand(args, funcName)
local cfg = Config:new()
cfg.curState = State:new(cfg)
local lastArg
local value = nil
repeat
lastArg = nextArg(args)
until not cfg:processFlag(lastArg)
-- get the entity ID from either the positional argument, the eid argument or the page argument
cfg.entityID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], true, args[p.args.globalSiteId])
if cfg.entityID == "" or not mw.wikibase.entityExists(cfg.entityID) then
return "" -- we cannot continue without an entity
end
-- serve according to the given command
if funcName == p.generalCommands.label then
value = cfg:getLabel(cfg.entityID, cfg.curState.rawValue, cfg.curState.linked, cfg.curState.shortName)
elseif funcName == p.generalCommands.title then
cfg.inSitelinks = true
if cfg.entityID:sub(1,1) == "Q" then
value = mw.wikibase.getSitelink(cfg.entityID)
end
if cfg.curState.linked and value then
value = buildWikilink(value)
end
elseif funcName == p.generalCommands.description then
value = mw.wikibase.getDescription(cfg.entityID)
else
local parsedFormat, formatParams
local hooks = {count = 0}
cfg.entity = mw.wikibase.getEntity(cfg.entityID)
if funcName == p.generalCommands.alias or funcName == p.generalCommands.badge then
cfg.curState.singleValue = true
end
if funcName == p.generalCommands.alias or funcName == p.generalCommands.aliases then
if not cfg.entity.aliases or not cfg.entity.aliases[cfg.langCode] then
return "" -- there is no use to continue without any aliasses
end
local aliases = cfg.entity.aliases[cfg.langCode]
-- parse the desired format, or parse the default aliases format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
else
parsedFormat, formatParams = parseFormat(formats.alias)
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hook that should be called (getAlias);
-- only define the hook if the parameter ("%a") has been given
if formatParams[parameters.alias] then
hooks[parameters.alias] = getHookName(parameters.alias, 1)
hooks.count = hooks.count + 1
end
-- set the parsed format and the separators (and optional punctuation mark)
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
-- iterate to collect values
value = cfg:concatValues(cfg.curState:iterate(aliases, hooks))
elseif funcName == p.generalCommands.badge or funcName == p.generalCommands.badges then
if not cfg.entity.sitelinks or not cfg.entity.sitelinks[cfg.siteID] or not cfg.entity.sitelinks[cfg.siteID].badges then
return "" -- there is no use to continue without any badges
end
local badges = cfg.entity.sitelinks[cfg.siteID].badges
cfg.inSitelinks = true
-- parse the desired format, or parse the default aliases format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
else
parsedFormat, formatParams = parseFormat(formats.badge)
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hook that should be called (getBadge);
-- only define the hook if the parameter ("%b") has been given
if formatParams[parameters.badge] then
hooks[parameters.badge] = getHookName(parameters.badge, 1)
hooks.count = hooks.count + 1
end
-- set the parsed format and the separators (and optional punctuation mark)
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
-- iterate to collect values
value = cfg:concatValues(cfg.curState:iterate(badges, hooks))
end
end
value = value or ""
if cfg.editable and value ~= "" then
-- if desired, add a clickable icon that may be used to edit the returned value on Wikidata
value = value .. cfg:getEditIcon()
end
return value
end
-- modules that include this module should call the functions with an underscore prepended, e.g.: p._property(args)
local function establishCommands(commandList, commandFunc)
for _, commandName in pairs(commandList) do
local function wikitextWrapper(frame)
local args = copyTable(frame.args)
args.pointer = 1
loadI18n(aliasesP, frame)
return commandFunc(args, commandName)
end
p[commandName] = wikitextWrapper
local function luaWrapper(args)
args = copyTable(args)
args.pointer = 1
loadI18n(aliasesP)
return commandFunc(args, commandName)
end
p["_" .. commandName] = luaWrapper
end
end
establishCommands(p.claimCommands, claimCommand)
establishCommands(p.generalCommands, generalCommand)
-- main function that is supposed to be used by wrapper templates
function p.main(frame)
if not mw.wikibase then return nil end
local f, args
loadI18n(aliasesP, frame)
-- get the parent frame to take the arguments that were passed to the wrapper template
frame = frame:getParent() or frame
if not frame.args[1] then
throwError("no-function-specified")
end
f = mw.text.trim(frame.args[1])
if f == "main" then
throwError("main-called-twice")
end
assert(p["_"..f], errorText('no-such-function', f))
-- copy arguments from immutable to mutable table
args = copyTable(frame.args)
-- remove the function name from the list
table.remove(args, 1)
return p["_"..f](args)
end
return p
dyjtoxlu5p2mq8c2h4dmvnmhx8qx22r
124180
124179
2026-11-09T20:20:39Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Wd]]
124179
Scribunto
text/plain
-- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]].
require("strict")
local p = {}
local module_arg = ...
local i18n
local i18nPath
local function loadI18n(aliasesP, frame)
local title
if frame then
-- current module invoked by page/template, get its title from frame
title = frame:getTitle()
else
-- current module included by other module, get its title from ...
title = module_arg
end
if not i18n then
i18nPath = title .. "/i18n"
i18n = require(i18nPath).init(aliasesP)
end
end
p.claimCommands = {
property = "property",
properties = "properties",
qualifier = "qualifier",
qualifiers = "qualifiers",
reference = "reference",
references = "references"
}
p.generalCommands = {
label = "label",
title = "title",
description = "description",
alias = "alias",
aliases = "aliases",
badge = "badge",
badges = "badges"
}
p.flags = {
linked = "linked",
short = "short",
raw = "raw",
multilanguage = "multilanguage",
unit = "unit",
-------------
preferred = "preferred",
normal = "normal",
deprecated = "deprecated",
best = "best",
future = "future",
current = "current",
former = "former",
edit = "edit",
editAtEnd = "edit@end",
mdy = "mdy",
single = "single",
sourced = "sourced"
}
p.args = {
eid = "eid",
page = "page",
date = "date",
globalSiteId = "globalSiteId"
}
local aliasesP = {
coord = "P625",
-----------------------
image = "P18",
author = "P50",
authorNameString = "P2093",
publisher = "P123",
importedFrom = "P143",
wikimediaImportURL = "P4656",
statedIn = "P248",
pages = "P304",
language = "P407",
wikimediaLanguageCode = "P424",
hasPart = "P527",
publicationDate = "P577",
startTime = "P580",
endTime = "P582",
chapter = "P792",
retrieved = "P813",
referenceURL = "P854",
sectionVerseOrParagraph = "P958",
archiveURL = "P1065",
title = "P1476",
formatterURL = "P1630",
quote = "P1683",
shortName = "P1813",
definingFormula = "P2534",
archiveDate = "P2960",
inferredFrom = "P3452",
typeOfReference = "P3865",
column = "P3903",
subjectNamedAs = "P1810",
wikidataProperty = "P1687",
publishedIn = "P1433",
lastUpdate = "P5017"
}
local aliasesQ = {
percentage = "Q11229",
prolepticJulianCalendar = "Q1985786",
citeWeb = "Q5637226",
citeQ = "Q22321052"
}
local parameters = {
property = "%p",
qualifier = "%q",
reference = "%r",
alias = "%a",
badge = "%b",
separator = "%s",
general = "%x"
}
local formats = {
property = "%p[%s][%r]",
qualifier = "%q[%s][%r]",
reference = "%r",
propertyWithQualifier = "%p[ <span style=\"font-size:85\\%\">(%q)</span>][%s][%r]",
alias = "%a[%s]",
badge = "%b[%s]"
}
local hookNames = { -- {level_1, level_2}
[parameters.property] = {"getProperty"},
[parameters.reference] = {"getReferences", "getReference"},
[parameters.qualifier] = {"getAllQualifiers"},
[parameters.qualifier.."\\d"] = {"getQualifiers", "getQualifier"},
[parameters.alias] = {"getAlias"},
[parameters.badge] = {"getBadge"}
}
-- default value objects, should NOT be mutated but instead copied
local defaultSeparators = {
["sep"] = {" "},
["sep%s"] = {","},
["sep%q"] = {"; "},
["sep%q\\d"] = {", "},
["sep%r"] = nil, -- none
["punc"] = nil -- none
}
local rankTable = {
["preferred"] = 1,
["normal"] = 2,
["deprecated"] = 3
}
local function replaceAlias(id)
if aliasesP[id] then
id = aliasesP[id]
end
return id
end
local function errorText(code, ...)
local text = i18n["errors"][code]
if arg then text = mw.ustring.format(text, unpack(arg)) end
return text
end
local function throwError(errorMessage, ...)
error(errorText(errorMessage, unpack(arg)))
end
local function replaceDecimalMark(num)
return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1)
end
local function padZeros(num, numDigits)
local numZeros
local negative = false
if num < 0 then
negative = true
num = num * -1
end
num = tostring(num)
numZeros = numDigits - num:len()
for _ = 1, numZeros do
num = "0"..num
end
if negative then
num = "-"..num
end
return num
end
local function replaceSpecialChar(chr)
if chr == '_' then
-- replace underscores with spaces
return ' '
else
return chr
end
end
local function replaceSpecialChars(str)
local chr
local esc = false
local strOut = ""
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
esc = true
else
strOut = strOut .. replaceSpecialChar(chr)
end
else
strOut = strOut .. chr
esc = false
end
end
return strOut
end
local function buildWikilink(target, label)
if not label or target == label then
return "[[" .. target .. "]]"
else
return "[[" .. target .. "|" .. label .. "]]"
end
end
-- used to make frame.args mutable, to replace #frame.args (which is always 0)
-- with the actual amount and to simply copy tables
local function copyTable(tIn)
if not tIn then
return nil
end
local tOut = {}
for i, v in pairs(tIn) do
tOut[i] = v
end
return tOut
end
-- used to merge output arrays together;
-- note that it currently mutates the first input array
local function mergeArrays(a1, a2)
for i = 1, #a2 do
a1[#a1 + 1] = a2[i]
end
return a1
end
local function split(str, del)
local out = {}
local i, j = str:find(del)
if i and j then
out[1] = str:sub(1, i - 1)
out[2] = str:sub(j + 1)
else
out[1] = str
end
return out
end
local function parseWikidataURL(url)
local id
if url:match('^http[s]?://') then
id = split(url, "Q")
if id[2] then
return "Q" .. id[2]
end
end
return nil
end
local function parseDate(dateStr, precision)
precision = precision or "d"
local i, j, index, ptr
local parts = {nil, nil, nil}
if dateStr == nil then
return parts[1], parts[2], parts[3] -- year, month, day
end
-- 'T' for snak values, '/' for outputs with '/Julian' attached
i, j = dateStr:find("[T/]")
if i then
dateStr = dateStr:sub(1, i-1)
end
local from = 1
if dateStr:sub(1,1) == "-" then
-- this is a negative number, look further ahead
from = 2
end
index = 1
ptr = 1
i, j = dateStr:find("-", from)
if i then
-- year
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) -- explicitly give base 10 to prevent error
if parts[index] == -0 then
parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead
end
if precision == "y" then
-- we're done
return parts[1], parts[2], parts[3] -- year, month, day
end
index = index + 1
ptr = i + 1
i, j = dateStr:find("-", ptr)
if i then
-- month
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)
if precision == "m" then
-- we're done
return parts[1], parts[2], parts[3] -- year, month, day
end
index = index + 1
ptr = i + 1
end
end
if dateStr:sub(ptr) ~= "" then
-- day if we have month, month if we have year, or year
parts[index] = tonumber(dateStr:sub(ptr), 10)
end
return parts[1], parts[2], parts[3] -- year, month, day
end
local function datePrecedesDate(aY, aM, aD, bY, bM, bD)
if aY == nil or bY == nil then
return nil
end
aM = aM or 1
aD = aD or 1
bM = bM or 1
bD = bD or 1
if aY < bY then
return true
end
if aY > bY then
return false
end
if aM < bM then
return true
end
if aM > bM then
return false
end
if aD < bD then
return true
end
return false
end
local function getHookName(param, index)
if hookNames[param] then
return hookNames[param][index]
elseif param:len() > 2 then
return hookNames[param:sub(1, 2).."\\d"][index]
else
return nil
end
end
local function alwaysTrue()
return true
end
-- The following function parses a format string.
--
-- The example below shows how a parsed string is structured in memory.
-- Variables other than 'str' and 'child' are left out for clarity's sake.
--
-- Example:
-- "A %p B [%s[%q1]] C [%r] D"
--
-- Structure:
-- [
-- {
-- str = "A "
-- },
-- {
-- str = "%p"
-- },
-- {
-- str = " B ",
-- child =
-- [
-- {
-- str = "%s",
-- child =
-- [
-- {
-- str = "%q1"
-- }
-- ]
-- }
-- ]
-- },
-- {
-- str = " C ",
-- child =
-- [
-- {
-- str = "%r"
-- }
-- ]
-- },
-- {
-- str = " D"
-- }
-- ]
--
local function parseFormat(str)
local chr, esc, param, root, cur, prev, new
local params = {}
local function newObject(array)
local obj = {} -- new object
obj.str = ""
array[#array + 1] = obj -- array{object}
obj.parent = array
return obj
end
local function endParam()
if param > 0 then
if cur.str ~= "" then
cur.str = "%"..cur.str
cur.param = true
params[cur.str] = true
cur.parent.req[cur.str] = true
prev = cur
cur = newObject(cur.parent)
end
param = 0
end
end
root = {} -- array
root.req = {}
cur = newObject(root)
prev = nil
esc = false
param = 0
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
endParam()
esc = true
elseif chr == '%' then
endParam()
if cur.str ~= "" then
cur = newObject(cur.parent)
end
param = 2
elseif chr == '[' then
endParam()
if prev and cur.str == "" then
table.remove(cur.parent)
cur = prev
end
cur.child = {} -- new array
cur.child.req = {}
cur.child.parent = cur
cur = newObject(cur.child)
elseif chr == ']' then
endParam()
if cur.parent.parent then
new = newObject(cur.parent.parent.parent)
if cur.str == "" then
table.remove(cur.parent)
end
cur = new
end
else
if param > 1 then
param = param - 1
elseif param == 1 then
if not chr:match('%d') then
endParam()
end
end
cur.str = cur.str .. replaceSpecialChar(chr)
end
else
cur.str = cur.str .. chr
esc = false
end
prev = nil
end
endParam()
-- make sure that at least one required parameter has been defined
if not next(root.req) then
throwError("missing-required-parameter")
end
-- make sure that the separator parameter "%s" is not amongst the required parameters
if root.req[parameters.separator] then
throwError("extra-required-parameter", parameters.separator)
end
return root, params
end
local function sortOnRank(claims)
local rankPos
local ranks = {{}, {}, {}, {}} -- preferred, normal, deprecated, (default)
local sorted = {}
for _, v in ipairs(claims) do
rankPos = rankTable[v.rank] or 4
ranks[rankPos][#ranks[rankPos] + 1] = v
end
sorted = ranks[1]
sorted = mergeArrays(sorted, ranks[2])
sorted = mergeArrays(sorted, ranks[3])
return sorted
end
local function isValueInTable(searchedItem, inputTable)
for _, item in pairs(inputTable) do
if item == searchedItem then
return true
end
end
return false
end
local Config = {}
-- allows for recursive calls
function Config:new()
local cfg = {}
setmetatable(cfg, self)
self.__index = self
cfg.separators = {
-- single value objects wrapped in arrays so that we can pass by reference
["sep"] = {copyTable(defaultSeparators["sep"])},
["sep%s"] = {copyTable(defaultSeparators["sep%s"])},
["sep%q"] = {copyTable(defaultSeparators["sep%q"])},
["sep%r"] = {copyTable(defaultSeparators["sep%r"])},
["punc"] = {copyTable(defaultSeparators["punc"])}
}
cfg.entity = nil
cfg.entityID = nil
cfg.propertyID = nil
cfg.propertyValue = nil
cfg.qualifierIDs = {}
cfg.qualifierIDsAndValues = {}
cfg.bestRank = true
cfg.ranks = {true, true, false} -- preferred = true, normal = true, deprecated = false
cfg.foundRank = #cfg.ranks
cfg.flagBest = false
cfg.flagRank = false
cfg.periods = {true, true, true} -- future = true, current = true, former = true
cfg.flagPeriod = false
cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))} -- today as {year, month, day}
cfg.mdyDate = false
cfg.singleClaim = false
cfg.sourcedOnly = false
cfg.editable = false
cfg.editAtEnd = false
cfg.inSitelinks = false
cfg.langCode = mw.language.getContentLanguage().code
cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode)
cfg.langObj = mw.language.new(cfg.langCode)
cfg.siteID = mw.wikibase.getGlobalSiteId()
cfg.states = {}
cfg.states.qualifiersCount = 0
cfg.curState = nil
cfg.prefetchedRefs = nil
return cfg
end
local State = {}
function State:new(cfg, type)
local stt = {}
setmetatable(stt, self)
self.__index = self
stt.conf = cfg
stt.type = type
stt.results = {}
stt.parsedFormat = {}
stt.separator = {}
stt.movSeparator = {}
stt.puncMark = {}
stt.linked = false
stt.rawValue = false
stt.shortName = false
stt.anyLanguage = false
stt.unitOnly = false
stt.singleValue = false
return stt
end
-- if id == nil then item connected to current page is used
function Config:getLabel(id, raw, link, short)
local label = nil
local prefix, title= "", nil
if not id then
id = mw.wikibase.getEntityIdForCurrentPage()
if not id then
return ""
end
end
id = id:upper() -- just to be sure
if raw then
-- check if given id actually exists
if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then
label = id
end
prefix, title = "d:Special:EntityPage/", label -- may be nil
else
-- try short name first if requested
if short then
label = p._property{aliasesP.shortName, [p.args.eid] = id} -- get short name
if label == "" then
label = nil
end
end
-- get label
if not label then
label = mw.wikibase.getLabel(id)
end
end
if not label then
label = ""
elseif link then
-- build a link if requested
if not title then
if id:sub(1,1) == "Q" then
title = mw.wikibase.getSitelink(id)
elseif id:sub(1,1) == "P" then
-- properties have no sitelink, link to Wikidata instead
prefix, title = "d:Special:EntityPage/", id
end
end
label = mw.text.nowiki(label) -- escape raw label text so it cannot be wikitext markup
if title then
label = buildWikilink(prefix .. title, label)
end
end
return label
end
function Config:getEditIcon()
local value = ""
local prefix = ""
local front = " "
local back = ""
if self.entityID:sub(1,1) == "P" then
prefix = "Property:"
end
if self.editAtEnd then
front = '<span style="float:'
if self.langObj:isRTL() then
front = front .. 'left'
else
front = front .. 'right'
end
front = front .. '">'
back = '</span>'
end
value = "[[File:OOjs UI icon edit-ltr-progressive.svg|frameless|text-top|10px|alt=" .. i18n['info']['edit-on-wikidata'] .. "|link=https://www.wikidata.org/wiki/" .. prefix .. self.entityID .. "?uselang=" .. self.langCode
if self.propertyID then
value = value .. "#" .. self.propertyID
elseif self.inSitelinks then
value = value .. "#sitelinks-wikipedia"
end
value = value .. "|" .. i18n['info']['edit-on-wikidata'] .. "]]"
return front .. value .. back
end
-- used to create the final output string when it's all done, so that for references the
-- function extensionTag("ref", ...) is only called when they really ended up in the final output
function Config:concatValues(valuesArray)
local outString = ""
local j, skip
for i = 1, #valuesArray do
-- check if this is a reference
if valuesArray[i].refHash then
j = i - 1
skip = false
-- skip this reference if it is part of a continuous row of references that already contains the exact same reference
while valuesArray[j] and valuesArray[j].refHash do
if valuesArray[i].refHash == valuesArray[j].refHash then
skip = true
break
end
j = j - 1
end
if not skip then
-- add <ref> tag with the reference's hash as its name (to deduplicate references)
outString = outString .. mw.getCurrentFrame():extensionTag("ref", valuesArray[i][1], {name = valuesArray[i].refHash})
end
else
outString = outString .. valuesArray[i][1]
end
end
return outString
end
function Config:convertUnit(unit, raw, link, short, unitOnly)
local space = " "
local label = ""
local itemID
if unit == "" or unit == "1" then
return nil
end
if unitOnly then
space = ""
end
itemID = parseWikidataURL(unit)
if itemID then
if itemID == aliasesQ.percentage then
return "%"
else
label = self:getLabel(itemID, raw, link, short)
if label ~= "" then
return space .. label
end
end
end
return ""
end
function State:getValue(snak)
return self.conf:getValue(snak, self.rawValue, self.linked, self.shortName, self.anyLanguage, self.unitOnly, false, self.type:sub(1,2))
end
function Config:getValue(snak, raw, link, short, anyLang, unitOnly, noSpecial, type)
if snak.snaktype == 'value' then
local datatype = snak.datavalue.type
local subtype = snak.datatype
local datavalue = snak.datavalue.value
if datatype == 'string' then
if subtype == 'url' and link then
-- create link explicitly
if raw then
-- will render as a linked number like [1]
return "[" .. datavalue .. "]"
else
return "[" .. datavalue .. " " .. datavalue .. "]"
end
elseif subtype == 'commonsMedia' then
if link then
return buildWikilink("c:File:" .. datavalue, datavalue)
elseif not raw then
return "[[File:" .. datavalue .. "]]"
else
return datavalue
end
elseif subtype == 'geo-shape' and link then
return buildWikilink("c:" .. datavalue, datavalue)
elseif subtype == 'math' and not raw then
local attribute = nil
if (type == parameters.property or (type == parameters.qualifier and self.propertyID == aliasesP.hasPart)) and snak.property == aliasesP.definingFormula then
attribute = {qid = self.entityID}
end
return mw.getCurrentFrame():extensionTag("math", datavalue, attribute)
elseif subtype == 'external-id' and link then
local url = p._property{p.flags.raw, aliasesP.formatterURL, [p.args.eid] = snak.property} -- get formatter URL
if url ~= "" then
url = mw.ustring.gsub(url, "$1", datavalue)
return "[" .. url .. " " .. datavalue .. "]"
else
return datavalue
end
else
return datavalue
end
elseif datatype == 'monolingualtext' then
if anyLang or datavalue['language'] == self.langCode then
return datavalue['text']
else
return nil
end
elseif datatype == 'quantity' then
local value = ""
local unit
if not unitOnly then
-- get value and strip + signs from front
value = mw.ustring.gsub(datavalue['amount'], "^%+(.+)$", "%1")
if raw then
return value
end
-- replace decimal mark based on locale
value = replaceDecimalMark(value)
-- add delimiters for readability
value = i18n.addDelimiters(value)
end
unit = self:convertUnit(datavalue['unit'], raw, link, short, unitOnly)
if unit then
value = value .. unit
end
return value
elseif datatype == 'time' then
local y, m, d, p, yDiv, yRound, yFull, value, calendarID, dateStr
local yFactor = 1
local sign = 1
local prefix = ""
local suffix = ""
local mayAddCalendar = false
local calendar = ""
local precision = datavalue['precision']
if precision == 11 then
p = "d"
elseif precision == 10 then
p = "m"
else
p = "y"
yFactor = 10^(9-precision)
end
y, m, d = parseDate(datavalue['time'], p)
if y < 0 then
sign = -1
y = y * sign
end
-- if precision is tens/hundreds/thousands/millions/billions of years
if precision <= 8 then
yDiv = y / yFactor
-- if precision is tens/hundreds/thousands of years
if precision >= 6 then
mayAddCalendar = true
if precision <= 7 then
-- round centuries/millenniums up (e.g. 20th century or 3rd millennium)
yRound = math.ceil(yDiv)
if not raw then
if precision == 6 then
suffix = i18n['datetime']['suffixes']['millennium']
else
suffix = i18n['datetime']['suffixes']['century']
end
suffix = i18n.getOrdinalSuffix(yRound) .. suffix
else
-- if not verbose, take the first year of the century/millennium
-- (e.g. 1901 for 20th century or 2001 for 3rd millennium)
yRound = (yRound - 1) * yFactor + 1
end
else
-- precision == 8
-- round decades down (e.g. 2010s)
yRound = math.floor(yDiv) * yFactor
if not raw then
prefix = i18n['datetime']['prefixes']['decade-period']
suffix = i18n['datetime']['suffixes']['decade-period']
end
end
if raw and sign < 0 then
-- if BCE then compensate for "counting backwards"
-- (e.g. -2019 for 2010s BCE, -2000 for 20th century BCE or -3000 for 3rd millennium BCE)
yRound = yRound + yFactor - 1
end
else
local yReFactor, yReDiv, yReRound
-- round to nearest for tens of thousands of years or more
yRound = math.floor(yDiv + 0.5)
if yRound == 0 then
if precision <= 2 and y ~= 0 then
yReFactor = 1e6
yReDiv = y / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to millions of years only if we have a whole number of them
precision = 3
yFactor = yReFactor
yRound = yReRound
end
end
if yRound == 0 then
-- otherwise, take the unrounded (original) number of years
precision = 5
yFactor = 1
yRound = y
mayAddCalendar = true
end
end
if precision >= 1 and y ~= 0 then
yFull = yRound * yFactor
yReFactor = 1e9
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to billions of years if we're in that range
precision = 0
yFactor = yReFactor
yRound = yReRound
else
yReFactor = 1e6
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
-- change precision to millions of years if we're in that range
precision = 3
yFactor = yReFactor
yRound = yReRound
end
end
end
if not raw then
if precision == 3 then
suffix = i18n['datetime']['suffixes']['million-years']
elseif precision == 0 then
suffix = i18n['datetime']['suffixes']['billion-years']
else
yRound = yRound * yFactor
if yRound == 1 then
suffix = i18n['datetime']['suffixes']['year']
else
suffix = i18n['datetime']['suffixes']['years']
end
end
else
yRound = yRound * yFactor
end
end
else
yRound = y
mayAddCalendar = true
end
if mayAddCalendar then
calendarID = parseWikidataURL(datavalue['calendarmodel'])
if calendarID and calendarID == aliasesQ.prolepticJulianCalendar then
if not raw then
if link then
calendar = " ("..buildWikilink(i18n['datetime']['julian-calendar'], i18n['datetime']['julian'])..")"
else
calendar = " ("..i18n['datetime']['julian']..")"
end
else
calendar = "/"..i18n['datetime']['julian']
end
end
end
if not raw then
local ce = nil
if sign < 0 then
ce = i18n['datetime']['BCE']
elseif precision <= 5 then
ce = i18n['datetime']['CE']
end
if ce then
if link then
ce = buildWikilink(i18n['datetime']['common-era'], ce)
end
suffix = suffix .. " " .. ce
end
value = tostring(yRound)
if m then
dateStr = self.langObj:formatDate("F", "1-"..m.."-1")
if d then
if self.mdyDate then
dateStr = dateStr .. " " .. d .. ","
else
dateStr = d .. " " .. dateStr
end
end
value = dateStr .. " " .. value
end
value = prefix .. value .. suffix .. calendar
else
value = padZeros(yRound * sign, 4)
if m then
value = value .. "-" .. padZeros(m, 2)
if d then
value = value .. "-" .. padZeros(d, 2)
end
end
value = value .. calendar
end
return value
elseif datatype == 'globecoordinate' then
-- logic from https://github.com/DataValues/Geo (v4.0.1)
local precision, unitsPerDegree, numDigits, strFormat, value, globe
local latitude, latConv, latValue, latLink
local longitude, lonConv, lonValue, lonLink
local latDirection, latDirectionN, latDirectionS, latDirectionEN
local lonDirection, lonDirectionE, lonDirectionW, lonDirectionEN
local degSymbol, minSymbol, secSymbol, separator
local latDegrees = nil
local latMinutes = nil
local latSeconds = nil
local lonDegrees = nil
local lonMinutes = nil
local lonSeconds = nil
local latDegSym = ""
local latMinSym = ""
local latSecSym = ""
local lonDegSym = ""
local lonMinSym = ""
local lonSecSym = ""
local latDirectionEN_N = "N"
local latDirectionEN_S = "S"
local lonDirectionEN_E = "E"
local lonDirectionEN_W = "W"
if not raw then
latDirectionN = i18n['coord']['latitude-north']
latDirectionS = i18n['coord']['latitude-south']
lonDirectionE = i18n['coord']['longitude-east']
lonDirectionW = i18n['coord']['longitude-west']
degSymbol = i18n['coord']['degrees']
minSymbol = i18n['coord']['minutes']
secSymbol = i18n['coord']['seconds']
separator = i18n['coord']['separator']
else
latDirectionN = latDirectionEN_N
latDirectionS = latDirectionEN_S
lonDirectionE = lonDirectionEN_E
lonDirectionW = lonDirectionEN_W
degSymbol = "/"
minSymbol = "/"
secSymbol = "/"
separator = "/"
end
latitude = datavalue['latitude']
longitude = datavalue['longitude']
if latitude < 0 then
latDirection = latDirectionS
latDirectionEN = latDirectionEN_S
latitude = math.abs(latitude)
else
latDirection = latDirectionN
latDirectionEN = latDirectionEN_N
end
if longitude < 0 then
lonDirection = lonDirectionW
lonDirectionEN = lonDirectionEN_W
longitude = math.abs(longitude)
else
lonDirection = lonDirectionE
lonDirectionEN = lonDirectionEN_E
end
precision = datavalue['precision']
if not precision or precision <= 0 then
precision = 1 / 3600 -- precision not set (correctly), set to arcsecond
end
-- remove insignificant detail
latitude = math.floor(latitude / precision + 0.5) * precision
longitude = math.floor(longitude / precision + 0.5) * precision
if precision >= 1 - (1 / 60) and precision < 1 then
precision = 1
elseif precision >= (1 / 60) - (1 / 3600) and precision < (1 / 60) then
precision = 1 / 60
end
if precision >= 1 then
unitsPerDegree = 1
elseif precision >= (1 / 60) then
unitsPerDegree = 60
else
unitsPerDegree = 3600
end
numDigits = math.ceil(-math.log10(unitsPerDegree * precision))
if numDigits <= 0 then
numDigits = tonumber("0") -- for some reason, 'numDigits = 0' may actually store '-0', so parse from string instead
end
strFormat = "%." .. numDigits .. "f"
if precision >= 1 then
latDegrees = strFormat:format(latitude)
lonDegrees = strFormat:format(longitude)
if not raw then
latDegSym = replaceDecimalMark(latDegrees) .. degSymbol
lonDegSym = replaceDecimalMark(lonDegrees) .. degSymbol
else
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol
end
else
latConv = math.floor(latitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
lonConv = math.floor(longitude * unitsPerDegree * 10^numDigits + 0.5) / 10^numDigits
if precision >= (1 / 60) then
latMinutes = latConv
lonMinutes = lonConv
else
latSeconds = latConv
lonSeconds = lonConv
latMinutes = math.floor(latSeconds / 60)
lonMinutes = math.floor(lonSeconds / 60)
latSeconds = strFormat:format(latSeconds - (latMinutes * 60))
lonSeconds = strFormat:format(lonSeconds - (lonMinutes * 60))
if not raw then
latSecSym = replaceDecimalMark(latSeconds) .. secSymbol
lonSecSym = replaceDecimalMark(lonSeconds) .. secSymbol
else
latSecSym = latSeconds .. secSymbol
lonSecSym = lonSeconds .. secSymbol
end
end
latDegrees = math.floor(latMinutes / 60)
lonDegrees = math.floor(lonMinutes / 60)
latDegSym = latDegrees .. degSymbol
lonDegSym = lonDegrees .. degSymbol
latMinutes = latMinutes - (latDegrees * 60)
lonMinutes = lonMinutes - (lonDegrees * 60)
if precision >= (1 / 60) then
latMinutes = strFormat:format(latMinutes)
lonMinutes = strFormat:format(lonMinutes)
if not raw then
latMinSym = replaceDecimalMark(latMinutes) .. minSymbol
lonMinSym = replaceDecimalMark(lonMinutes) .. minSymbol
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
else
latMinSym = latMinutes .. minSymbol
lonMinSym = lonMinutes .. minSymbol
end
end
latValue = latDegSym .. latMinSym .. latSecSym .. latDirection
lonValue = lonDegSym .. lonMinSym .. lonSecSym .. lonDirection
value = latValue .. separator .. lonValue
if link then
globe = parseWikidataURL(datavalue['globe'])
if globe then
globe = mw.wikibase.getLabelByLang(globe, "en"):lower()
else
globe = "earth"
end
latLink = table.concat({latDegrees, latMinutes, latSeconds}, "_")
lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_")
value = "[https://geohack.toolforge.org/geohack.php?language="..self.langCode.."¶ms="..latLink.."_"..latDirectionEN.."_"..lonLink.."_"..lonDirectionEN.."_globe:"..globe.." "..value.."]"
end
return value
elseif datatype == 'wikibase-entityid' then
local label
local itemID = datavalue['numeric-id']
if subtype == 'wikibase-item' then
itemID = "Q" .. itemID
elseif subtype == 'wikibase-property' then
itemID = "P" .. itemID
else
return '<strong class="error">' .. errorText('unknown-data-type', subtype) .. '</strong>'
end
label = self:getLabel(itemID, raw, link, short)
if label == "" then
label = nil
end
return label
else
return '<strong class="error">' .. errorText('unknown-data-type', datatype) .. '</strong>'
end
elseif snak.snaktype == 'somevalue' and not noSpecial then
if raw then
return " " -- single space represents 'somevalue'
else
return i18n['values']['unknown']
end
elseif snak.snaktype == 'novalue' and not noSpecial then
if raw then
return "" -- empty string represents 'novalue'
else
return i18n['values']['none']
end
else
return nil
end
end
function Config:getSingleRawQualifier(claim, qualifierID)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[qualifierID] end
if qualifiers and qualifiers[1] then
return self:getValue(qualifiers[1], true) -- raw = true
else
return nil
end
end
function Config:snakEqualsValue(snak, value)
local snakValue = self:getValue(snak, true) -- raw = true
if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper() end
return snakValue == value
end
function Config:setRank(rank)
local rankPos
if rank == p.flags.best then
self.bestRank = true
self.flagBest = true -- mark that 'best' flag was given
return
end
if rank:sub(1,9) == p.flags.preferred then
rankPos = 1
elseif rank:sub(1,6) == p.flags.normal then
rankPos = 2
elseif rank:sub(1,10) == p.flags.deprecated then
rankPos = 3
else
return
end
-- one of the rank flags was given, check if another one was given before
if not self.flagRank then
self.ranks = {false, false, false} -- no other rank flag given before, so unset ranks
self.bestRank = self.flagBest -- unsets bestRank only if 'best' flag was not given before
self.flagRank = true -- mark that a rank flag was given
end
if rank:sub(-1) == "+" then
for i = rankPos, 1, -1 do
self.ranks[i] = true
end
elseif rank:sub(-1) == "-" then
for i = rankPos, #self.ranks do
self.ranks[i] = true
end
else
self.ranks[rankPos] = true
end
end
function Config:setPeriod(period)
local periodPos
if period == p.flags.future then
periodPos = 1
elseif period == p.flags.current then
periodPos = 2
elseif period == p.flags.former then
periodPos = 3
else
return
end
-- one of the period flags was given, check if another one was given before
if not self.flagPeriod then
self.periods = {false, false, false} -- no other period flag given before, so unset periods
self.flagPeriod = true -- mark that a period flag was given
end
self.periods[periodPos] = true
end
function Config:qualifierMatches(claim, id, value)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[id] end
if qualifiers then
for _, v in pairs(qualifiers) do
if self:snakEqualsValue(v, value) then
return true
end
end
elseif value == "" then
-- if the qualifier is not present then treat it the same as the special value 'novalue'
return true
end
return false
end
function Config:rankMatches(rankPos)
if self.bestRank then
return (self.ranks[rankPos] and self.foundRank >= rankPos)
else
return self.ranks[rankPos]
end
end
function Config:timeMatches(claim)
local startTime = nil
local startTimeY = nil
local startTimeM = nil
local startTimeD = nil
local endTime = nil
local endTimeY = nil
local endTimeM = nil
local endTimeD = nil
if self.periods[1] and self.periods[2] and self.periods[3] then
-- any time
return true
end
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
if startTime and startTime ~= "" and startTime ~= " " then
startTimeY, startTimeM, startTimeD = parseDate(startTime)
end
endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
if endTime and endTime ~= "" and endTime ~= " " then
endTimeY, endTimeM, endTimeD = parseDate(endTime)
end
if startTimeY ~= nil and endTimeY ~= nil and datePrecedesDate(endTimeY, endTimeM, endTimeD, startTimeY, startTimeM, startTimeD) then
-- invalidate end time if it precedes start time
endTimeY = nil
endTimeM = nil
endTimeD = nil
end
if self.periods[1] then
-- future
if startTimeY and datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD) then
return true
end
end
if self.periods[2] then
-- current
if (startTimeY == nil or not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], startTimeY, startTimeM, startTimeD)) and
(endTimeY == nil or datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD)) then
return true
end
end
if self.periods[3] then
-- former
if endTimeY and not datePrecedesDate(self.atDate[1], self.atDate[2], self.atDate[3], endTimeY, endTimeM, endTimeD) then
return true
end
end
return false
end
function Config:processFlag(flag)
if not flag then
return false
end
if flag == p.flags.linked then
self.curState.linked = true
return true
elseif flag == p.flags.raw then
self.curState.rawValue = true
if self.curState == self.states[parameters.reference] then
-- raw reference values end with periods and require a separator (other than none)
self.separators["sep%r"][1] = {" "}
end
return true
elseif flag == p.flags.short then
self.curState.shortName = true
return true
elseif flag == p.flags.multilanguage then
self.curState.anyLanguage = true
return true
elseif flag == p.flags.unit then
self.curState.unitOnly = true
return true
elseif flag == p.flags.mdy then
self.mdyDate = true
return true
elseif flag == p.flags.single then
self.singleClaim = true
return true
elseif flag == p.flags.sourced then
self.sourcedOnly = true
return true
elseif flag == p.flags.edit then
self.editable = true
return true
elseif flag == p.flags.editAtEnd then
self.editable = true
self.editAtEnd = true
return true
elseif flag == p.flags.best or flag:match('^'..p.flags.preferred..'[+-]?$') or flag:match('^'..p.flags.normal..'[+-]?$') or flag:match('^'..p.flags.deprecated..'[+-]?$') then
self:setRank(flag)
return true
elseif flag == p.flags.future or flag == p.flags.current or flag == p.flags.former then
self:setPeriod(flag)
return true
elseif flag == "" then
-- ignore empty flags and carry on
return true
else
return false
end
end
function Config:processFlagOrCommand(flag)
local param = ""
if not flag then
return false
end
if flag == p.claimCommands.property or flag == p.claimCommands.properties then
param = parameters.property
elseif flag == p.claimCommands.qualifier or flag == p.claimCommands.qualifiers then
self.states.qualifiersCount = self.states.qualifiersCount + 1
param = parameters.qualifier .. self.states.qualifiersCount
self.separators["sep"..param] = {copyTable(defaultSeparators["sep%q\\d"])}
elseif flag == p.claimCommands.reference or flag == p.claimCommands.references then
param = parameters.reference
else
return self:processFlag(flag)
end
if self.states[param] then
return false
end
-- create a new state for each command
self.states[param] = State:new(self, param)
-- use "%x" as the general parameter name
self.states[param].parsedFormat = parseFormat(parameters.general) -- will be overwritten for param=="%p"
-- set the separator
self.states[param].separator = self.separators["sep"..param] -- will be nil for param=="%p", which will be set separately
if flag == p.claimCommands.property or flag == p.claimCommands.qualifier or flag == p.claimCommands.reference then
self.states[param].singleValue = true
end
self.curState = self.states[param]
return true
end
function Config:processSeparators(args)
local sep
for i, v in pairs(self.separators) do
if args[i] then
sep = replaceSpecialChars(args[i])
if sep ~= "" then
self.separators[i][1] = {sep}
else
self.separators[i][1] = nil
end
end
end
end
function Config:setFormatAndSeparators(state, parsedFormat)
state.parsedFormat = parsedFormat
state.separator = self.separators["sep"]
state.movSeparator = self.separators["sep"..parameters.separator]
state.puncMark = self.separators["punc"]
end
-- determines if a claim has references by prefetching them from the claim using getReferences,
-- which applies some filtering that determines if a reference is actually returned,
-- and caches the references for later use
function State:isSourced(claim)
self.conf.prefetchedRefs = self:getReferences(claim)
return (#self.conf.prefetchedRefs > 0)
end
function State:resetCaches()
-- any prefetched references of the previous claim must not be used
self.conf.prefetchedRefs = nil
end
function State:claimMatches(claim)
local matches, rankPos
-- first of all, reset any cached values used for the previous claim
self:resetCaches()
-- if a property value was given, check if it matches the claim's property value
if self.conf.propertyValue then
matches = self.conf:snakEqualsValue(claim.mainsnak, self.conf.propertyValue)
else
matches = true
end
-- if any qualifier values were given, check if each matches one of the claim's qualifier values
for i, v in pairs(self.conf.qualifierIDsAndValues) do
matches = (matches and self.conf:qualifierMatches(claim, i, v))
end
-- check if the claim's rank and time period match
rankPos = rankTable[claim.rank] or 4
matches = (matches and self.conf:rankMatches(rankPos) and self.conf:timeMatches(claim))
-- if only claims with references must be returned, check if this one has any
if self.conf.sourcedOnly then
matches = (matches and self:isSourced(claim)) -- prefetches and caches references
end
return matches, rankPos
end
function State:out()
local result -- collection of arrays with value objects
local valuesArray -- array with value objects
local sep = nil -- value object
local out = {} -- array with value objects
local function walk(formatTable, result)
local valuesArray = {} -- array with value objects
for i, v in pairs(formatTable.req) do
if not result[i] or not result[i][1] then
-- we've got no result for a parameter that is required on this level,
-- so skip this level (and its children) by returning an empty result
return {}
end
end
for _, v in ipairs(formatTable) do
if v.param then
valuesArray = mergeArrays(valuesArray, result[v.str])
elseif v.str ~= "" then
valuesArray[#valuesArray + 1] = {v.str}
end
if v.child then
valuesArray = mergeArrays(valuesArray, walk(v.child, result))
end
end
return valuesArray
end
-- iterate through the results from back to front, so that we know when to add separators
for i = #self.results, 1, -1 do
result = self.results[i]
-- if there is already some output, then add the separators
if #out > 0 then
sep = self.separator[1] -- fixed separator
result[parameters.separator] = {self.movSeparator[1]} -- movable separator
else
sep = nil
result[parameters.separator] = {self.puncMark[1]} -- optional punctuation mark
end
valuesArray = walk(self.parsedFormat, result)
if #valuesArray > 0 then
if sep then
valuesArray[#valuesArray + 1] = sep
end
out = mergeArrays(valuesArray, out)
end
end
-- reset state before next iteration
self.results = {}
return out
end
-- level 1 hook
function State:getProperty(claim)
local value = {self:getValue(claim.mainsnak)} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getQualifiers(claim, param)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[self.conf.qualifierIDs[param]] end
if qualifiers then
-- iterate through claim's qualifier statements to collect their values;
-- return array with multiple value objects
return self.conf.states[param]:iterate(qualifiers, {[parameters.general] = hookNames[parameters.qualifier.."\\d"][2], count = 1}) -- pass qualifier state with level 2 hook
else
return {} -- return empty array
end
end
-- level 2 hook
function State:getQualifier(snak)
local value = {self:getValue(snak)} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getAllQualifiers(claim, param, result, hooks)
local out = {} -- array with value objects
local sep = self.conf.separators["sep"..parameters.qualifier][1] -- value object
-- iterate through the output of the separate "qualifier(s)" commands
for i = 1, self.conf.states.qualifiersCount do
-- if a hook has not been called yet, call it now
if not result[parameters.qualifier..i] then
self:callHook(parameters.qualifier..i, hooks, claim, result)
end
-- if there is output for this particular "qualifier(s)" command, then add it
if result[parameters.qualifier..i] and result[parameters.qualifier..i][1] then
-- if there is already some output, then add the separator
if #out > 0 and sep then
out[#out + 1] = sep
end
out = mergeArrays(out, result[parameters.qualifier..i])
end
end
return out
end
-- level 1 hook
function State:getReferences(claim)
if self.conf.prefetchedRefs then
-- return references that have been prefetched by isSourced
return self.conf.prefetchedRefs
end
if claim.references then
-- iterate through claim's reference statements to collect their values;
-- return array with multiple value objects
return self.conf.states[parameters.reference]:iterate(claim.references, {[parameters.general] = hookNames[parameters.reference][2], count = 1}) -- pass reference state with level 2 hook
else
return {} -- return empty array
end
end
-- level 2 hook
function State:getReference(statement)
local citeParamMapping = i18n['cite']['param-mapping']
local citeConfig = i18n['cite']['config']
local citeTypes = i18n['cite']['output-types']
-- for each citation type, there will be an associative array that associates lists of rendered properties
-- to citation-template parameters
local candidateParams = {}
-- like above, but only associates one rendered property to each parameter; if the above variable
-- contains more strings for a parameter, the strings will be assigned to numbered params (e.g. "author1")
local citeParams = {}
local citeErrors = {}
local referenceEmpty = true -- will be set to false if at least one parameter is left unremoved
local version = 13 -- increment this each time the below logic is changed to avoid conflict errors
if not statement.snaks then
return {}
end
-- don't use bot-added references referencing Wikimedia projects or containing "inferred from" (such references are not usable on Wikipedia)
if statement.snaks[aliasesP.importedFrom] or statement.snaks[aliasesP.wikimediaImportURL] or statement.snaks[aliasesP.inferredFrom] then
return {}
end
-- don't include "type of reference"
if statement.snaks[aliasesP.typeOfReference] then
statement.snaks[aliasesP.typeOfReference] = nil
end
-- don't include "image" to prevent littering
if statement.snaks[aliasesP.image] then
statement.snaks[aliasesP.image] = nil
end
-- initialize candidateParams and citeParams
for _, citeType in ipairs(citeTypes) do
candidateParams[citeType] = {}
citeParams[citeType] = {}
end
-- fill candidateParams
for _, citeType in ipairs(citeTypes) do
-- This will contain value--priority pairs for each param name.
local candidateValuesAndPriorities = {}
-- fill candidateValuesAndPriorities
for refProperty in pairs(statement.snaks) do
if citeErrors[citeType] then
break
end
repeat -- just a simple wrapper to emulate "continue"
-- set mappingKey
local mappingKey
if statement.snaks[refProperty][1].datatype == 'external-id' then
mappingKey = "external-id"
else
mappingKey = refProperty
end
local paramName = citeParamMapping[citeType][mappingKey]
-- skip properties with empty parameter name
if paramName == "" then
break -- skip this property for this value of citeType
end
-- handle unknown properties in the reference
if not paramName then
referenceEmpty = false
local propertyWikitext = "[[d:Special:EntityPage/" .. refProperty .. "|" .. self.conf:getLabel(refProperty) .. " (" .. refProperty .. ")]]"
local error_message = errorText("unknown-property-in-ref", propertyWikitext)
assert(error_message) -- Should not be nil
citeErrors[citeType] = error_message
break
end
-- set processedProperty
local processedProperty
local raw = false -- if the value is wanted raw
if isValueInTable(paramName, citeConfig[citeType]["raw-value-params"] or {}) then
raw = true
end
local customRenderer = nil
if citeConfig[citeType]["customRenderers"] then
customRenderer = citeConfig[citeType]["customRenderers"][paramName]
end
if isValueInTable(paramName, citeConfig[citeType]["numbered-params"] or {}) then
-- Multiple values may be given.
processedProperty = self:getReferenceDetails(statement.snaks, refProperty, raw, self.linked, true, customRenderer) -- anyLang = true
else
-- If multiple values are given, all but the first suitable one are discarted.
processedProperty = {self:getReferenceDetail(statement.snaks, refProperty, raw, self.linked and (statement.snaks[refProperty][1].datatype ~= 'url'), true, customRenderer)} -- link = true/false, anyLang = true
end
if #processedProperty == 0 then
break
end
referenceEmpty = false
-- add an empty entry to candidateValuesAndPriorities, if there isn't one already
if not candidateValuesAndPriorities[paramName] then
candidateValuesAndPriorities[paramName] = {}
end
-- find the priority of refProperty
-- (the actual index is mappingKey, not refProperty, because of external IDs)
local thisPropertyPriority = -1
local thisParamPrioritization = (citeConfig[citeType]["prioritization"] or {})[paramName]
if thisParamPrioritization then
for i_priority, i_key in ipairs(thisParamPrioritization) do
if i_key == mappingKey then
thisPropertyPriority = i_priority
end
end
end
for _, propertyValue in pairs(processedProperty) do
table.insert(
candidateValuesAndPriorities[paramName],
{propertyValue, thisPropertyPriority}
)
end
until true
end
-- fill candidateParams[citeType]
if not citeErrors[citeType] then
local compareValuePriorities = function(pair1, pair2)
if pair1[2] == -1 and pair2[2] ~= -1 then
return false
end
if pair1[2] ~= -1 and pair2[2] == -1 then
return true
end
return pair1[2] < pair2[2]
end
-- fill candidateParams[citeType][paramName] for each used param
for paramName, _ in pairs(candidateValuesAndPriorities) do
table.sort(candidateValuesAndPriorities[paramName], compareValuePriorities)
candidateParams[citeType][paramName] = {}
for _, valuePriorityPair in ipairs(candidateValuesAndPriorities[paramName]) do
table.insert(candidateParams[citeType][paramName], valuePriorityPair[1])
end
end
end
end
-- fill citeParams
for _, citeType in ipairs(citeTypes) do
for paramName, paramValues in pairs(candidateParams[citeType]) do
if #paramValues == 1 or not isValueInTable(paramName, citeConfig[citeType]["numbered-params"] or {}) then
citeParams[citeType][paramName] = paramValues[1]
else
-- There is more than one value for this parameter - the values will
-- go into separate numbered parameters (e.g. "author1", "author2")
for paramNum, paramValue in pairs(paramValues) do
citeParams[citeType][paramName .. paramNum] = paramValue
end
end
end
end
-- handle missing mandatory parameters for the templates
for _, citeType in ipairs(citeTypes) do
for _, requiredCiteParam in pairs(citeConfig[citeType]["mandatory-params"] or {}) do
if not citeParams[citeType][requiredCiteParam] then -- The required param is not present.
if citeErrors[citeType] then -- Do not override the previous error, if it exists.
break
end
local error_message = errorText("missing-mandatory-param", requiredCiteParam)
assert(error_message) -- Should not be nil
citeErrors[citeType] = error_message
end
end
end
local citeTypeToUse = nil
-- choose the output template
for _, citeType in ipairs(citeTypes) do
if not citeErrors[citeType] then
citeTypeToUse = citeType
break
end
end
-- set refContent
local refContent = ""
if citeTypeToUse then
local templateToUse = citeConfig[citeTypeToUse]["template"]
local paramsToUse = citeParams[citeTypeToUse]
if not templateToUse or templateToUse == "" then
throwError("no-such-reference-template", tostring(templateToUse), i18nPath, citeTypeToUse)
end
-- if this module is being substituted then build a regular template call, otherwise expand the template
if mw.isSubsting() then
for i, v in pairs(paramsToUse) do
refContent = refContent .. "|" .. i .. "=" .. v
end
refContent = "{{" .. templateToUse .. refContent .. "}}"
else
xpcall(
function () refContent = mw.getCurrentFrame():expandTemplate{title=templateToUse, args=paramsToUse} end,
function () throwError("no-such-reference-template", templateToUse, i18nPath, citeTypeToUse) end
)
end
-- If the citation couldn't be displayed using any template, but is not empty (barring ignored propeties), throw an error.
elseif not referenceEmpty then
refContent = errorText("malformed-reference-header")
for _, citeType in ipairs(citeTypes) do
local templateWikitext = "<nowiki>{{</nowiki>[[Template:" .. citeConfig[citeType]["template"] .. "|" .. citeConfig[citeType]["template"] .. "]]<nowiki>}}</nowiki>"
refContent = refContent .. errorText("template-failure-reason", templateWikitext, citeErrors[citeType])
end
refContent = refContent .. errorText("malformed-reference-footer")
end
-- wrap refContent
local ref = {}
if refContent ~= "" then
ref = {refContent}
if not self.rawValue then
-- this should become a <ref> tag, so save the reference's hash for later
ref.refHash = "wikidata-" .. statement.hash .. "-v" .. (tonumber(i18n['version']) + version)
end
return {ref}
else
return {}
end
end
-- gets a detail of one particular type for a reference
function State:getReferenceDetail(snaks, dType, raw, link, anyLang, customRenderer)
local switchLang = anyLang
local value = nil
if not snaks[dType] then
return nil
end
-- if anyLang, first try the local language and otherwise any language
repeat
for _, v in ipairs(snaks[dType]) do
local defaultRenderer = function ()
return self.conf:getValue(v, raw, link, false, anyLang and not switchLang, false, true) -- noSpecial = true
end
if customRenderer then
value = customRenderer(
v, dType,
defaultRenderer,
p._properties,
function (...) return self.conf:getValue(unpack(arg)) end,
snaks
)
else
value = defaultRenderer()
end
if value then
break
end
end
if value or not anyLang then
break
end
switchLang = not switchLang
until anyLang and switchLang
return value
end
-- gets the details of one particular type for a reference
function State:getReferenceDetails(snaks, dType, raw, link, anyLang, customRenderer)
local values = {}
if not snaks[dType] then
return {}
end
for _, v in ipairs(snaks[dType]) do
local defaultRenderer = function ()
return self.conf:getValue(v, raw, link, false, anyLang, false, true) -- noSpecial = true
end
local value
if customRenderer then
value = customRenderer(
v, dType,
defaultRenderer,
p._properties,
function (...) return self.conf:getValue(unpack(arg)) end,
snaks
)
else
value = defaultRenderer()
end
-- if value is nil then it will not be added to the table
values[#values + 1] = value
end
return values
end
-- level 1 hook
function State:getAlias(object)
local value = object.value
local title = nil
if value and self.linked then
if self.conf.entityID:sub(1,1) == "Q" then
title = mw.wikibase.getSitelink(self.conf.entityID)
elseif self.conf.entityID:sub(1,1) == "P" then
title = "d:Property:" .. self.conf.entityID
end
if title then
value = buildWikilink(title, value)
end
end
value = {value} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
-- level 1 hook
function State:getBadge(value)
value = self.conf:getLabel(value, self.rawValue, self.linked, self.shortName)
if value == "" then
value = nil
end
value = {value} -- create one value object
if #value > 0 then
return {value} -- wrap the value object in an array and return it
else
return {} -- return empty array if there was no value
end
end
function State:callHook(param, hooks, statement, result)
-- call a parameter's hook if it has been defined and if it has not been called before
if not result[param] and hooks[param] then
local valuesArray = self[hooks[param]](self, statement, param, result, hooks) -- array with value objects
-- add to the result
if #valuesArray > 0 then
result[param] = valuesArray
result.count = result.count + 1
else
result[param] = {} -- an empty array to indicate that we've tried this hook already
return true -- miss == true
end
end
return false
end
-- iterate through claims, claim's qualifiers or claim's references to collect values
function State:iterate(statements, hooks, matchHook)
matchHook = matchHook or alwaysTrue
local matches = false
local rankPos = nil
local result, gotRequired
for _, v in ipairs(statements) do
-- rankPos will be nil for non-claim statements (e.g. qualifiers, references, etc.)
matches, rankPos = matchHook(self, v)
if matches then
result = {count = 0} -- collection of arrays with value objects
local function walk(formatTable)
local miss
for i2, v2 in pairs(formatTable.req) do
-- call a hook, adding its return value to the result
miss = self:callHook(i2, hooks, v, result)
if miss then
-- we miss a required value for this level, so return false
return false
end
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point breaks the loop
return true
end
end
for _, v2 in ipairs(formatTable) do
if result.count == hooks.count then
-- we're done if all hooks have been called;
-- returning at this point prevents further childs from being processed
return true
end
if v2.child then
walk(v2.child)
end
end
return true
end
gotRequired = walk(self.parsedFormat)
-- only append the result if we got values for all required parameters on the root level
if gotRequired then
-- if we have a rankPos (only with matchHook() for complete claims), then update the foundRank
if rankPos and self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos
end
-- append the result
self.results[#self.results + 1] = result
-- break if we only need a single value
if self.singleValue then
break
end
end
end
end
return self:out()
end
local function getEntityId(arg, eid, page, allowOmitPropPrefix, globalSiteId)
local id = nil
local prop = nil
if arg then
if arg:sub(1,1) == ":" then
page = arg
eid = nil
elseif arg:sub(1,1):upper() == "Q" or arg:sub(1,9):lower() == "property:" or allowOmitPropPrefix then
eid = arg
page = nil
else
prop = arg
end
end
if eid then
if eid:sub(1,9):lower() == "property:" then
id = replaceAlias(mw.text.trim(eid:sub(10)))
if id:sub(1,1):upper() ~= "P" then
id = ""
end
else
id = replaceAlias(eid)
end
elseif page then
if page:sub(1,1) == ":" then
page = mw.text.trim(page:sub(2))
end
id = mw.wikibase.getEntityIdForTitle(page, globalSiteId) or ""
end
if not id then
id = mw.wikibase.getEntityIdForCurrentPage() or ""
end
id = id:upper()
if not mw.wikibase.isValidEntityId(id) then
id = ""
end
return id, prop
end
local function nextArg(args)
local arg = args[args.pointer]
if arg then
args.pointer = args.pointer + 1
return mw.text.trim(arg)
else
return nil
end
end
local function claimCommand(args, funcName)
local cfg = Config:new()
cfg:processFlagOrCommand(funcName) -- process first command (== function name)
local lastArg, parsedFormat, formatParams, claims, value
local hooks = {count = 0}
-- set the date if given;
-- must come BEFORE processing the flags
if args[p.args.date] then
cfg.atDate = {parseDate(args[p.args.date])}
cfg.periods = {false, true, false} -- change default time constraint to 'current'
end
-- process flags and commands
repeat
lastArg = nextArg(args)
until not cfg:processFlagOrCommand(lastArg)
-- get the entity ID from either the positional argument, the eid argument or the page argument
cfg.entityID, cfg.propertyID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], false, args[p.args.globalSiteId])
if cfg.entityID == "" then
return "" -- we cannot continue without a valid entity ID
end
cfg.entity = mw.wikibase.getEntity(cfg.entityID)
if not cfg.propertyID then
cfg.propertyID = nextArg(args)
end
cfg.propertyID = replaceAlias(cfg.propertyID)
if not cfg.entity or not cfg.propertyID then
return "" -- we cannot continue without an entity or a property ID
end
cfg.propertyID = cfg.propertyID:upper()
if not cfg.entity.claims or not cfg.entity.claims[cfg.propertyID] then
return "" -- there is no use to continue without any claims
end
claims = cfg.entity.claims[cfg.propertyID]
if cfg.states.qualifiersCount > 0 then
-- do further processing if "qualifier(s)" command was given
if #args - args.pointer + 1 > cfg.states.qualifiersCount then
-- claim ID or literal value has been given
cfg.propertyValue = nextArg(args)
end
for i = 1, cfg.states.qualifiersCount do
-- check if given qualifier ID is an alias and add it
cfg.qualifierIDs[parameters.qualifier..i] = replaceAlias(nextArg(args) or ""):upper()
end
elseif cfg.states[parameters.reference] then
-- do further processing if "reference(s)" command was given
cfg.propertyValue = nextArg(args)
end
-- check for special property value 'somevalue' or 'novalue'
if cfg.propertyValue then
cfg.propertyValue = replaceSpecialChars(cfg.propertyValue)
if cfg.propertyValue ~= "" and mw.text.trim(cfg.propertyValue) == "" then
cfg.propertyValue = " " -- single space represents 'somevalue', whereas empty string represents 'novalue'
else
cfg.propertyValue = mw.text.trim(cfg.propertyValue)
end
end
-- parse the desired format, or choose an appropriate format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
elseif cfg.states.qualifiersCount > 0 then -- "qualifier(s)" command given
if cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier)
else
parsedFormat, formatParams = parseFormat(formats.qualifier)
end
elseif cfg.states[parameters.property] then -- "propert(y|ies)" command given
parsedFormat, formatParams = parseFormat(formats.property)
else -- "reference(s)" command given
parsedFormat, formatParams = parseFormat(formats.reference)
end
-- if a "qualifier(s)" command and no "propert(y|ies)" command has been given, make the movable separator a semicolon
if cfg.states.qualifiersCount > 0 and not cfg.states[parameters.property] then
cfg.separators["sep"..parameters.separator][1] = {";"}
end
-- if only "reference(s)" has been given, set the default separator to none (except when raw)
if cfg.states[parameters.reference] and not cfg.states[parameters.property] and cfg.states.qualifiersCount == 0
and not cfg.states[parameters.reference].rawValue then
cfg.separators["sep"][1] = nil
end
-- if exactly one "qualifier(s)" command has been given, make "sep%q" point to "sep%q1" to make them equivalent
if cfg.states.qualifiersCount == 1 then
cfg.separators["sep"..parameters.qualifier] = cfg.separators["sep"..parameters.qualifier.."1"]
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hooks that should be called (getProperty, getQualifiers, getReferences);
-- only define a hook if both its command ("propert(y|ies)", "reference(s)", "qualifier(s)") and its parameter ("%p", "%r", "%q1", "%q2", "%q3") have been given
for i, v in pairs(cfg.states) do
-- e.g. 'formatParams["%q1"] or formatParams["%q"]' to define hook even if "%q1" was not defined to be able to build a complete value for "%q"
if formatParams[i] or formatParams[i:sub(1, 2)] then
hooks[i] = getHookName(i, 1)
hooks.count = hooks.count + 1
end
end
-- the "%q" parameter is not attached to a state, but is a collection of the results of multiple states (attached to "%q1", "%q2", "%q3", ...);
-- so if this parameter is given then this hook must be defined separately, but only if at least one "qualifier(s)" command has been given
if formatParams[parameters.qualifier] and cfg.states.qualifiersCount > 0 then
hooks[parameters.qualifier] = getHookName(parameters.qualifier, 1)
hooks.count = hooks.count + 1
end
-- create a state for "properties" if it doesn't exist yet, which will be used as a base configuration for each claim iteration;
-- must come AFTER defining the hooks
if not cfg.states[parameters.property] then
cfg.states[parameters.property] = State:new(cfg, parameters.property)
-- if the "single" flag has been given then this state should be equivalent to "property" (singular)
if cfg.singleClaim then
cfg.states[parameters.property].singleValue = true
end
end
-- if the "sourced" flag has been given then create a state for "reference" if it doesn't exist yet, using default values,
-- which must exist in order to be able to determine if a claim has any references;
-- must come AFTER defining the hooks
if cfg.sourcedOnly and not cfg.states[parameters.reference] then
cfg:processFlagOrCommand(p.claimCommands.reference) -- use singular "reference" to minimize overhead
end
-- set the parsed format and the separators (and optional punctuation mark);
-- must come AFTER creating the additonal states
cfg:setFormatAndSeparators(cfg.states[parameters.property], parsedFormat)
-- process qualifier matching values, analogous to cfg.propertyValue
for i, v in pairs(args) do
i = tostring(i)
if i:match('^[Pp]%d+$') or aliasesP[i] then
v = replaceSpecialChars(v)
-- check for special qualifier value 'somevalue'
if v ~= "" and mw.text.trim(v) == "" then
v = " " -- single space represents 'somevalue'
end
cfg.qualifierIDsAndValues[replaceAlias(i):upper()] = v
end
end
-- first sort the claims on rank to pre-define the order of output (preferred first, then normal, then deprecated)
claims = sortOnRank(claims)
-- then iterate through the claims to collect values
value = cfg:concatValues(cfg.states[parameters.property]:iterate(claims, hooks, State.claimMatches)) -- pass property state with level 1 hooks and matchHook
-- if desired, add a clickable icon that may be used to edit the returned values on Wikidata
if cfg.editable and value ~= "" then
value = value .. cfg:getEditIcon()
end
return value
end
local function generalCommand(args, funcName)
local cfg = Config:new()
cfg.curState = State:new(cfg)
local lastArg
local value = nil
repeat
lastArg = nextArg(args)
until not cfg:processFlag(lastArg)
-- get the entity ID from either the positional argument, the eid argument or the page argument
cfg.entityID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], true, args[p.args.globalSiteId])
if cfg.entityID == "" or not mw.wikibase.entityExists(cfg.entityID) then
return "" -- we cannot continue without an entity
end
-- serve according to the given command
if funcName == p.generalCommands.label then
value = cfg:getLabel(cfg.entityID, cfg.curState.rawValue, cfg.curState.linked, cfg.curState.shortName)
elseif funcName == p.generalCommands.title then
cfg.inSitelinks = true
if cfg.entityID:sub(1,1) == "Q" then
value = mw.wikibase.getSitelink(cfg.entityID)
end
if cfg.curState.linked and value then
value = buildWikilink(value)
end
elseif funcName == p.generalCommands.description then
value = mw.wikibase.getDescription(cfg.entityID)
else
local parsedFormat, formatParams
local hooks = {count = 0}
cfg.entity = mw.wikibase.getEntity(cfg.entityID)
if funcName == p.generalCommands.alias or funcName == p.generalCommands.badge then
cfg.curState.singleValue = true
end
if funcName == p.generalCommands.alias or funcName == p.generalCommands.aliases then
if not cfg.entity.aliases or not cfg.entity.aliases[cfg.langCode] then
return "" -- there is no use to continue without any aliasses
end
local aliases = cfg.entity.aliases[cfg.langCode]
-- parse the desired format, or parse the default aliases format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
else
parsedFormat, formatParams = parseFormat(formats.alias)
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hook that should be called (getAlias);
-- only define the hook if the parameter ("%a") has been given
if formatParams[parameters.alias] then
hooks[parameters.alias] = getHookName(parameters.alias, 1)
hooks.count = hooks.count + 1
end
-- set the parsed format and the separators (and optional punctuation mark)
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
-- iterate to collect values
value = cfg:concatValues(cfg.curState:iterate(aliases, hooks))
elseif funcName == p.generalCommands.badge or funcName == p.generalCommands.badges then
if not cfg.entity.sitelinks or not cfg.entity.sitelinks[cfg.siteID] or not cfg.entity.sitelinks[cfg.siteID].badges then
return "" -- there is no use to continue without any badges
end
local badges = cfg.entity.sitelinks[cfg.siteID].badges
cfg.inSitelinks = true
-- parse the desired format, or parse the default aliases format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
else
parsedFormat, formatParams = parseFormat(formats.badge)
end
-- process overridden separator values;
-- must come AFTER tweaking the default separators
cfg:processSeparators(args)
-- define the hook that should be called (getBadge);
-- only define the hook if the parameter ("%b") has been given
if formatParams[parameters.badge] then
hooks[parameters.badge] = getHookName(parameters.badge, 1)
hooks.count = hooks.count + 1
end
-- set the parsed format and the separators (and optional punctuation mark)
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
-- iterate to collect values
value = cfg:concatValues(cfg.curState:iterate(badges, hooks))
end
end
value = value or ""
if cfg.editable and value ~= "" then
-- if desired, add a clickable icon that may be used to edit the returned value on Wikidata
value = value .. cfg:getEditIcon()
end
return value
end
-- modules that include this module should call the functions with an underscore prepended, e.g.: p._property(args)
local function establishCommands(commandList, commandFunc)
for _, commandName in pairs(commandList) do
local function wikitextWrapper(frame)
local args = copyTable(frame.args)
args.pointer = 1
loadI18n(aliasesP, frame)
return commandFunc(args, commandName)
end
p[commandName] = wikitextWrapper
local function luaWrapper(args)
args = copyTable(args)
args.pointer = 1
loadI18n(aliasesP)
return commandFunc(args, commandName)
end
p["_" .. commandName] = luaWrapper
end
end
establishCommands(p.claimCommands, claimCommand)
establishCommands(p.generalCommands, generalCommand)
-- main function that is supposed to be used by wrapper templates
function p.main(frame)
if not mw.wikibase then return nil end
local f, args
loadI18n(aliasesP, frame)
-- get the parent frame to take the arguments that were passed to the wrapper template
frame = frame:getParent() or frame
if not frame.args[1] then
throwError("no-function-specified")
end
f = mw.text.trim(frame.args[1])
if f == "main" then
throwError("main-called-twice")
end
assert(p["_"..f], errorText('no-such-function', f))
-- copy arguments from immutable to mutable table
args = copyTable(frame.args)
-- remove the function name from the list
table.remove(args, 1)
return p["_"..f](args)
end
return p
dyjtoxlu5p2mq8c2h4dmvnmhx8qx22r
Module:Wd/i18n
828
13419
124181
116960
2026-11-05T22:01:07Z
en>Janhrach
0
update from sandbox; see [[Module talk:Wd#Proposed update: customizable snak-->param rendering, related changes, misc. bugfixes]]
124181
Scribunto
text/plain
-- The values and functions in this submodule should be localized per wiki.
local p = {}
function p.init(aliasesP)
p = {
["version"] = "9", -- increment this each time the below parameters are changed to avoid reference conflict errors
["errors"] = {
["unknown-data-type"] = "Unknown or unsupported datatype '%s'.",
["missing-required-parameter"] = "No required parameters defined, needing at least one",
["extra-required-parameter"] = "Parameter '%s' must be defined as optional",
["no-function-specified"] = "You must specify a function to call", -- equal to the standard module error message
["main-called-twice"] = 'The function "main" cannot be called twice',
["no-such-function"] = 'The function "%s" does not exist', -- equal to the standard module error message
["no-such-reference-template"] = 'Error: template "%s", which is set in %s as the output template for the citation-output type "%s", does not exist',
-- Parts of the error message signalling a malformed reference.
["malformed-reference-header"] = "<div style=\"color:#dd3333\">\nError: Unable to display the reference from Wikidata properly. Technical details:\n",
["malformed-reference-footer"] = "See [[Module:wd/doc#References|the documentation]] for further details.\n</div>\n[[Category:Module:Wd reference errors]]",
["template-failure-reason"] = "* Reason for the failure of %s: %s\n",
["missing-mandatory-param"] = 'The output template call would miss the mandatory parameter <code>%s</code>.',
["unknown-property-in-ref"] = 'The Wikidata reference contains the property %s, which is not assigned to any parameter of this template.'
},
["info"] = {
["edit-on-wikidata"] = "Edit this on Wikidata"
},
["numeric"] = {
["decimal-mark"] = ".",
["delimiter"] = ","
},
["datetime"] = {
["prefixes"] = {
["decade-period"] = ""
},
["suffixes"] = {
["decade-period"] = "s",
["millennium"] = " millennium",
["century"] = " century",
["million-years"] = " million years",
["billion-years"] = " billion years",
["year"] = " year",
["years"] = " years"
},
["julian-calendar"] = "Julian calendar", -- linked page title
["julian"] = "Julian",
["BCE"] = "BCE",
["CE"] = "CE",
["common-era"] = "Common Era" -- linked page title
},
["coord"] = {
["latitude-north"] = "N",
["latitude-south"] = "S",
["longitude-east"] = "E",
["longitude-west"] = "W",
["degrees"] = "°",
["minutes"] = "'",
["seconds"] = '"',
["separator"] = ", "
},
["values"] = {
["unknown"] = "unknown",
["none"] = "none"
},
["cite"] = {
["output-types"] = {"web", "q"}, -- In this order, the output types will be tried
["param-mapping"] = {
["web"] = {
-- <= left side: all allowed reference properties for *web page sources* per https://www.wikidata.org/wiki/Help:Sources
-- => right side: corresponding parameter names in (equivalent of) [[:en:Template:Cite web]] (if non-existent, keep empty i.e. "")
[aliasesP.statedIn] = "website",
[aliasesP.referenceURL] = "url",
[aliasesP.publicationDate] = "date",
[aliasesP.lastUpdate] = "date",
[aliasesP.retrieved] = "access-date",
[aliasesP.title] = "title",
[aliasesP.subjectNamedAs] = "title",
[aliasesP.archiveURL] = "archive-url",
[aliasesP.archiveDate] = "archive-date",
[aliasesP.language] = "language",
[aliasesP.author] = "author",
[aliasesP.authorNameString] = "author",
[aliasesP.publisher] = "publisher",
[aliasesP.quote] = "quote",
[aliasesP.pages] = "pages", -- extra option
[aliasesP.publishedIn] = "website",
[aliasesP.sectionVerseOrParagraph] = "at",
["external-id"] = "url", -- used for any type of database property ID
},
["q"] = {
-- <= left side: all allowed reference properties for *sources other than web pages* per https://www.wikidata.org/wiki/Help:Sources
-- => right side: corresponding parameter names in (equivalent of) [[:en:Template:Cite Q]] (if non-existent, keep empty i.e. "")
[aliasesP.statedIn] = "1",
[aliasesP.pages] = "pages",
[aliasesP.column] = "at",
[aliasesP.chapter] = "chapter",
[aliasesP.sectionVerseOrParagraph] = "section",
["external-id"] = "id", -- used for any type of database property ID
[aliasesP.title] = "title",
[aliasesP.publicationDate] = "date",
[aliasesP.lastUpdate] = "date",
[aliasesP.retrieved] = "access-date"
}
},
["config"] = {
-- supported fields:
-- - template: name of the template used for output
-- - numbered-params:
-- citation params accepting an arbitrary number of values
-- by numbering the params (e.g. author1, author2)
-- - raw-value-params:
-- params taking a raw value (which means the property is
-- rendered with getValue with raw=true)
-- - mandatory-params:
-- params that are required to be in the template call
-- (after potentially appending numbers
-- to params listed in numbered-params)
-- - prioritization:
-- table associating a list of properties, in the order
-- in which they are preferred, to template parameters;
-- properties not mentioned here have the lowest priority;
-- no key of this table can be from numbered-params
-- - customRenderers:
-- functions that override the default way a single
-- Wikidata value is rendered (converted into a suitable
-- template argument) for the given template parameter;
-- these functions receive the following arguments:
-- snak -- the Wikidata value to be rendered
-- refProperty -- the property with which `snak` is associated;
-- this is useful if this custom renderer handles
-- multiple properties
-- defaultRenderer -- argumentless function that returns a string
-- containing the default rendering of `snak`
-- propertiesFunc -- the function `_properties`, as defined by the wd module
-- getValue -- the internal module function used for rendering snaks
-- Leaving out the "template" field causes the output type to be ignored.
["web"] = {
["template"] = "Cite web",
["numbered-params"] = {"author"},
["mandatory-params"] = {"url"},
["prioritization"] = {
["date"] = {aliasesP.lastUpdate, aliasesP.publicationDate},
["title"] = {aliasesP.title, aliasesP.subjectNamedAs},
["url"] = {aliasesP.referenceURL, "external-id"}
},
["customRenderers"] = {
["language"] = function (snak, _, defaultRenderer, propertiesFunc, getValue)
-- Discart the local language.
local langQID = getValue(snak, true, false) -- argument explanation: raw, not linked
if mw.language.getContentLanguage().code == propertiesFunc{aliasesP.wikimediaLanguageCode, ["eid"] = langQID} then
return nil
end
return defaultRenderer()
end,
["url"] = function (snak, refProperty, defaultRenderer, propertiesFunc, getValue, snaks)
if refProperty == aliasesP.referenceURL then
-- plain URLs from Wikidata don't need special handling.
return defaultRenderer()
end
-- Now we know that `snak` contains an external ID. We want to convert it into a URL.
if not snaks[aliasesP.statedIn] then
-- No source database is cited explicitly. Wikidata discourages this.
return nil -- Don't return anything in this case.
end
-- Check if the ID indeed refers to the cited source given in the "Stated in" field.
local citedSourceQID = getValue(snaks[aliasesP.statedIn][1], true, false) -- argument explanation: raw, not linked
local sourceAssociatedProps = propertiesFunc{"raw", aliasesP.wikidataProperty, ["eid"] = citedSourceQID} -- fetch the associated properties for the cited source
for i, associatedProp in pairs(mw.text.split(sourceAssociatedProps, ", ", true)) do
if associatedProp == refProperty then
-- The external ID indeed refers to the source identified by citedSourceQID.
local renderedSnak = getValue(snak, false, true) -- not raw, linked
if mw.ustring.match(renderedSnak, "^%[%Z- %Z+%]$") then
-- The last getValue call returned a URL in square brackets.
-- strip link wikisyntax, and return the bare URL
local url = mw.ustring.gsub(renderedSnak, "^%[(%Z-) %Z+%]$", "%1") -- gsub returns two values
return url
end
end
end
end,
}
},
["q"] = {
["template"] = "Cite Q",
["raw-value-params"] = {"1"}, -- the first, unnamed parameter of CiteQ takes a QID, not the name of the item cited
["mandatory-params"] = {"1"},
["prioritization"] = {
["date"] = {aliasesP.lastUpdate, aliasesP.publicationDate}
},
["customRenderers"] = {
["id"] = function (_, refProperty, defaultRenderer)
local output = defaultRenderer()
if output then
output = mw.wikibase.getLabel(refProperty) .. " " .. output
end
return output
end,
}
}
}
}
}
p.getOrdinalSuffix = function(num)
if tostring(num):sub(-2,-2) == '1' then
return "th" -- 10th, 11th, 12th, 13th, ... 19th
end
num = tostring(num):sub(-1)
if num == '1' then
return "st"
elseif num == '2' then
return "nd"
elseif num == '3' then
return "rd"
else
return "th"
end
end
p.addDelimiters = function(n)
local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$")
if left and num and right then
return left .. (num:reverse():gsub("(%d%d%d)", "%1" .. p['numeric']['delimiter']):reverse()) .. right
else
return n
end
end
return p
end
return p
oxg4xygireze1hyk3uq0s2xrq92yivw
124182
124181
2026-11-09T20:20:39Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Wd/i18n]]
124181
Scribunto
text/plain
-- The values and functions in this submodule should be localized per wiki.
local p = {}
function p.init(aliasesP)
p = {
["version"] = "9", -- increment this each time the below parameters are changed to avoid reference conflict errors
["errors"] = {
["unknown-data-type"] = "Unknown or unsupported datatype '%s'.",
["missing-required-parameter"] = "No required parameters defined, needing at least one",
["extra-required-parameter"] = "Parameter '%s' must be defined as optional",
["no-function-specified"] = "You must specify a function to call", -- equal to the standard module error message
["main-called-twice"] = 'The function "main" cannot be called twice',
["no-such-function"] = 'The function "%s" does not exist', -- equal to the standard module error message
["no-such-reference-template"] = 'Error: template "%s", which is set in %s as the output template for the citation-output type "%s", does not exist',
-- Parts of the error message signalling a malformed reference.
["malformed-reference-header"] = "<div style=\"color:#dd3333\">\nError: Unable to display the reference from Wikidata properly. Technical details:\n",
["malformed-reference-footer"] = "See [[Module:wd/doc#References|the documentation]] for further details.\n</div>\n[[Category:Module:Wd reference errors]]",
["template-failure-reason"] = "* Reason for the failure of %s: %s\n",
["missing-mandatory-param"] = 'The output template call would miss the mandatory parameter <code>%s</code>.',
["unknown-property-in-ref"] = 'The Wikidata reference contains the property %s, which is not assigned to any parameter of this template.'
},
["info"] = {
["edit-on-wikidata"] = "Edit this on Wikidata"
},
["numeric"] = {
["decimal-mark"] = ".",
["delimiter"] = ","
},
["datetime"] = {
["prefixes"] = {
["decade-period"] = ""
},
["suffixes"] = {
["decade-period"] = "s",
["millennium"] = " millennium",
["century"] = " century",
["million-years"] = " million years",
["billion-years"] = " billion years",
["year"] = " year",
["years"] = " years"
},
["julian-calendar"] = "Julian calendar", -- linked page title
["julian"] = "Julian",
["BCE"] = "BCE",
["CE"] = "CE",
["common-era"] = "Common Era" -- linked page title
},
["coord"] = {
["latitude-north"] = "N",
["latitude-south"] = "S",
["longitude-east"] = "E",
["longitude-west"] = "W",
["degrees"] = "°",
["minutes"] = "'",
["seconds"] = '"',
["separator"] = ", "
},
["values"] = {
["unknown"] = "unknown",
["none"] = "none"
},
["cite"] = {
["output-types"] = {"web", "q"}, -- In this order, the output types will be tried
["param-mapping"] = {
["web"] = {
-- <= left side: all allowed reference properties for *web page sources* per https://www.wikidata.org/wiki/Help:Sources
-- => right side: corresponding parameter names in (equivalent of) [[:en:Template:Cite web]] (if non-existent, keep empty i.e. "")
[aliasesP.statedIn] = "website",
[aliasesP.referenceURL] = "url",
[aliasesP.publicationDate] = "date",
[aliasesP.lastUpdate] = "date",
[aliasesP.retrieved] = "access-date",
[aliasesP.title] = "title",
[aliasesP.subjectNamedAs] = "title",
[aliasesP.archiveURL] = "archive-url",
[aliasesP.archiveDate] = "archive-date",
[aliasesP.language] = "language",
[aliasesP.author] = "author",
[aliasesP.authorNameString] = "author",
[aliasesP.publisher] = "publisher",
[aliasesP.quote] = "quote",
[aliasesP.pages] = "pages", -- extra option
[aliasesP.publishedIn] = "website",
[aliasesP.sectionVerseOrParagraph] = "at",
["external-id"] = "url", -- used for any type of database property ID
},
["q"] = {
-- <= left side: all allowed reference properties for *sources other than web pages* per https://www.wikidata.org/wiki/Help:Sources
-- => right side: corresponding parameter names in (equivalent of) [[:en:Template:Cite Q]] (if non-existent, keep empty i.e. "")
[aliasesP.statedIn] = "1",
[aliasesP.pages] = "pages",
[aliasesP.column] = "at",
[aliasesP.chapter] = "chapter",
[aliasesP.sectionVerseOrParagraph] = "section",
["external-id"] = "id", -- used for any type of database property ID
[aliasesP.title] = "title",
[aliasesP.publicationDate] = "date",
[aliasesP.lastUpdate] = "date",
[aliasesP.retrieved] = "access-date"
}
},
["config"] = {
-- supported fields:
-- - template: name of the template used for output
-- - numbered-params:
-- citation params accepting an arbitrary number of values
-- by numbering the params (e.g. author1, author2)
-- - raw-value-params:
-- params taking a raw value (which means the property is
-- rendered with getValue with raw=true)
-- - mandatory-params:
-- params that are required to be in the template call
-- (after potentially appending numbers
-- to params listed in numbered-params)
-- - prioritization:
-- table associating a list of properties, in the order
-- in which they are preferred, to template parameters;
-- properties not mentioned here have the lowest priority;
-- no key of this table can be from numbered-params
-- - customRenderers:
-- functions that override the default way a single
-- Wikidata value is rendered (converted into a suitable
-- template argument) for the given template parameter;
-- these functions receive the following arguments:
-- snak -- the Wikidata value to be rendered
-- refProperty -- the property with which `snak` is associated;
-- this is useful if this custom renderer handles
-- multiple properties
-- defaultRenderer -- argumentless function that returns a string
-- containing the default rendering of `snak`
-- propertiesFunc -- the function `_properties`, as defined by the wd module
-- getValue -- the internal module function used for rendering snaks
-- Leaving out the "template" field causes the output type to be ignored.
["web"] = {
["template"] = "Cite web",
["numbered-params"] = {"author"},
["mandatory-params"] = {"url"},
["prioritization"] = {
["date"] = {aliasesP.lastUpdate, aliasesP.publicationDate},
["title"] = {aliasesP.title, aliasesP.subjectNamedAs},
["url"] = {aliasesP.referenceURL, "external-id"}
},
["customRenderers"] = {
["language"] = function (snak, _, defaultRenderer, propertiesFunc, getValue)
-- Discart the local language.
local langQID = getValue(snak, true, false) -- argument explanation: raw, not linked
if mw.language.getContentLanguage().code == propertiesFunc{aliasesP.wikimediaLanguageCode, ["eid"] = langQID} then
return nil
end
return defaultRenderer()
end,
["url"] = function (snak, refProperty, defaultRenderer, propertiesFunc, getValue, snaks)
if refProperty == aliasesP.referenceURL then
-- plain URLs from Wikidata don't need special handling.
return defaultRenderer()
end
-- Now we know that `snak` contains an external ID. We want to convert it into a URL.
if not snaks[aliasesP.statedIn] then
-- No source database is cited explicitly. Wikidata discourages this.
return nil -- Don't return anything in this case.
end
-- Check if the ID indeed refers to the cited source given in the "Stated in" field.
local citedSourceQID = getValue(snaks[aliasesP.statedIn][1], true, false) -- argument explanation: raw, not linked
local sourceAssociatedProps = propertiesFunc{"raw", aliasesP.wikidataProperty, ["eid"] = citedSourceQID} -- fetch the associated properties for the cited source
for i, associatedProp in pairs(mw.text.split(sourceAssociatedProps, ", ", true)) do
if associatedProp == refProperty then
-- The external ID indeed refers to the source identified by citedSourceQID.
local renderedSnak = getValue(snak, false, true) -- not raw, linked
if mw.ustring.match(renderedSnak, "^%[%Z- %Z+%]$") then
-- The last getValue call returned a URL in square brackets.
-- strip link wikisyntax, and return the bare URL
local url = mw.ustring.gsub(renderedSnak, "^%[(%Z-) %Z+%]$", "%1") -- gsub returns two values
return url
end
end
end
end,
}
},
["q"] = {
["template"] = "Cite Q",
["raw-value-params"] = {"1"}, -- the first, unnamed parameter of CiteQ takes a QID, not the name of the item cited
["mandatory-params"] = {"1"},
["prioritization"] = {
["date"] = {aliasesP.lastUpdate, aliasesP.publicationDate}
},
["customRenderers"] = {
["id"] = function (_, refProperty, defaultRenderer)
local output = defaultRenderer()
if output then
output = mw.wikibase.getLabel(refProperty) .. " " .. output
end
return output
end,
}
}
}
}
}
p.getOrdinalSuffix = function(num)
if tostring(num):sub(-2,-2) == '1' then
return "th" -- 10th, 11th, 12th, 13th, ... 19th
end
num = tostring(num):sub(-1)
if num == '1' then
return "st"
elseif num == '2' then
return "nd"
elseif num == '3' then
return "rd"
else
return "th"
end
end
p.addDelimiters = function(n)
local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$")
if left and num and right then
return left .. (num:reverse():gsub("(%d%d%d)", "%1" .. p['numeric']['delimiter']):reverse()) .. right
else
return n
end
end
return p
end
return p
oxg4xygireze1hyk3uq0s2xrq92yivw
Module:High-use
828
15089
124195
118653
2026-10-18T08:06:09Z
en>Paine Ellsworth
0
per edit request on talk page - update preview text
124195
Scribunto
text/plain
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local _fetch = require('Module:Transclusion_count')._fetch -- _fetch looks at the 'demo' argument
local yesno = require('Module:Yesno')
local lang_obj = mw.getContentLanguage() -- this here because the language object is used multiple places in the module
local large_count_cutoff = 100000
local approx_num_total_pages = 66000000
local user_subpage_info_page = 'Wikipedia:User pages#SUB'
local sandbox_module_page = 'Module:Sandbox'
local system_messages_cat = 'Pages used in system messages needing protection'
local sandbox_word = 'sandbox'
local testcases_word = 'testcases'
local doc_word = 'doc'
local function count_from_args(args)
if tonumber(args.count) then -- check if function has already been used
return tonumber(args.count) -- early exit if so
end
local count
if yesno(args['fetch']) ~= false then
count = _fetch(args) -- fetch transclusion count
end
-- use explicitly-provided count when fetch fails
if count == nil and args[1] ~= nil and args[1] ~= '' then
-- convert local language number string to a number understandable by Lua
count = mw.ustring.gsub(args[1], '+$', '')
count = lang_obj:parseFormattedNumber(args[1])
end
-- in case someone writes a non-positive number
if count and count > 0 then
return count
end
return nil
end
-- Actions if there is a large (greater than or equal to 100,000) transclusion count
local function risk_boolean(args)
if args.risk == true or args.risk == false then
return args.risk
elseif args[1] == 'risk' then
return true
else
local count = count_from_args(args)
if count and count >= large_count_cutoff then
return true
end
end
return false
end
-- function retained for backwards compatibility
function p._risk(args)
return risk_boolean(args) and 'risk' or ''
end
-- function retained for backwards compatibility
function p.risk(frame)
return p._risk(getArgs(frame))
end
-- count and no_percent arguments retained for backwards compatibility
function p._num(args, count, no_percent)
if count == nil then
count = count_from_args(args)
end
args.count = count
args.risk = risk_boolean(args)
-- Build output string
local return_value = ''
if args.count == nil and args.risk then
return 'a very large number of'
elseif args.count == nil then
return 'many'
else
-- Use 2 significant figures for smaller numbers and 3 for larger ones
local sigfig = 2
if args.count >= large_count_cutoff then
sigfig = 3
end
-- Prepare to round to appropriate number of sigfigs
local f = math.floor(math.log10(args.count)) - sigfig + 1
-- Round and insert 'approximately' or '+' when appropriate
if yesno(args[2]) == true or (type(args[1]) == 'string' and (mw.ustring.sub(args[1], -1) == '+')) then
-- Round down
return_value = string.format('%s+', lang_obj:formatNum(math.floor( (args.count / 10^(f)) ) * (10^(f))) )
else
-- Round to nearest
return_value = string.format('approximately %s', lang_obj:formatNum(math.floor( (args.count / 10^(f)) + 0.5) * (10^(f))) )
end
-- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes
no_percent = yesno(no_percent or args['no-percent'])
if args.count and args.count >= approx_num_total_pages/100 and not no_percent then
local num_total_pages = mw.getCurrentFrame():callParserFunction('NUMBEROFPAGES', 'R')
local total_percent = math.floor( ( ( args.count/num_total_pages ) * 100) + 0.5)
if total_percent >= 1 then
return_value = string.format('%s pages, or roughly %s%% of all', return_value, total_percent)
end
end
end
return return_value
end
-- used by [[Template:Stub documentation]] and other pages
-- count argument retained for backwards compatibility
function p.num(frame, count)
return p._num(getArgs(frame), count)
end
-- count argument retained for backwards compatibility
function p._text(args, count)
--[=[
Only show the information about how this template gets updated
if someone is actually editing the page and maybe trying to update the count.
]=]
local bot_text = (mw.getCurrentFrame():preprocess('{{REVISIONID}}') == '') and ("\n\n----\n'''Preview info''':" .. ' The number of transclusions [[Template:High-use/doc#Technical details|is updated automatically]].') or ''
if count == nil then
count = count_from_args(args)
end
args.count = count
args.risk = risk_boolean(args)
-- trim /doc, /sandbox and /testcases
local title = args.title or (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
if title.subpageText == doc_word or title.subpageText == sandbox_word or title.subpageText == testcases_word then
title = title.basePageTitle
end
-- use /testcases of base template
local testcases_page = mw.title.new(title.prefixedText .. '/' .. testcases_word)
-- exists is expensive
while testcases_page.basePageTitle.isSubpage and not testcases_page.exists do
testcases_page = mw.title.new(testcases_page.basePageTitle.basePageTitle.prefixedText .. '/' .. testcases_word)
end
local systemMessages = (args['system'] or '') ~= ''
-- This retrieves the project URL automatically to simplify localization.
local templateCount = ('on [https://linkcount.toolforge.org/?project=%s&page=%s#transclusions %s pages]'):format(
title:fullUrl():gsub('//(.-)/.*', '%1'),
mw.uri.encode(title.fullText), p._num(args))
local used_on_text = "'''This " .. (title:inNamespace('Module') and 'Lua module' or 'template') .. ' is used '
if systemMessages then
used_on_text = used_on_text .. args['system'] ..
((args.count and args.count > 2000) and ("''', and " .. templateCount) or ("'''"))
else
used_on_text = used_on_text .. templateCount .. "'''"
end
local sandbox_text = ('%s\'s [[%s/sandbox|/sandbox]] or [[%s|/testcases]] subpages, or in your own [[%s]]. '):format(
title:inNamespace('Module') and 'module' or 'template',
title.fullText,
testcases_page.fullText,
title:inNamespace('Module') and (sandbox_module_page .. '|module sandbox') or (user_subpage_info_page .. '|user subpage')
)
local infoArg = args['info'] ~= '' and args['info']
if (systemMessages or args.risk) then
local info = '.'
if systemMessages then
info = info .. '<br />Changes to it can cause immediate changes to the ' .. mw.site.namespaces.Project.name .. ' user interface.'
end
if infoArg then
info = info .. '<br />' .. infoArg
end
sandbox_text = info .. '<br /> To avoid major disruption' ..
(args.count and args.count >= large_count_cutoff and ' and server load' or '') .. -- should this use args.risk?
', any changes should be tested in the ' .. sandbox_text ..
'The tested changes can be added to this page in a single edit. '
else
sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') ..
'hanges may be widely noticed. Test changes in the ' .. sandbox_text
end
local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes '
if args[2] ~= nil and args[2] ~= '' and yesno(args[2]) == nil then
discussion_text = string.format('%sat [[%s]]', discussion_text, args[2])
else
discussion_text = string.format('%son the [[%s|talk page]]', discussion_text, title.talkPageTitle.fullText)
end
return used_on_text .. sandbox_text .. discussion_text .. ' before implementing them.' .. bot_text
end
-- used by [[Template:R from high-use template]]
-- count argument retained for backwards compatibility
function p.text(frame, count)
return p._text(getArgs(frame), count)
end
-- nocat argument retained for backwards compatibility
function p._main(args, nocat)
args.count = count_from_args(args)
args.risk = risk_boolean(args)
args.title = (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
local image = 'Ambox warning yellow.svg'
local type_param = 'style'
local epilogue = ''
if args['system'] and args['system'] ~= '' then
image = 'Ambox important.svg'
type_param = 'content'
if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then
local protection_action = (args.title:inNamespace('File') and 'upload') or 'edit'
local protection_level = require('Module:Effective protection level')._main(protection_action, args.title.fullText)
if protection_level ~= 'sysop' and protection_level ~= 'templateeditor' and protection_level ~= 'interfaceadmin' then
epilogue = mw.getCurrentFrame():expandTemplate {
title = 'sandbox other',
args = {
[2] = '[[Category:' .. system_messages_cat .. ']]'
}
}
end
end
elseif args.risk then
image = 'Ambox warning orange.svg'
type_param = 'content'
end
image = '[[File:' .. image .. '|40px|alt=Warning|link=]]'
if args['form'] == 'editnotice' then
return mw.getCurrentFrame():expandTemplate{
title = 'editnotice',
args = {
['image'] = image,
['text'] = p._text(args),
['expiry'] = (args['expiry'] or '')
}
} .. epilogue
else
return require('Module:Message box').main('ombox', {
type = type_param,
image = image,
text = p._text(args),
expiry = (args['expiry'] or '')
}) .. epilogue
end
end
function p.main(frame)
return p._main(getArgs(frame))
end
return p
5obsps34wvcavn864brncey49uuo8l1
124196
124195
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:High-use]]
124195
Scribunto
text/plain
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local _fetch = require('Module:Transclusion_count')._fetch -- _fetch looks at the 'demo' argument
local yesno = require('Module:Yesno')
local lang_obj = mw.getContentLanguage() -- this here because the language object is used multiple places in the module
local large_count_cutoff = 100000
local approx_num_total_pages = 66000000
local user_subpage_info_page = 'Wikipedia:User pages#SUB'
local sandbox_module_page = 'Module:Sandbox'
local system_messages_cat = 'Pages used in system messages needing protection'
local sandbox_word = 'sandbox'
local testcases_word = 'testcases'
local doc_word = 'doc'
local function count_from_args(args)
if tonumber(args.count) then -- check if function has already been used
return tonumber(args.count) -- early exit if so
end
local count
if yesno(args['fetch']) ~= false then
count = _fetch(args) -- fetch transclusion count
end
-- use explicitly-provided count when fetch fails
if count == nil and args[1] ~= nil and args[1] ~= '' then
-- convert local language number string to a number understandable by Lua
count = mw.ustring.gsub(args[1], '+$', '')
count = lang_obj:parseFormattedNumber(args[1])
end
-- in case someone writes a non-positive number
if count and count > 0 then
return count
end
return nil
end
-- Actions if there is a large (greater than or equal to 100,000) transclusion count
local function risk_boolean(args)
if args.risk == true or args.risk == false then
return args.risk
elseif args[1] == 'risk' then
return true
else
local count = count_from_args(args)
if count and count >= large_count_cutoff then
return true
end
end
return false
end
-- function retained for backwards compatibility
function p._risk(args)
return risk_boolean(args) and 'risk' or ''
end
-- function retained for backwards compatibility
function p.risk(frame)
return p._risk(getArgs(frame))
end
-- count and no_percent arguments retained for backwards compatibility
function p._num(args, count, no_percent)
if count == nil then
count = count_from_args(args)
end
args.count = count
args.risk = risk_boolean(args)
-- Build output string
local return_value = ''
if args.count == nil and args.risk then
return 'a very large number of'
elseif args.count == nil then
return 'many'
else
-- Use 2 significant figures for smaller numbers and 3 for larger ones
local sigfig = 2
if args.count >= large_count_cutoff then
sigfig = 3
end
-- Prepare to round to appropriate number of sigfigs
local f = math.floor(math.log10(args.count)) - sigfig + 1
-- Round and insert 'approximately' or '+' when appropriate
if yesno(args[2]) == true or (type(args[1]) == 'string' and (mw.ustring.sub(args[1], -1) == '+')) then
-- Round down
return_value = string.format('%s+', lang_obj:formatNum(math.floor( (args.count / 10^(f)) ) * (10^(f))) )
else
-- Round to nearest
return_value = string.format('approximately %s', lang_obj:formatNum(math.floor( (args.count / 10^(f)) + 0.5) * (10^(f))) )
end
-- Insert percentage of pages if that is likely to be >= 1% and when |no-percent= not set to yes
no_percent = yesno(no_percent or args['no-percent'])
if args.count and args.count >= approx_num_total_pages/100 and not no_percent then
local num_total_pages = mw.getCurrentFrame():callParserFunction('NUMBEROFPAGES', 'R')
local total_percent = math.floor( ( ( args.count/num_total_pages ) * 100) + 0.5)
if total_percent >= 1 then
return_value = string.format('%s pages, or roughly %s%% of all', return_value, total_percent)
end
end
end
return return_value
end
-- used by [[Template:Stub documentation]] and other pages
-- count argument retained for backwards compatibility
function p.num(frame, count)
return p._num(getArgs(frame), count)
end
-- count argument retained for backwards compatibility
function p._text(args, count)
--[=[
Only show the information about how this template gets updated
if someone is actually editing the page and maybe trying to update the count.
]=]
local bot_text = (mw.getCurrentFrame():preprocess('{{REVISIONID}}') == '') and ("\n\n----\n'''Preview info''':" .. ' The number of transclusions [[Template:High-use/doc#Technical details|is updated automatically]].') or ''
if count == nil then
count = count_from_args(args)
end
args.count = count
args.risk = risk_boolean(args)
-- trim /doc, /sandbox and /testcases
local title = args.title or (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
if title.subpageText == doc_word or title.subpageText == sandbox_word or title.subpageText == testcases_word then
title = title.basePageTitle
end
-- use /testcases of base template
local testcases_page = mw.title.new(title.prefixedText .. '/' .. testcases_word)
-- exists is expensive
while testcases_page.basePageTitle.isSubpage and not testcases_page.exists do
testcases_page = mw.title.new(testcases_page.basePageTitle.basePageTitle.prefixedText .. '/' .. testcases_word)
end
local systemMessages = (args['system'] or '') ~= ''
-- This retrieves the project URL automatically to simplify localization.
local templateCount = ('on [https://linkcount.toolforge.org/?project=%s&page=%s#transclusions %s pages]'):format(
title:fullUrl():gsub('//(.-)/.*', '%1'),
mw.uri.encode(title.fullText), p._num(args))
local used_on_text = "'''This " .. (title:inNamespace('Module') and 'Lua module' or 'template') .. ' is used '
if systemMessages then
used_on_text = used_on_text .. args['system'] ..
((args.count and args.count > 2000) and ("''', and " .. templateCount) or ("'''"))
else
used_on_text = used_on_text .. templateCount .. "'''"
end
local sandbox_text = ('%s\'s [[%s/sandbox|/sandbox]] or [[%s|/testcases]] subpages, or in your own [[%s]]. '):format(
title:inNamespace('Module') and 'module' or 'template',
title.fullText,
testcases_page.fullText,
title:inNamespace('Module') and (sandbox_module_page .. '|module sandbox') or (user_subpage_info_page .. '|user subpage')
)
local infoArg = args['info'] ~= '' and args['info']
if (systemMessages or args.risk) then
local info = '.'
if systemMessages then
info = info .. '<br />Changes to it can cause immediate changes to the ' .. mw.site.namespaces.Project.name .. ' user interface.'
end
if infoArg then
info = info .. '<br />' .. infoArg
end
sandbox_text = info .. '<br /> To avoid major disruption' ..
(args.count and args.count >= large_count_cutoff and ' and server load' or '') .. -- should this use args.risk?
', any changes should be tested in the ' .. sandbox_text ..
'The tested changes can be added to this page in a single edit. '
else
sandbox_text = (infoArg and ('.<br />' .. infoArg .. ' C') or ' and c') ..
'hanges may be widely noticed. Test changes in the ' .. sandbox_text
end
local discussion_text = systemMessages and 'Please discuss changes ' or 'Consider discussing changes '
if args[2] ~= nil and args[2] ~= '' and yesno(args[2]) == nil then
discussion_text = string.format('%sat [[%s]]', discussion_text, args[2])
else
discussion_text = string.format('%son the [[%s|talk page]]', discussion_text, title.talkPageTitle.fullText)
end
return used_on_text .. sandbox_text .. discussion_text .. ' before implementing them.' .. bot_text
end
-- used by [[Template:R from high-use template]]
-- count argument retained for backwards compatibility
function p.text(frame, count)
return p._text(getArgs(frame), count)
end
-- nocat argument retained for backwards compatibility
function p._main(args, nocat)
args.count = count_from_args(args)
args.risk = risk_boolean(args)
args.title = (args.demo and args.demo ~= '' and mw.title.new(args.demo, 'Template')) or mw.title.getCurrentTitle()
local image = 'Ambox warning yellow.svg'
local type_param = 'style'
local epilogue = ''
if args['system'] and args['system'] ~= '' then
image = 'Ambox important.svg'
type_param = 'content'
if yesno(nocat or args['nocat']) ~= true and not args.title.isRedirect then
local protection_action = (args.title:inNamespace('File') and 'upload') or 'edit'
local protection_level = require('Module:Effective protection level')._main(protection_action, args.title.fullText)
if protection_level ~= 'sysop' and protection_level ~= 'templateeditor' and protection_level ~= 'interfaceadmin' then
epilogue = mw.getCurrentFrame():expandTemplate {
title = 'sandbox other',
args = {
[2] = '[[Category:' .. system_messages_cat .. ']]'
}
}
end
end
elseif args.risk then
image = 'Ambox warning orange.svg'
type_param = 'content'
end
image = '[[File:' .. image .. '|40px|alt=Warning|link=]]'
if args['form'] == 'editnotice' then
return mw.getCurrentFrame():expandTemplate{
title = 'editnotice',
args = {
['image'] = image,
['text'] = p._text(args),
['expiry'] = (args['expiry'] or '')
}
} .. epilogue
else
return require('Module:Message box').main('ombox', {
type = type_param,
image = image,
text = p._text(args),
expiry = (args['expiry'] or '')
}) .. epilogue
end
end
function p.main(frame)
return p._main(getArgs(frame))
end
return p
5obsps34wvcavn864brncey49uuo8l1
Module:Transclusion count/data/I
828
15103
124199
121166
2026-10-18T05:09:56Z
en>Ahechtbot
0
[[Wikipedia:BOT|Bot]]: Updated page.
124199
Scribunto
text/plain
return {
["IAST"] = 6300,
["IA_SCOTUS_URL"] = 3300,
["IBDB_name"] = 9800,
["ICD10"] = 5000,
["ICD9"] = 4400,
["ICS"] = 3500,
["ICS_flag"] = 3500,
["IDN"] = 3800,
["IMDb_episode"] = 11000,
["IMDb_episodes"] = 4300,
["IMDb_name"] = 173000,
["IMDb_title"] = 212000,
["IMO_Number"] = 4500,
["IMSLP"] = 9200,
["INA"] = 2400,
["IND"] = 8800,
["INR"] = 6600,
["INRConvert"] = 6800,
["INRConvert/CurrentRate"] = 6700,
["INRConvert/USD"] = 6700,
["INRConvert/out"] = 6700,
["IOBDB_name"] = 2100,
["IP"] = 2800,
["IPA"] = 183000,
["IPA_audio_link"] = 5300,
["IPA_link"] = 5100,
["IPAblink"] = 2600,
["IPAc-cmn"] = 2800,
["IPAc-en"] = 56000,
["IPAc-pl"] = 51000,
["IPSummary"] = 82000,
["IP_summary"] = 83000,
["IPtalk"] = 18000,
["IPuser"] = 7600,
["IPvandal"] = 2800,
["IRC"] = 7200,
["IRI"] = 2600,
["IRL"] = 6100,
["IRN"] = 4000,
["ISBN"] = 475000,
["ISBN?"] = 2400,
["ISBNT"] = 46000,
["ISBN_missing"] = 3200,
["ISFDB_name"] = 4300,
["ISFDB_title"] = 5100,
["ISL"] = 2300,
["ISO_15924/script-example-character"] = 3100,
["ISO_15924/wp-article"] = 3100,
["ISO_15924/wp-article/format"] = 3100,
["ISO_15924/wp-article/label"] = 3000,
["ISO_3166_code"] = 277000,
["ISO_3166_name"] = 16000,
["ISO_639_name"] = 28000,
["ISP"] = 3700,
["ISR"] = 6100,
["ISSN"] = 12000,
["ISSN_link"] = 33000,
["ISTAT"] = 8100,
["ISU_figure_skater"] = 2300,
["ITA"] = 20000,
["ITF"] = 6800,
["ITF_profile"] = 2600,
["ITIS"] = 5900,
["ITN_talk"] = 13000,
["ITN_talk/date"] = 13000,
["IUCN_banner"] = 15000,
["I_sup"] = 4900,
["Ice_hockey_box"] = 2000,
["Ice_hockey_stats"] = 20000,
["Icehockeystats"] = 11000,
["Icelandic_name"] = 2200,
["Icon"] = 679000,
["If"] = 438000,
["If_all"] = 8000,
["If_autoconfirmed"] = 2200,
["If_between"] = 4800,
["If_both"] = 210000,
["If_dark"] = 4100,
["If_dark/styles.css"] = 4100,
["If_either"] = 22000,
["If_empty"] = 6800000,
["If_first_display_both"] = 122000,
["If_in_category"] = 164000,
["If_in_page"] = 23000,
["If_last_display_both"] = 38000,
["If_mobile"] = 2100,
["If_mobile/styles.css"] = 4400,
["If_preview"] = 66000,
["If_then_show"] = 89000,
["Ifempty"] = 949000,
["Ifeq"] = 84000,
["Iferror_then_show"] = 4000,
["Ifexist_not_redirect"] = 1990000,
["Ifnotempty"] = 19000,
["Ifnoteq_then_show"] = 2300,
["Ifnumber"] = 78000,
["Ifsubst"] = 1030000,
["Ih"] = 8100,
["Ill"] = 262000,
["Illm"] = 5800,
["Image_frame"] = 6200,
["Image_label"] = 4700,
["Image_label_begin"] = 4100,
["Image_label_end"] = 4100,
["Image_label_small"] = 2600,
["Image_needed"] = 4400,
["Image_other"] = 191000,
["Image_requested"] = 134000,
["Image_requested/Category_helper"] = 124000,
["Imbox"] = 1000000,
["Imdb_name"] = 5300,
["Imdb_title"] = 2900,
["Importance"] = 15000,
["Importance/colour"] = 30000,
["Importance_mask"] = 632000,
["Improve_categories"] = 7000,
["Improve_documentation"] = 4300,
["Improve_plot"] = 4200,
["In_class"] = 5600,
["In_lang"] = 390000,
["In_progress"] = 3800,
["In_string"] = 310000,
["In_title"] = 31000,
["Inactive_userpage_blanked"] = 3600,
["Inaturalist_taxon"] = 3800,
["Include-USGov"] = 24000,
["Incomplete_list"] = 24000,
["Inconclusive"] = 2400,
["Increase"] = 62000,
["Incumbent_pope"] = 4400,
["Indent"] = 2400,
["Indented_plain_list"] = 2800,
["Indented_plainlist"] = 2500,
["Independent_sources"] = 10000,
["IndexFungorum"] = 2100,
["Indian_English"] = 5000,
["Indian_railway_code"] = 3600,
["Indian_rupee"] = 12000,
["Inflation"] = 28000,
["Inflation-fn"] = 5900,
["Inflation-year"] = 4300,
["Inflation/IN/startyear"] = 6700,
["Inflation/UK"] = 5600,
["Inflation/UK/dataset"] = 5600,
["Inflation/UK/startyear"] = 5600,
["Inflation/US"] = 16000,
["Inflation/US-GDP"] = 3100,
["Inflation/US-GDP/dataset"] = 3100,
["Inflation/US-GDP/startyear"] = 3100,
["Inflation/US/dataset"] = 16000,
["Inflation/US/startyear"] = 16000,
["Inflation/fn"] = 7600,
["Inflation/year"] = 34000,
["Info"] = 5600,
["Infobox"] = 3440000,
["Infobox/Columns"] = 3300,
["Infobox/mobileviewfix.css"] = 177000,
["Infobox/styles-images.css"] = 21000,
["Infobox3cols"] = 28000,
["Infobox_AFL_biography"] = 15000,
["Infobox_Athletics_Championships"] = 3400,
["Infobox_Australian_place"] = 15000,
["Infobox_Australian_place/styles.css"] = 15000,
["Infobox_Australian_place/table"] = 11000,
["Infobox_COA_wide"] = 3700,
["Infobox_Canada_electoral_district"] = 2700,
["Infobox_Chinese"] = 24000,
["Infobox_Chinese/Chinese"] = 3200,
["Infobox_Chinese/Footer"] = 7200,
["Infobox_Chinese/Header"] = 7200,
["Infobox_Christian_leader"] = 23000,
["Infobox_French_commune"] = 38000,
["Infobox_French_subdivision"] = 2200,
["Infobox_Gaelic_games_biography"] = 5500,
["Infobox_Gaelic_games_player"] = 3000,
["Infobox_German_place"] = 14000,
["Infobox_Grand_Prix_race_report"] = 2200,
["Infobox_Greece_place"] = 3600,
["Infobox_Greek_Dimos"] = 2900,
["Infobox_Hindu_temple"] = 2900,
["Infobox_Indian_constituency"] = 5800,
["Infobox_Indian_constituency/defaultdata"] = 5800,
["Infobox_Italian_comune"] = 8100,
["Infobox_Korean"] = 2100,
["Infobox_Korean/auto"] = 15000,
["Infobox_Korean/auto/categories"] = 15000,
["Infobox_Korean/base"] = 2100,
["Infobox_Korean/base/auto"] = 18000,
["Infobox_Korean/categories"] = 2100,
["Infobox_Korean_name"] = 2100,
["Infobox_Korean_name/auto"] = 14000,
["Infobox_Korean_television_name"] = 3500,
["Infobox_NASCAR_driver"] = 2400,
["Infobox_NASCAR_race_report"] = 2800,
["Infobox_NCAA_basketball_conference_tournament"] = 2100,
["Infobox_NCAA_team_season"] = 11000,
["Infobox_NFL_biography"] = 27000,
["Infobox_NFL_team_season"] = 2300,
["Infobox_NRHP"] = 74000,
["Infobox_NRHP/conv"] = 19000,
["Infobox_NRHP/pushpinmap2region"] = 68000,
["Infobox_Olympic_event"] = 8100,
["Infobox_Olympic_event/event_link"] = 8100,
["Infobox_Olympic_event/games_text"] = 8100,
["Infobox_Pan_American_Games_event"] = 2900,
["Infobox_Paralympic_event"] = 2900,
["Infobox_Paralympic_event/games_text"] = 2900,
["Infobox_Romanian_subdivision"] = 3200,
["Infobox_Russian_district"] = 2100,
["Infobox_Russian_inhabited_locality"] = 4700,
["Infobox_Russian_inhabited_locality/PosMapFS"] = 4200,
["Infobox_Russian_inhabited_locality/federal_subject"] = 4700,
["Infobox_SCOTUS_case"] = 4600,
["Infobox_SSSI"] = 2000,
["Infobox_Site_of_Special_Scientific_Interest"] = 2100,
["Infobox_Slovak_place"] = 3000,
["Infobox_Swiss_town"] = 3000,
["Infobox_Switzerland_municipality"] = 3000,
["Infobox_Turkey_place"] = 20000,
["Infobox_U.S._county"] = 3000,
["Infobox_U.S._county/district"] = 3000,
["Infobox_U.S._legislation"] = 2300,
["Infobox_UK_constituency"] = 2200,
["Infobox_UK_constituency/year"] = 2200,
["Infobox_UK_legislation"] = 6500,
["Infobox_UK_place"] = 27000,
["Infobox_UK_place/NoDialCode"] = 8300,
["Infobox_UK_place/NoPostCode"] = 3700,
["Infobox_UK_place/area"] = 2800,
["Infobox_UK_place/dens"] = 2300,
["Infobox_UK_place/dist"] = 2800,
["Infobox_UK_place/local"] = 27000,
["Infobox_UK_place/styles.css"] = 27000,
["Infobox_UNESCO_World_Heritage_Site"] = 2100,
["Infobox_UN_resolution"] = 2300,
["Infobox_US_Supreme_Court_case"] = 4800,
["Infobox_US_Supreme_Court_case/courts"] = 4800,
["Infobox_United_States_legislative_district"] = 2800,
["Infobox_United_States_legislative_district/representative"] = 2800,
["Infobox_Wikipedia_user"] = 12000,
["Infobox_academic"] = 27000,
["Infobox_aircraft"] = 13000,
["Infobox_aircraft/styles.css"] = 14000,
["Infobox_aircraft_occurrence"] = 2900,
["Infobox_airline"] = 4800,
["Infobox_airline/styles.css"] = 4800,
["Infobox_airport"] = 14000,
["Infobox_airport/datatable"] = 13000,
["Infobox_airport/styles.css"] = 14000,
["Infobox_album"] = 169000,
["Infobox_album/color"] = 209000,
["Infobox_album/link"] = 169000,
["Infobox_anatomy"] = 4500,
["Infobox_animanga/Footer"] = 7800,
["Infobox_animanga/Header"] = 7800,
["Infobox_animanga/Print"] = 6700,
["Infobox_animanga/Video"] = 5100,
["Infobox_architect"] = 4500,
["Infobox_artist"] = 35000,
["Infobox_artist_discography"] = 6500,
["Infobox_artwork"] = 16000,
["Infobox_automobile"] = 9300,
["Infobox_award"] = 16000,
["Infobox_badminton_player"] = 3300,
["Infobox_baseball_biography"] = 30000,
["Infobox_baseball_biography/style"] = 30000,
["Infobox_baseball_biography/styles.css"] = 30000,
["Infobox_baseball_team_season"] = 3400,
["Infobox_baseball_team_season/leagueseason"] = 3400,
["Infobox_baseball_team_season/season"] = 3400,
["Infobox_baseball_team_season/styles.css"] = 3400,
["Infobox_basketball_biography"] = 24000,
["Infobox_basketball_biography/style"] = 24000,
["Infobox_basketball_club"] = 3300,
["Infobox_basketball_club/styles.css"] = 3300,
["Infobox_beauty_pageant"] = 2200,
["Infobox_bilateral_relations"] = 5100,
["Infobox_bishop_styles"] = 2500,
["Infobox_body_of_water"] = 19000,
["Infobox_book"] = 64000,
["Infobox_book/styles.css"] = 64000,
["Infobox_boxer"] = 6600,
["Infobox_brand"] = 2200,
["Infobox_brand/styles.css"] = 2200,
["Infobox_bridge"] = 6800,
["Infobox_building"] = 35000,
["Infobox_bus_company"] = 2100,
["Infobox_cemetery"] = 2200,
["Infobox_character"] = 8500,
["Infobox_character/styles.css"] = 8500,
["Infobox_chess_biography"] = 4800,
["Infobox_chess_player"] = 3800,
["Infobox_church"] = 17000,
["Infobox_church/denomination"] = 17000,
["Infobox_church/font_color"] = 17000,
["Infobox_civil_conflict"] = 3300,
["Infobox_civilian_attack"] = 7800,
["Infobox_college_coach"] = 13000,
["Infobox_college_football_game"] = 2300,
["Infobox_college_football_player"] = 2700,
["Infobox_college_sports_team_season"] = 46000,
["Infobox_college_sports_team_season/link"] = 46000,
["Infobox_college_sports_team_season/name"] = 46000,
["Infobox_college_sports_team_season/succession"] = 46000,
["Infobox_college_sports_team_season/team"] = 46000,
["Infobox_comedian"] = 2200,
["Infobox_comic_book_title"] = 3200,
["Infobox_comics_character"] = 3400,
["Infobox_comics_creator"] = 3600,
["Infobox_comics_creator/styles.css"] = 3600,
["Infobox_company"] = 93000,
["Infobox_company/styles.css"] = 93000,
["Infobox_computing_device"] = 2600,
["Infobox_concert"] = 4000,
["Infobox_constituency"] = 8100,
["Infobox_country"] = 7200,
["Infobox_country/formernext"] = 6800,
["Infobox_country/imagetable"] = 5600,
["Infobox_country/multirow"] = 9400,
["Infobox_country/status_text"] = 3100,
["Infobox_country/styles.css"] = 7200,
["Infobox_country_at_games"] = 17000,
["Infobox_country_at_games/core"] = 17000,
["Infobox_country_at_games/see_also"] = 14000,
["Infobox_court_case"] = 5400,
["Infobox_court_case/images"] = 2900,
["Infobox_court_case/styles.css"] = 5400,
["Infobox_cricket_tournament"] = 2800,
["Infobox_cricketer"] = 32000,
["Infobox_cricketer/career"] = 32000,
["Infobox_cricketer/national_side"] = 7700,
["Infobox_criminal"] = 7800,
["Infobox_curler"] = 2800,
["Infobox_cycling_race_report"] = 5000,
["Infobox_cyclist"] = 17000,
["Infobox_dam"] = 5900,
["Infobox_deity"] = 2300,
["Infobox_deity/color"] = 2300,
["Infobox_designation_list"] = 33000,
["Infobox_designation_list/entry"] = 23000,
["Infobox_dim"] = 6400,
["Infobox_diocese"] = 4100,
["Infobox_drug"] = 12000,
["Infobox_drug/chemical_formula"] = 12000,
["Infobox_drug/data_page_link"] = 12000,
["Infobox_drug/formatATC"] = 12000,
["Infobox_drug/formatCASnumber"] = 12000,
["Infobox_drug/formatChEBI"] = 12000,
["Infobox_drug/formatChEMBL"] = 12000,
["Infobox_drug/formatChemDBNIAID"] = 12000,
["Infobox_drug/formatChemSpider"] = 12000,
["Infobox_drug/formatCompTox"] = 12000,
["Infobox_drug/formatDrugBank"] = 12000,
["Infobox_drug/formatIUPHARBPS"] = 12000,
["Infobox_drug/formatJmol"] = 12000,
["Infobox_drug/formatKEGG"] = 12000,
["Infobox_drug/formatPDBligand"] = 11000,
["Infobox_drug/formatPubChemCID"] = 12000,
["Infobox_drug/formatPubChemSID"] = 12000,
["Infobox_drug/formatUNII"] = 12000,
["Infobox_drug/legal_status"] = 12000,
["Infobox_drug/licence"] = 12000,
["Infobox_drug/maintenance_categories"] = 12000,
["Infobox_drug/non-ref-space"] = 4000,
["Infobox_drug/pregnancy_category"] = 12000,
["Infobox_drug/styles.css"] = 12000,
["Infobox_drug/title"] = 12000,
["Infobox_economist"] = 2100,
["Infobox_election"] = 41000,
["Infobox_election/shortname"] = 2600,
["Infobox_election/styles.css"] = 41000,
["Infobox_enzyme"] = 5100,
["Infobox_ethnic_group"] = 8100,
["Infobox_event"] = 8100,
["Infobox_family"] = 2800,
["Infobox_field_hockey_player"] = 2600,
["Infobox_figure_skater"] = 4000,
["Infobox_film"] = 171000,
["Infobox_film/short_description"] = 167000,
["Infobox_film_awards"] = 3200,
["Infobox_film_awards/link"] = 3200,
["Infobox_film_awards/style"] = 3200,
["Infobox_film_or_theatre_festival"] = 2100,
["Infobox_food"] = 7800,
["Infobox_football_biography"] = 220000,
["Infobox_football_club"] = 30000,
["Infobox_football_club_season"] = 25000,
["Infobox_football_league"] = 2800,
["Infobox_football_league_season"] = 22000,
["Infobox_football_match"] = 6800,
["Infobox_football_tournament"] = 2200,
["Infobox_football_tournament_season"] = 9400,
["Infobox_former_subdivision"] = 3800,
["Infobox_former_subdivision/styles.css"] = 3800,
["Infobox_galaxy"] = 3400,
["Infobox_game"] = 3200,
["Infobox_game_score"] = 3800,
["Infobox_games"] = 2100,
["Infobox_gene"] = 13000,
["Infobox_given_name"] = 4100,
["Infobox_golfer"] = 4900,
["Infobox_golfer/highest_ranking"] = 4900,
["Infobox_government_agency"] = 13000,
["Infobox_government_cabinet"] = 3600,
["Infobox_gridiron_football_biography"] = 41000,
["Infobox_gridiron_football_biography/position"] = 40000,
["Infobox_gridiron_football_team_season"] = 4100,
["Infobox_gymnast"] = 6000,
["Infobox_handball_biography"] = 5600,
["Infobox_historic_site"] = 22000,
["Infobox_holiday"] = 2200,
["Infobox_holiday/date"] = 2200,
["Infobox_horseraces"] = 2700,
["Infobox_hospital"] = 7000,
["Infobox_hospital/care_system"] = 7000,
["Infobox_hospital/lists"] = 7000,
["Infobox_hurling_championship"] = 2700,
["Infobox_ice_hockey_biography"] = 21000,
["Infobox_ice_hockey_player"] = 18000,
["Infobox_ice_hockey_team"] = 3300,
["Infobox_ice_hockey_team_season"] = 2200,
["Infobox_international_football_competition"] = 6800,
["Infobox_islands"] = 9700,
["Infobox_islands/area"] = 10000,
["Infobox_islands/density"] = 10000,
["Infobox_islands/length"] = 9700,
["Infobox_islands/styles.css"] = 9700,
["Infobox_journal"] = 10000,
["Infobox_journal/Abbreviation_search"] = 10000,
["Infobox_journal/Bluebook_check"] = 10000,
["Infobox_journal/Former_check"] = 10000,
["Infobox_journal/ISO_4_check"] = 10000,
["Infobox_journal/ISSN-eISSN"] = 9900,
["Infobox_journal/Indexing_search"] = 10000,
["Infobox_journal/MathSciNet_check"] = 10000,
["Infobox_journal/NLM_check"] = 10000,
["Infobox_journal/frequency"] = 9100,
["Infobox_journal/openaccess"] = 2700,
["Infobox_judoka"] = 2800,
["Infobox_lake"] = 3800,
["Infobox_language"] = 10000,
["Infobox_language/family-color"] = 12000,
["Infobox_language/genetic"] = 7000,
["Infobox_language/lingualist"] = 12000,
["Infobox_language/linguistlist"] = 10000,
["Infobox_language/ref"] = 7400,
["Infobox_law_enforcement_agency"] = 2200,
["Infobox_legislation"] = 2800,
["Infobox_legislative_district"] = 2400,
["Infobox_legislative_election"] = 2700,
["Infobox_legislative_election/row"] = 2600,
["Infobox_legislative_election/styles.css"] = 2700,
["Infobox_legislative_term"] = 2300,
["Infobox_legislature"] = 4400,
["Infobox_library"] = 2500,
["Infobox_lighthouse"] = 2700,
["Infobox_lighthouse/light"] = 2700,
["Infobox_locomotive"] = 5000,
["Infobox_magazine"] = 8300,
["Infobox_manner_of_address"] = 4200,
["Infobox_martial_artist"] = 6300,
["Infobox_martial_artist/record"] = 6300,
["Infobox_medal_templates"] = 481000,
["Infobox_medical_condition"] = 9900,
["Infobox_medical_condition_(new)"] = 6200,
["Infobox_medical_person"] = 2600,
["Infobox_militant_organization"] = 2200,
["Infobox_military_conflict"] = 28000,
["Infobox_military_installation"] = 11000,
["Infobox_military_person"] = 54000,
["Infobox_military_unit"] = 29000,
["Infobox_mine"] = 2300,
["Infobox_mineral"] = 2000,
["Infobox_mobile_phone"] = 2600,
["Infobox_mobile_phone/size"] = 2200,
["Infobox_mobile_phone/weight"] = 2300,
["Infobox_model"] = 2300,
["Infobox_monument"] = 2900,
["Infobox_motorsport_season"] = 2900,
["Infobox_mountain"] = 30000,
["Infobox_multi-sport_competition_event"] = 2900,
["Infobox_museum"] = 12000,
["Infobox_musical_artist"] = 131000,
["Infobox_musical_artist/hCard_class"] = 122000,
["Infobox_musical_composition"] = 3700,
["Infobox_name"] = 8900,
["Infobox_name_module"] = 9700,
["Infobox_newspaper"] = 11000,
["Infobox_newspaper/styles.css"] = 11000,
["Infobox_noble"] = 7900,
["Infobox_officeholder"] = 284000,
["Infobox_officeholder/office"] = 291000,
["Infobox_official_post"] = 9900,
["Infobox_organization"] = 43000,
["Infobox_pageant_titleholder"] = 3100,
["Infobox_park"] = 10000,
["Infobox_person"] = 676000,
["Infobox_person/Wikidata"] = 5000,
["Infobox_person/height"] = 116000,
["Infobox_person/length"] = 7700,
["Infobox_person/weight"] = 74000,
["Infobox_philosopher"] = 3800,
["Infobox_planet"] = 4800,
["Infobox_play"] = 4600,
["Infobox_political_party"] = 16000,
["Infobox_power_station"] = 3400,
["Infobox_prepared_food"] = 2500,
["Infobox_professional_wrestler"] = 4800,
["Infobox_professional_wrestling_event"] = 3400,
["Infobox_protected_area"] = 15000,
["Infobox_protein_family"] = 2200,
["Infobox_publisher"] = 2600,
["Infobox_racehorse"] = 6000,
["Infobox_racing_driver"] = 6000,
["Infobox_racing_driver_series_section"] = 3000,
["Infobox_radio_station"] = 22000,
["Infobox_radio_station/styles.css"] = 22000,
["Infobox_rail"] = 3200,
["Infobox_rail_line"] = 8100,
["Infobox_rail_service"] = 3300,
["Infobox_reality_competition_season"] = 4400,
["Infobox_record_label"] = 4200,
["Infobox_recurring_event"] = 8200,
["Infobox_religious_biography"] = 7300,
["Infobox_religious_building"] = 15000,
["Infobox_religious_building/color"] = 22000,
["Infobox_restaurant"] = 4700,
["Infobox_river"] = 32000,
["Infobox_river/calcunit"] = 32000,
["Infobox_river/discharge"] = 32000,
["Infobox_river/row-style"] = 32000,
["Infobox_river/source"] = 32000,
["Infobox_road"] = 25000,
["Infobox_road/meta/mask/category"] = 24000,
["Infobox_road/meta/mask/country"] = 25000,
["Infobox_road/styles.css"] = 26000,
["Infobox_road_small"] = 2500,
["Infobox_rockunit"] = 6500,
["Infobox_royalty"] = 26000,
["Infobox_royalty/short_description"] = 8800,
["Infobox_rugby_biography"] = 19000,
["Infobox_rugby_biography/correct_date"] = 19000,
["Infobox_rugby_biography/depcheck"] = 19000,
["Infobox_rugby_league_biography"] = 11000,
["Infobox_rugby_league_biography/PLAYER"] = 11000,
["Infobox_rugby_team"] = 2700,
["Infobox_sailboat_specifications"] = 2300,
["Infobox_saint"] = 5500,
["Infobox_school"] = 39000,
["Infobox_school/short_description"] = 39000,
["Infobox_school/styles.css"] = 39000,
["Infobox_school_district"] = 6500,
["Infobox_school_district/styles.css"] = 6500,
["Infobox_scientist"] = 57000,
["Infobox_settlement"] = 599000,
["Infobox_settlement/areadisp"] = 261000,
["Infobox_settlement/columns"] = 108000,
["Infobox_settlement/columns/styles.css"] = 108000,
["Infobox_settlement/densdisp"] = 459000,
["Infobox_settlement/lengthdisp"] = 182000,
["Infobox_settlement/link"] = 108000,
["Infobox_settlement/styles.css"] = 599000,
["Infobox_ship"] = 43000,
["Infobox_ship/career"] = 39000,
["Infobox_ship/characteristics"] = 43000,
["Infobox_ship/class_overview"] = 4400,
["Infobox_ship/image"] = 42000,
["Infobox_ship/service_record"] = 2500,
["Infobox_shopping_mall"] = 3800,
["Infobox_short_story"] = 2800,
["Infobox_skier"] = 2700,
["Infobox_soap_character"] = 3100,
["Infobox_social_media_personality"] = 4400,
["Infobox_software"] = 14000,
["Infobox_software/simple"] = 15000,
["Infobox_song"] = 84000,
["Infobox_song/color"] = 84000,
["Infobox_song/link"] = 84000,
["Infobox_song_contest_national_year"] = 2000,
["Infobox_song_contest_national_year/Year"] = 2100,
["Infobox_spaceflight"] = 4100,
["Infobox_spaceflight/styles.css"] = 4100,
["Infobox_speed_skater"] = 2100,
["Infobox_sport_event"] = 2800,
["Infobox_sports_competition_event"] = 25000,
["Infobox_sports_competition_event/medalrow"] = 16000,
["Infobox_sports_league"] = 5700,
["Infobox_sports_season"] = 7000,
["Infobox_sports_team"] = 2300,
["Infobox_sportsperson"] = 179000,
["Infobox_stadium"] = 2600,
["Infobox_station"] = 58000,
["Infobox_station/services"] = 58000,
["Infobox_station/styles.css"] = 58000,
["Infobox_street"] = 4500,
["Infobox_swimmer"] = 11000,
["Infobox_television"] = 64000,
["Infobox_television/Short_description"] = 62000,
["Infobox_television/styles.css"] = 64000,
["Infobox_television_channel"] = 6800,
["Infobox_television_channel/styles.css"] = 6800,
["Infobox_television_episode"] = 13000,
["Infobox_television_episode/styles.css"] = 14000,
["Infobox_television_season"] = 11000,
["Infobox_television_station"] = 3200,
["Infobox_television_station/styles.css"] = 3300,
["Infobox_tennis_biography"] = 11000,
["Infobox_tennis_event"] = 3400,
["Infobox_tennis_tournament"] = 2100,
["Infobox_tennis_tournament/heading"] = 2100,
["Infobox_tennis_tournament/style"] = 2100,
["Infobox_tennis_tournament_event"] = 23000,
["Infobox_tennis_tournament_year"] = 11000,
["Infobox_tennis_tournament_year/color"] = 33000,
["Infobox_tennis_tournament_year/footer"] = 33000,
["Infobox_tournament_season"] = 13000,
["Infobox_train"] = 2600,
["Infobox_university"] = 25000,
["Infobox_user"] = 3000,
["Infobox_venue"] = 20000,
["Infobox_video_game"] = 30000,
["Infobox_video_game/styles.css"] = 30000,
["Infobox_volleyball_biography"] = 5900,
["Infobox_weapon"] = 8100,
["Infobox_weather_event"] = 3600,
["Infobox_weather_event/Effects"] = 3400,
["Infobox_weather_event/Footer"] = 3500,
["Infobox_weather_event/History"] = 3400,
["Infobox_weather_event/SSHWS"] = 2000,
["Infobox_weather_event/meteorology"] = 3300,
["Infobox_weather_event/scale"] = 2100,
["Infobox_weather_event/styles.css"] = 3600,
["Infobox_website"] = 8300,
["Infobox_writer"] = 46000,
["Information"] = 98000,
["Information/styles.css"] = 98000,
["Inlang"] = 2400,
["Inline"] = 3800,
["Inline_block"] = 5400,
["Inprogress"] = 2700,
["Input_link"] = 32000,
["Instagram"] = 21000,
["InterSportStats"] = 6900,
["Interlanguage_link"] = 310000,
["Interlanguage_link_multi"] = 9000,
["International_Paralympic_Committee"] = 4300,
["International_football_primary_link"] = 3600,
["International_football_primary_style"] = 3600,
["International_football_secondary_style"] = 3500,
["Internet_Archive"] = 2300,
["Internet_Archive_SCOTUS_URL"] = 3300,
["Internet_Archive_author"] = 19000,
["Internet_Archive_film"] = 2600,
["Intitle"] = 22000,
["Ip"] = 2100,
["Iptalk"] = 18000,
["IranCensus2006"] = 29000,
["IranNCSGN"] = 3100,
["Iran_Census_2006"] = 29000,
["Irish_place_name"] = 3000,
["IsIPAddress"] = 47000,
["IsValidPageName"] = 3400,
["Is_MLB_league"] = 3300,
["Is_NPB_league"] = 3400,
["Is_continent"] = 13000,
["Is_country_in_Central_America"] = 17000,
["Is_country_in_the_Caribbean"] = 17000,
["Is_interwiki_link"] = 6100,
["Is_italic_taxon"] = 657000,
["Is_redirect"] = 387000,
["Is_time"] = 6700,
["Is_valid_page_name"] = 3400,
["Isbn"] = 10000,
["Isnum"] = 3000,
["Isnumeric"] = 122000,
["Iso2continent"] = 110000,
["Iso2country"] = 26000,
["Iso2country/article"] = 25000,
["Iso2country/data"] = 26000,
["Issubst"] = 64000,
["Italic_dab2"] = 5900,
["Italic_disambiguation"] = 2400,
["Italic_title"] = 259000,
["Italic_title_prefixed"] = 8800,
["Italictitle"] = 3000,
["Ivmbox"] = 143000,
["Ivory_messagebox"] = 192000,
["Ivory_messagebox/styles.css"] = 192000,
["Module:I18n/complex_date"] = 49000,
["Module:IP"] = 223000,
["Module:IPA"] = 186000,
["Module:IPA/data"] = 168000,
["Module:IPA/styles.css"] = 153000,
["Module:IPA_symbol"] = 6900,
["Module:IPA_symbol/data"] = 6900,
["Module:IPAc-en"] = 56000,
["Module:IPAc-en/data"] = 56000,
["Module:IPAc-en/phonemes"] = 56000,
["Module:IPAc-en/pronunciation"] = 56000,
["Module:IPAddress"] = 292000,
["Module:ISO_3166"] = 949000,
["Module:ISO_3166/data/AT"] = 2500,
["Module:ISO_3166/data/BA"] = 3400,
["Module:ISO_3166/data/CA"] = 2600,
["Module:ISO_3166/data/CH"] = 4300,
["Module:ISO_3166/data/CN"] = 2800,
["Module:ISO_3166/data/CZ"] = 6600,
["Module:ISO_3166/data/DE"] = 15000,
["Module:ISO_3166/data/ES"] = 3700,
["Module:ISO_3166/data/FR"] = 38000,
["Module:ISO_3166/data/GB"] = 7100,
["Module:ISO_3166/data/GR"] = 3500,
["Module:ISO_3166/data/IN"] = 29000,
["Module:ISO_3166/data/IR"] = 24000,
["Module:ISO_3166/data/IT"] = 2500,
["Module:ISO_3166/data/National"] = 949000,
["Module:ISO_3166/data/PL"] = 7600,
["Module:ISO_3166/data/RS"] = 3200,
["Module:ISO_3166/data/RU"] = 27000,
["Module:ISO_3166/data/UA"] = 2200,
["Module:ISO_3166/data/US"] = 91000,
["Module:ISO_639_name"] = 34000,
["Module:ISO_639_name/ISO_639-1"] = 29000,
["Module:ISO_639_name/ISO_639-2"] = 21000,
["Module:ISO_639_name/ISO_639-2B"] = 20000,
["Module:ISO_639_name/ISO_639-3"] = 20000,
["Module:ISO_639_name/ISO_639-3_(dep)"] = 34000,
["Module:ISO_639_name/ISO_639-5"] = 19000,
["Module:ISO_639_name/ISO_639_deprecated"] = 34000,
["Module:ISO_639_name/ISO_639_name_to_code"] = 4600,
["Module:ISO_639_name/ISO_639_override"] = 34000,
["Module:ISOdate"] = 49000,
["Module:Ice_hockey_box"] = 2000,
["Module:Icon"] = 692000,
["Module:Icon/data"] = 692000,
["Module:Icon_box"] = 267000,
["Module:Icon_box/data"] = 267000,
["Module:If_any_equal"] = 255000,
["Module:If_empty"] = 6840000,
["Module:If_in_category"] = 164000,
["Module:If_in_page"] = 23000,
["Module:If_not_given_or_empty"] = 125000,
["Module:If_preview"] = 1440000,
["Module:If_preview/configuration"] = 1440000,
["Module:If_preview/styles.css"] = 1440000,
["Module:In_lang"] = 391000,
["Module:Indent"] = 2400,
["Module:Infobox"] = 4720000,
["Module:Infobox/dates"] = 78000,
["Module:Infobox/styles.css"] = 4990000,
["Module:Infobox/utilities"] = 2700,
["Module:Infobox3cols"] = 322000,
["Module:InfoboxBuilder"] = 3100,
["Module:InfoboxImage"] = 5650000,
["Module:InfoboxImage/data"] = 3390000,
["Module:Infobox_body_of_water_tracking"] = 19000,
["Module:Infobox_cyclist_tracking"] = 17000,
["Module:Infobox_dim"] = 383000,
["Module:Infobox_dim/data"] = 234000,
["Module:Infobox_election"] = 43000,
["Module:Infobox_gene"] = 14000,
["Module:Infobox_gene/orthologs"] = 14000,
["Module:Infobox_mapframe"] = 1690000,
["Module:Infobox_military_conflict"] = 28000,
["Module:Infobox_military_conflict/styles.css"] = 28000,
["Module:Infobox_multi-lingual_name"] = 24000,
["Module:Infobox_multi-lingual_name/data"] = 24000,
["Module:Infobox_power_station"] = 3400,
["Module:Infobox_road"] = 26000,
["Module:Infobox_road/browselinks"] = 26000,
["Module:Infobox_road/errors"] = 25000,
["Module:Infobox_road/length"] = 26000,
["Module:Infobox_road/locations"] = 25000,
["Module:Infobox_road/map"] = 25000,
["Module:Infobox_road/route"] = 26000,
["Module:Infobox_road/sections"] = 25000,
["Module:Infobox_ship"] = 43000,
["Module:Infobox_ship/data"] = 43000,
["Module:Infobox_ship/styles.css"] = 43000,
["Module:Infobox_television"] = 64000,
["Module:Infobox_television_disambiguation_check"] = 72000,
["Module:Infobox_television_episode"] = 13000,
["Module:Infobox_television_season_disambiguation_check"] = 10000,
["Module:Infobox_television_season_name"] = 11000,
["Module:Internet_Archive"] = 22000,
["Module:Is_article"] = 2300,
["Module:Is_infobox_in_lead"] = 462000,
["Module:Is_instance"] = 361000,
["Module:Iso2nationality"] = 96000,
["Module:Italic_title"] = 1260000,
["Module:Italic_title2"] = 5900,
}
mvg1awblmjpp8maxf9jwreh620cpua9
124200
124199
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Transclusion_count/data/I]]
124199
Scribunto
text/plain
return {
["IAST"] = 6300,
["IA_SCOTUS_URL"] = 3300,
["IBDB_name"] = 9800,
["ICD10"] = 5000,
["ICD9"] = 4400,
["ICS"] = 3500,
["ICS_flag"] = 3500,
["IDN"] = 3800,
["IMDb_episode"] = 11000,
["IMDb_episodes"] = 4300,
["IMDb_name"] = 173000,
["IMDb_title"] = 212000,
["IMO_Number"] = 4500,
["IMSLP"] = 9200,
["INA"] = 2400,
["IND"] = 8800,
["INR"] = 6600,
["INRConvert"] = 6800,
["INRConvert/CurrentRate"] = 6700,
["INRConvert/USD"] = 6700,
["INRConvert/out"] = 6700,
["IOBDB_name"] = 2100,
["IP"] = 2800,
["IPA"] = 183000,
["IPA_audio_link"] = 5300,
["IPA_link"] = 5100,
["IPAblink"] = 2600,
["IPAc-cmn"] = 2800,
["IPAc-en"] = 56000,
["IPAc-pl"] = 51000,
["IPSummary"] = 82000,
["IP_summary"] = 83000,
["IPtalk"] = 18000,
["IPuser"] = 7600,
["IPvandal"] = 2800,
["IRC"] = 7200,
["IRI"] = 2600,
["IRL"] = 6100,
["IRN"] = 4000,
["ISBN"] = 475000,
["ISBN?"] = 2400,
["ISBNT"] = 46000,
["ISBN_missing"] = 3200,
["ISFDB_name"] = 4300,
["ISFDB_title"] = 5100,
["ISL"] = 2300,
["ISO_15924/script-example-character"] = 3100,
["ISO_15924/wp-article"] = 3100,
["ISO_15924/wp-article/format"] = 3100,
["ISO_15924/wp-article/label"] = 3000,
["ISO_3166_code"] = 277000,
["ISO_3166_name"] = 16000,
["ISO_639_name"] = 28000,
["ISP"] = 3700,
["ISR"] = 6100,
["ISSN"] = 12000,
["ISSN_link"] = 33000,
["ISTAT"] = 8100,
["ISU_figure_skater"] = 2300,
["ITA"] = 20000,
["ITF"] = 6800,
["ITF_profile"] = 2600,
["ITIS"] = 5900,
["ITN_talk"] = 13000,
["ITN_talk/date"] = 13000,
["IUCN_banner"] = 15000,
["I_sup"] = 4900,
["Ice_hockey_box"] = 2000,
["Ice_hockey_stats"] = 20000,
["Icehockeystats"] = 11000,
["Icelandic_name"] = 2200,
["Icon"] = 679000,
["If"] = 438000,
["If_all"] = 8000,
["If_autoconfirmed"] = 2200,
["If_between"] = 4800,
["If_both"] = 210000,
["If_dark"] = 4100,
["If_dark/styles.css"] = 4100,
["If_either"] = 22000,
["If_empty"] = 6800000,
["If_first_display_both"] = 122000,
["If_in_category"] = 164000,
["If_in_page"] = 23000,
["If_last_display_both"] = 38000,
["If_mobile"] = 2100,
["If_mobile/styles.css"] = 4400,
["If_preview"] = 66000,
["If_then_show"] = 89000,
["Ifempty"] = 949000,
["Ifeq"] = 84000,
["Iferror_then_show"] = 4000,
["Ifexist_not_redirect"] = 1990000,
["Ifnotempty"] = 19000,
["Ifnoteq_then_show"] = 2300,
["Ifnumber"] = 78000,
["Ifsubst"] = 1030000,
["Ih"] = 8100,
["Ill"] = 262000,
["Illm"] = 5800,
["Image_frame"] = 6200,
["Image_label"] = 4700,
["Image_label_begin"] = 4100,
["Image_label_end"] = 4100,
["Image_label_small"] = 2600,
["Image_needed"] = 4400,
["Image_other"] = 191000,
["Image_requested"] = 134000,
["Image_requested/Category_helper"] = 124000,
["Imbox"] = 1000000,
["Imdb_name"] = 5300,
["Imdb_title"] = 2900,
["Importance"] = 15000,
["Importance/colour"] = 30000,
["Importance_mask"] = 632000,
["Improve_categories"] = 7000,
["Improve_documentation"] = 4300,
["Improve_plot"] = 4200,
["In_class"] = 5600,
["In_lang"] = 390000,
["In_progress"] = 3800,
["In_string"] = 310000,
["In_title"] = 31000,
["Inactive_userpage_blanked"] = 3600,
["Inaturalist_taxon"] = 3800,
["Include-USGov"] = 24000,
["Incomplete_list"] = 24000,
["Inconclusive"] = 2400,
["Increase"] = 62000,
["Incumbent_pope"] = 4400,
["Indent"] = 2400,
["Indented_plain_list"] = 2800,
["Indented_plainlist"] = 2500,
["Independent_sources"] = 10000,
["IndexFungorum"] = 2100,
["Indian_English"] = 5000,
["Indian_railway_code"] = 3600,
["Indian_rupee"] = 12000,
["Inflation"] = 28000,
["Inflation-fn"] = 5900,
["Inflation-year"] = 4300,
["Inflation/IN/startyear"] = 6700,
["Inflation/UK"] = 5600,
["Inflation/UK/dataset"] = 5600,
["Inflation/UK/startyear"] = 5600,
["Inflation/US"] = 16000,
["Inflation/US-GDP"] = 3100,
["Inflation/US-GDP/dataset"] = 3100,
["Inflation/US-GDP/startyear"] = 3100,
["Inflation/US/dataset"] = 16000,
["Inflation/US/startyear"] = 16000,
["Inflation/fn"] = 7600,
["Inflation/year"] = 34000,
["Info"] = 5600,
["Infobox"] = 3440000,
["Infobox/Columns"] = 3300,
["Infobox/mobileviewfix.css"] = 177000,
["Infobox/styles-images.css"] = 21000,
["Infobox3cols"] = 28000,
["Infobox_AFL_biography"] = 15000,
["Infobox_Athletics_Championships"] = 3400,
["Infobox_Australian_place"] = 15000,
["Infobox_Australian_place/styles.css"] = 15000,
["Infobox_Australian_place/table"] = 11000,
["Infobox_COA_wide"] = 3700,
["Infobox_Canada_electoral_district"] = 2700,
["Infobox_Chinese"] = 24000,
["Infobox_Chinese/Chinese"] = 3200,
["Infobox_Chinese/Footer"] = 7200,
["Infobox_Chinese/Header"] = 7200,
["Infobox_Christian_leader"] = 23000,
["Infobox_French_commune"] = 38000,
["Infobox_French_subdivision"] = 2200,
["Infobox_Gaelic_games_biography"] = 5500,
["Infobox_Gaelic_games_player"] = 3000,
["Infobox_German_place"] = 14000,
["Infobox_Grand_Prix_race_report"] = 2200,
["Infobox_Greece_place"] = 3600,
["Infobox_Greek_Dimos"] = 2900,
["Infobox_Hindu_temple"] = 2900,
["Infobox_Indian_constituency"] = 5800,
["Infobox_Indian_constituency/defaultdata"] = 5800,
["Infobox_Italian_comune"] = 8100,
["Infobox_Korean"] = 2100,
["Infobox_Korean/auto"] = 15000,
["Infobox_Korean/auto/categories"] = 15000,
["Infobox_Korean/base"] = 2100,
["Infobox_Korean/base/auto"] = 18000,
["Infobox_Korean/categories"] = 2100,
["Infobox_Korean_name"] = 2100,
["Infobox_Korean_name/auto"] = 14000,
["Infobox_Korean_television_name"] = 3500,
["Infobox_NASCAR_driver"] = 2400,
["Infobox_NASCAR_race_report"] = 2800,
["Infobox_NCAA_basketball_conference_tournament"] = 2100,
["Infobox_NCAA_team_season"] = 11000,
["Infobox_NFL_biography"] = 27000,
["Infobox_NFL_team_season"] = 2300,
["Infobox_NRHP"] = 74000,
["Infobox_NRHP/conv"] = 19000,
["Infobox_NRHP/pushpinmap2region"] = 68000,
["Infobox_Olympic_event"] = 8100,
["Infobox_Olympic_event/event_link"] = 8100,
["Infobox_Olympic_event/games_text"] = 8100,
["Infobox_Pan_American_Games_event"] = 2900,
["Infobox_Paralympic_event"] = 2900,
["Infobox_Paralympic_event/games_text"] = 2900,
["Infobox_Romanian_subdivision"] = 3200,
["Infobox_Russian_district"] = 2100,
["Infobox_Russian_inhabited_locality"] = 4700,
["Infobox_Russian_inhabited_locality/PosMapFS"] = 4200,
["Infobox_Russian_inhabited_locality/federal_subject"] = 4700,
["Infobox_SCOTUS_case"] = 4600,
["Infobox_SSSI"] = 2000,
["Infobox_Site_of_Special_Scientific_Interest"] = 2100,
["Infobox_Slovak_place"] = 3000,
["Infobox_Swiss_town"] = 3000,
["Infobox_Switzerland_municipality"] = 3000,
["Infobox_Turkey_place"] = 20000,
["Infobox_U.S._county"] = 3000,
["Infobox_U.S._county/district"] = 3000,
["Infobox_U.S._legislation"] = 2300,
["Infobox_UK_constituency"] = 2200,
["Infobox_UK_constituency/year"] = 2200,
["Infobox_UK_legislation"] = 6500,
["Infobox_UK_place"] = 27000,
["Infobox_UK_place/NoDialCode"] = 8300,
["Infobox_UK_place/NoPostCode"] = 3700,
["Infobox_UK_place/area"] = 2800,
["Infobox_UK_place/dens"] = 2300,
["Infobox_UK_place/dist"] = 2800,
["Infobox_UK_place/local"] = 27000,
["Infobox_UK_place/styles.css"] = 27000,
["Infobox_UNESCO_World_Heritage_Site"] = 2100,
["Infobox_UN_resolution"] = 2300,
["Infobox_US_Supreme_Court_case"] = 4800,
["Infobox_US_Supreme_Court_case/courts"] = 4800,
["Infobox_United_States_legislative_district"] = 2800,
["Infobox_United_States_legislative_district/representative"] = 2800,
["Infobox_Wikipedia_user"] = 12000,
["Infobox_academic"] = 27000,
["Infobox_aircraft"] = 13000,
["Infobox_aircraft/styles.css"] = 14000,
["Infobox_aircraft_occurrence"] = 2900,
["Infobox_airline"] = 4800,
["Infobox_airline/styles.css"] = 4800,
["Infobox_airport"] = 14000,
["Infobox_airport/datatable"] = 13000,
["Infobox_airport/styles.css"] = 14000,
["Infobox_album"] = 169000,
["Infobox_album/color"] = 209000,
["Infobox_album/link"] = 169000,
["Infobox_anatomy"] = 4500,
["Infobox_animanga/Footer"] = 7800,
["Infobox_animanga/Header"] = 7800,
["Infobox_animanga/Print"] = 6700,
["Infobox_animanga/Video"] = 5100,
["Infobox_architect"] = 4500,
["Infobox_artist"] = 35000,
["Infobox_artist_discography"] = 6500,
["Infobox_artwork"] = 16000,
["Infobox_automobile"] = 9300,
["Infobox_award"] = 16000,
["Infobox_badminton_player"] = 3300,
["Infobox_baseball_biography"] = 30000,
["Infobox_baseball_biography/style"] = 30000,
["Infobox_baseball_biography/styles.css"] = 30000,
["Infobox_baseball_team_season"] = 3400,
["Infobox_baseball_team_season/leagueseason"] = 3400,
["Infobox_baseball_team_season/season"] = 3400,
["Infobox_baseball_team_season/styles.css"] = 3400,
["Infobox_basketball_biography"] = 24000,
["Infobox_basketball_biography/style"] = 24000,
["Infobox_basketball_club"] = 3300,
["Infobox_basketball_club/styles.css"] = 3300,
["Infobox_beauty_pageant"] = 2200,
["Infobox_bilateral_relations"] = 5100,
["Infobox_bishop_styles"] = 2500,
["Infobox_body_of_water"] = 19000,
["Infobox_book"] = 64000,
["Infobox_book/styles.css"] = 64000,
["Infobox_boxer"] = 6600,
["Infobox_brand"] = 2200,
["Infobox_brand/styles.css"] = 2200,
["Infobox_bridge"] = 6800,
["Infobox_building"] = 35000,
["Infobox_bus_company"] = 2100,
["Infobox_cemetery"] = 2200,
["Infobox_character"] = 8500,
["Infobox_character/styles.css"] = 8500,
["Infobox_chess_biography"] = 4800,
["Infobox_chess_player"] = 3800,
["Infobox_church"] = 17000,
["Infobox_church/denomination"] = 17000,
["Infobox_church/font_color"] = 17000,
["Infobox_civil_conflict"] = 3300,
["Infobox_civilian_attack"] = 7800,
["Infobox_college_coach"] = 13000,
["Infobox_college_football_game"] = 2300,
["Infobox_college_football_player"] = 2700,
["Infobox_college_sports_team_season"] = 46000,
["Infobox_college_sports_team_season/link"] = 46000,
["Infobox_college_sports_team_season/name"] = 46000,
["Infobox_college_sports_team_season/succession"] = 46000,
["Infobox_college_sports_team_season/team"] = 46000,
["Infobox_comedian"] = 2200,
["Infobox_comic_book_title"] = 3200,
["Infobox_comics_character"] = 3400,
["Infobox_comics_creator"] = 3600,
["Infobox_comics_creator/styles.css"] = 3600,
["Infobox_company"] = 93000,
["Infobox_company/styles.css"] = 93000,
["Infobox_computing_device"] = 2600,
["Infobox_concert"] = 4000,
["Infobox_constituency"] = 8100,
["Infobox_country"] = 7200,
["Infobox_country/formernext"] = 6800,
["Infobox_country/imagetable"] = 5600,
["Infobox_country/multirow"] = 9400,
["Infobox_country/status_text"] = 3100,
["Infobox_country/styles.css"] = 7200,
["Infobox_country_at_games"] = 17000,
["Infobox_country_at_games/core"] = 17000,
["Infobox_country_at_games/see_also"] = 14000,
["Infobox_court_case"] = 5400,
["Infobox_court_case/images"] = 2900,
["Infobox_court_case/styles.css"] = 5400,
["Infobox_cricket_tournament"] = 2800,
["Infobox_cricketer"] = 32000,
["Infobox_cricketer/career"] = 32000,
["Infobox_cricketer/national_side"] = 7700,
["Infobox_criminal"] = 7800,
["Infobox_curler"] = 2800,
["Infobox_cycling_race_report"] = 5000,
["Infobox_cyclist"] = 17000,
["Infobox_dam"] = 5900,
["Infobox_deity"] = 2300,
["Infobox_deity/color"] = 2300,
["Infobox_designation_list"] = 33000,
["Infobox_designation_list/entry"] = 23000,
["Infobox_dim"] = 6400,
["Infobox_diocese"] = 4100,
["Infobox_drug"] = 12000,
["Infobox_drug/chemical_formula"] = 12000,
["Infobox_drug/data_page_link"] = 12000,
["Infobox_drug/formatATC"] = 12000,
["Infobox_drug/formatCASnumber"] = 12000,
["Infobox_drug/formatChEBI"] = 12000,
["Infobox_drug/formatChEMBL"] = 12000,
["Infobox_drug/formatChemDBNIAID"] = 12000,
["Infobox_drug/formatChemSpider"] = 12000,
["Infobox_drug/formatCompTox"] = 12000,
["Infobox_drug/formatDrugBank"] = 12000,
["Infobox_drug/formatIUPHARBPS"] = 12000,
["Infobox_drug/formatJmol"] = 12000,
["Infobox_drug/formatKEGG"] = 12000,
["Infobox_drug/formatPDBligand"] = 11000,
["Infobox_drug/formatPubChemCID"] = 12000,
["Infobox_drug/formatPubChemSID"] = 12000,
["Infobox_drug/formatUNII"] = 12000,
["Infobox_drug/legal_status"] = 12000,
["Infobox_drug/licence"] = 12000,
["Infobox_drug/maintenance_categories"] = 12000,
["Infobox_drug/non-ref-space"] = 4000,
["Infobox_drug/pregnancy_category"] = 12000,
["Infobox_drug/styles.css"] = 12000,
["Infobox_drug/title"] = 12000,
["Infobox_economist"] = 2100,
["Infobox_election"] = 41000,
["Infobox_election/shortname"] = 2600,
["Infobox_election/styles.css"] = 41000,
["Infobox_enzyme"] = 5100,
["Infobox_ethnic_group"] = 8100,
["Infobox_event"] = 8100,
["Infobox_family"] = 2800,
["Infobox_field_hockey_player"] = 2600,
["Infobox_figure_skater"] = 4000,
["Infobox_film"] = 171000,
["Infobox_film/short_description"] = 167000,
["Infobox_film_awards"] = 3200,
["Infobox_film_awards/link"] = 3200,
["Infobox_film_awards/style"] = 3200,
["Infobox_film_or_theatre_festival"] = 2100,
["Infobox_food"] = 7800,
["Infobox_football_biography"] = 220000,
["Infobox_football_club"] = 30000,
["Infobox_football_club_season"] = 25000,
["Infobox_football_league"] = 2800,
["Infobox_football_league_season"] = 22000,
["Infobox_football_match"] = 6800,
["Infobox_football_tournament"] = 2200,
["Infobox_football_tournament_season"] = 9400,
["Infobox_former_subdivision"] = 3800,
["Infobox_former_subdivision/styles.css"] = 3800,
["Infobox_galaxy"] = 3400,
["Infobox_game"] = 3200,
["Infobox_game_score"] = 3800,
["Infobox_games"] = 2100,
["Infobox_gene"] = 13000,
["Infobox_given_name"] = 4100,
["Infobox_golfer"] = 4900,
["Infobox_golfer/highest_ranking"] = 4900,
["Infobox_government_agency"] = 13000,
["Infobox_government_cabinet"] = 3600,
["Infobox_gridiron_football_biography"] = 41000,
["Infobox_gridiron_football_biography/position"] = 40000,
["Infobox_gridiron_football_team_season"] = 4100,
["Infobox_gymnast"] = 6000,
["Infobox_handball_biography"] = 5600,
["Infobox_historic_site"] = 22000,
["Infobox_holiday"] = 2200,
["Infobox_holiday/date"] = 2200,
["Infobox_horseraces"] = 2700,
["Infobox_hospital"] = 7000,
["Infobox_hospital/care_system"] = 7000,
["Infobox_hospital/lists"] = 7000,
["Infobox_hurling_championship"] = 2700,
["Infobox_ice_hockey_biography"] = 21000,
["Infobox_ice_hockey_player"] = 18000,
["Infobox_ice_hockey_team"] = 3300,
["Infobox_ice_hockey_team_season"] = 2200,
["Infobox_international_football_competition"] = 6800,
["Infobox_islands"] = 9700,
["Infobox_islands/area"] = 10000,
["Infobox_islands/density"] = 10000,
["Infobox_islands/length"] = 9700,
["Infobox_islands/styles.css"] = 9700,
["Infobox_journal"] = 10000,
["Infobox_journal/Abbreviation_search"] = 10000,
["Infobox_journal/Bluebook_check"] = 10000,
["Infobox_journal/Former_check"] = 10000,
["Infobox_journal/ISO_4_check"] = 10000,
["Infobox_journal/ISSN-eISSN"] = 9900,
["Infobox_journal/Indexing_search"] = 10000,
["Infobox_journal/MathSciNet_check"] = 10000,
["Infobox_journal/NLM_check"] = 10000,
["Infobox_journal/frequency"] = 9100,
["Infobox_journal/openaccess"] = 2700,
["Infobox_judoka"] = 2800,
["Infobox_lake"] = 3800,
["Infobox_language"] = 10000,
["Infobox_language/family-color"] = 12000,
["Infobox_language/genetic"] = 7000,
["Infobox_language/lingualist"] = 12000,
["Infobox_language/linguistlist"] = 10000,
["Infobox_language/ref"] = 7400,
["Infobox_law_enforcement_agency"] = 2200,
["Infobox_legislation"] = 2800,
["Infobox_legislative_district"] = 2400,
["Infobox_legislative_election"] = 2700,
["Infobox_legislative_election/row"] = 2600,
["Infobox_legislative_election/styles.css"] = 2700,
["Infobox_legislative_term"] = 2300,
["Infobox_legislature"] = 4400,
["Infobox_library"] = 2500,
["Infobox_lighthouse"] = 2700,
["Infobox_lighthouse/light"] = 2700,
["Infobox_locomotive"] = 5000,
["Infobox_magazine"] = 8300,
["Infobox_manner_of_address"] = 4200,
["Infobox_martial_artist"] = 6300,
["Infobox_martial_artist/record"] = 6300,
["Infobox_medal_templates"] = 481000,
["Infobox_medical_condition"] = 9900,
["Infobox_medical_condition_(new)"] = 6200,
["Infobox_medical_person"] = 2600,
["Infobox_militant_organization"] = 2200,
["Infobox_military_conflict"] = 28000,
["Infobox_military_installation"] = 11000,
["Infobox_military_person"] = 54000,
["Infobox_military_unit"] = 29000,
["Infobox_mine"] = 2300,
["Infobox_mineral"] = 2000,
["Infobox_mobile_phone"] = 2600,
["Infobox_mobile_phone/size"] = 2200,
["Infobox_mobile_phone/weight"] = 2300,
["Infobox_model"] = 2300,
["Infobox_monument"] = 2900,
["Infobox_motorsport_season"] = 2900,
["Infobox_mountain"] = 30000,
["Infobox_multi-sport_competition_event"] = 2900,
["Infobox_museum"] = 12000,
["Infobox_musical_artist"] = 131000,
["Infobox_musical_artist/hCard_class"] = 122000,
["Infobox_musical_composition"] = 3700,
["Infobox_name"] = 8900,
["Infobox_name_module"] = 9700,
["Infobox_newspaper"] = 11000,
["Infobox_newspaper/styles.css"] = 11000,
["Infobox_noble"] = 7900,
["Infobox_officeholder"] = 284000,
["Infobox_officeholder/office"] = 291000,
["Infobox_official_post"] = 9900,
["Infobox_organization"] = 43000,
["Infobox_pageant_titleholder"] = 3100,
["Infobox_park"] = 10000,
["Infobox_person"] = 676000,
["Infobox_person/Wikidata"] = 5000,
["Infobox_person/height"] = 116000,
["Infobox_person/length"] = 7700,
["Infobox_person/weight"] = 74000,
["Infobox_philosopher"] = 3800,
["Infobox_planet"] = 4800,
["Infobox_play"] = 4600,
["Infobox_political_party"] = 16000,
["Infobox_power_station"] = 3400,
["Infobox_prepared_food"] = 2500,
["Infobox_professional_wrestler"] = 4800,
["Infobox_professional_wrestling_event"] = 3400,
["Infobox_protected_area"] = 15000,
["Infobox_protein_family"] = 2200,
["Infobox_publisher"] = 2600,
["Infobox_racehorse"] = 6000,
["Infobox_racing_driver"] = 6000,
["Infobox_racing_driver_series_section"] = 3000,
["Infobox_radio_station"] = 22000,
["Infobox_radio_station/styles.css"] = 22000,
["Infobox_rail"] = 3200,
["Infobox_rail_line"] = 8100,
["Infobox_rail_service"] = 3300,
["Infobox_reality_competition_season"] = 4400,
["Infobox_record_label"] = 4200,
["Infobox_recurring_event"] = 8200,
["Infobox_religious_biography"] = 7300,
["Infobox_religious_building"] = 15000,
["Infobox_religious_building/color"] = 22000,
["Infobox_restaurant"] = 4700,
["Infobox_river"] = 32000,
["Infobox_river/calcunit"] = 32000,
["Infobox_river/discharge"] = 32000,
["Infobox_river/row-style"] = 32000,
["Infobox_river/source"] = 32000,
["Infobox_road"] = 25000,
["Infobox_road/meta/mask/category"] = 24000,
["Infobox_road/meta/mask/country"] = 25000,
["Infobox_road/styles.css"] = 26000,
["Infobox_road_small"] = 2500,
["Infobox_rockunit"] = 6500,
["Infobox_royalty"] = 26000,
["Infobox_royalty/short_description"] = 8800,
["Infobox_rugby_biography"] = 19000,
["Infobox_rugby_biography/correct_date"] = 19000,
["Infobox_rugby_biography/depcheck"] = 19000,
["Infobox_rugby_league_biography"] = 11000,
["Infobox_rugby_league_biography/PLAYER"] = 11000,
["Infobox_rugby_team"] = 2700,
["Infobox_sailboat_specifications"] = 2300,
["Infobox_saint"] = 5500,
["Infobox_school"] = 39000,
["Infobox_school/short_description"] = 39000,
["Infobox_school/styles.css"] = 39000,
["Infobox_school_district"] = 6500,
["Infobox_school_district/styles.css"] = 6500,
["Infobox_scientist"] = 57000,
["Infobox_settlement"] = 599000,
["Infobox_settlement/areadisp"] = 261000,
["Infobox_settlement/columns"] = 108000,
["Infobox_settlement/columns/styles.css"] = 108000,
["Infobox_settlement/densdisp"] = 459000,
["Infobox_settlement/lengthdisp"] = 182000,
["Infobox_settlement/link"] = 108000,
["Infobox_settlement/styles.css"] = 599000,
["Infobox_ship"] = 43000,
["Infobox_ship/career"] = 39000,
["Infobox_ship/characteristics"] = 43000,
["Infobox_ship/class_overview"] = 4400,
["Infobox_ship/image"] = 42000,
["Infobox_ship/service_record"] = 2500,
["Infobox_shopping_mall"] = 3800,
["Infobox_short_story"] = 2800,
["Infobox_skier"] = 2700,
["Infobox_soap_character"] = 3100,
["Infobox_social_media_personality"] = 4400,
["Infobox_software"] = 14000,
["Infobox_software/simple"] = 15000,
["Infobox_song"] = 84000,
["Infobox_song/color"] = 84000,
["Infobox_song/link"] = 84000,
["Infobox_song_contest_national_year"] = 2000,
["Infobox_song_contest_national_year/Year"] = 2100,
["Infobox_spaceflight"] = 4100,
["Infobox_spaceflight/styles.css"] = 4100,
["Infobox_speed_skater"] = 2100,
["Infobox_sport_event"] = 2800,
["Infobox_sports_competition_event"] = 25000,
["Infobox_sports_competition_event/medalrow"] = 16000,
["Infobox_sports_league"] = 5700,
["Infobox_sports_season"] = 7000,
["Infobox_sports_team"] = 2300,
["Infobox_sportsperson"] = 179000,
["Infobox_stadium"] = 2600,
["Infobox_station"] = 58000,
["Infobox_station/services"] = 58000,
["Infobox_station/styles.css"] = 58000,
["Infobox_street"] = 4500,
["Infobox_swimmer"] = 11000,
["Infobox_television"] = 64000,
["Infobox_television/Short_description"] = 62000,
["Infobox_television/styles.css"] = 64000,
["Infobox_television_channel"] = 6800,
["Infobox_television_channel/styles.css"] = 6800,
["Infobox_television_episode"] = 13000,
["Infobox_television_episode/styles.css"] = 14000,
["Infobox_television_season"] = 11000,
["Infobox_television_station"] = 3200,
["Infobox_television_station/styles.css"] = 3300,
["Infobox_tennis_biography"] = 11000,
["Infobox_tennis_event"] = 3400,
["Infobox_tennis_tournament"] = 2100,
["Infobox_tennis_tournament/heading"] = 2100,
["Infobox_tennis_tournament/style"] = 2100,
["Infobox_tennis_tournament_event"] = 23000,
["Infobox_tennis_tournament_year"] = 11000,
["Infobox_tennis_tournament_year/color"] = 33000,
["Infobox_tennis_tournament_year/footer"] = 33000,
["Infobox_tournament_season"] = 13000,
["Infobox_train"] = 2600,
["Infobox_university"] = 25000,
["Infobox_user"] = 3000,
["Infobox_venue"] = 20000,
["Infobox_video_game"] = 30000,
["Infobox_video_game/styles.css"] = 30000,
["Infobox_volleyball_biography"] = 5900,
["Infobox_weapon"] = 8100,
["Infobox_weather_event"] = 3600,
["Infobox_weather_event/Effects"] = 3400,
["Infobox_weather_event/Footer"] = 3500,
["Infobox_weather_event/History"] = 3400,
["Infobox_weather_event/SSHWS"] = 2000,
["Infobox_weather_event/meteorology"] = 3300,
["Infobox_weather_event/scale"] = 2100,
["Infobox_weather_event/styles.css"] = 3600,
["Infobox_website"] = 8300,
["Infobox_writer"] = 46000,
["Information"] = 98000,
["Information/styles.css"] = 98000,
["Inlang"] = 2400,
["Inline"] = 3800,
["Inline_block"] = 5400,
["Inprogress"] = 2700,
["Input_link"] = 32000,
["Instagram"] = 21000,
["InterSportStats"] = 6900,
["Interlanguage_link"] = 310000,
["Interlanguage_link_multi"] = 9000,
["International_Paralympic_Committee"] = 4300,
["International_football_primary_link"] = 3600,
["International_football_primary_style"] = 3600,
["International_football_secondary_style"] = 3500,
["Internet_Archive"] = 2300,
["Internet_Archive_SCOTUS_URL"] = 3300,
["Internet_Archive_author"] = 19000,
["Internet_Archive_film"] = 2600,
["Intitle"] = 22000,
["Ip"] = 2100,
["Iptalk"] = 18000,
["IranCensus2006"] = 29000,
["IranNCSGN"] = 3100,
["Iran_Census_2006"] = 29000,
["Irish_place_name"] = 3000,
["IsIPAddress"] = 47000,
["IsValidPageName"] = 3400,
["Is_MLB_league"] = 3300,
["Is_NPB_league"] = 3400,
["Is_continent"] = 13000,
["Is_country_in_Central_America"] = 17000,
["Is_country_in_the_Caribbean"] = 17000,
["Is_interwiki_link"] = 6100,
["Is_italic_taxon"] = 657000,
["Is_redirect"] = 387000,
["Is_time"] = 6700,
["Is_valid_page_name"] = 3400,
["Isbn"] = 10000,
["Isnum"] = 3000,
["Isnumeric"] = 122000,
["Iso2continent"] = 110000,
["Iso2country"] = 26000,
["Iso2country/article"] = 25000,
["Iso2country/data"] = 26000,
["Issubst"] = 64000,
["Italic_dab2"] = 5900,
["Italic_disambiguation"] = 2400,
["Italic_title"] = 259000,
["Italic_title_prefixed"] = 8800,
["Italictitle"] = 3000,
["Ivmbox"] = 143000,
["Ivory_messagebox"] = 192000,
["Ivory_messagebox/styles.css"] = 192000,
["Module:I18n/complex_date"] = 49000,
["Module:IP"] = 223000,
["Module:IPA"] = 186000,
["Module:IPA/data"] = 168000,
["Module:IPA/styles.css"] = 153000,
["Module:IPA_symbol"] = 6900,
["Module:IPA_symbol/data"] = 6900,
["Module:IPAc-en"] = 56000,
["Module:IPAc-en/data"] = 56000,
["Module:IPAc-en/phonemes"] = 56000,
["Module:IPAc-en/pronunciation"] = 56000,
["Module:IPAddress"] = 292000,
["Module:ISO_3166"] = 949000,
["Module:ISO_3166/data/AT"] = 2500,
["Module:ISO_3166/data/BA"] = 3400,
["Module:ISO_3166/data/CA"] = 2600,
["Module:ISO_3166/data/CH"] = 4300,
["Module:ISO_3166/data/CN"] = 2800,
["Module:ISO_3166/data/CZ"] = 6600,
["Module:ISO_3166/data/DE"] = 15000,
["Module:ISO_3166/data/ES"] = 3700,
["Module:ISO_3166/data/FR"] = 38000,
["Module:ISO_3166/data/GB"] = 7100,
["Module:ISO_3166/data/GR"] = 3500,
["Module:ISO_3166/data/IN"] = 29000,
["Module:ISO_3166/data/IR"] = 24000,
["Module:ISO_3166/data/IT"] = 2500,
["Module:ISO_3166/data/National"] = 949000,
["Module:ISO_3166/data/PL"] = 7600,
["Module:ISO_3166/data/RS"] = 3200,
["Module:ISO_3166/data/RU"] = 27000,
["Module:ISO_3166/data/UA"] = 2200,
["Module:ISO_3166/data/US"] = 91000,
["Module:ISO_639_name"] = 34000,
["Module:ISO_639_name/ISO_639-1"] = 29000,
["Module:ISO_639_name/ISO_639-2"] = 21000,
["Module:ISO_639_name/ISO_639-2B"] = 20000,
["Module:ISO_639_name/ISO_639-3"] = 20000,
["Module:ISO_639_name/ISO_639-3_(dep)"] = 34000,
["Module:ISO_639_name/ISO_639-5"] = 19000,
["Module:ISO_639_name/ISO_639_deprecated"] = 34000,
["Module:ISO_639_name/ISO_639_name_to_code"] = 4600,
["Module:ISO_639_name/ISO_639_override"] = 34000,
["Module:ISOdate"] = 49000,
["Module:Ice_hockey_box"] = 2000,
["Module:Icon"] = 692000,
["Module:Icon/data"] = 692000,
["Module:Icon_box"] = 267000,
["Module:Icon_box/data"] = 267000,
["Module:If_any_equal"] = 255000,
["Module:If_empty"] = 6840000,
["Module:If_in_category"] = 164000,
["Module:If_in_page"] = 23000,
["Module:If_not_given_or_empty"] = 125000,
["Module:If_preview"] = 1440000,
["Module:If_preview/configuration"] = 1440000,
["Module:If_preview/styles.css"] = 1440000,
["Module:In_lang"] = 391000,
["Module:Indent"] = 2400,
["Module:Infobox"] = 4720000,
["Module:Infobox/dates"] = 78000,
["Module:Infobox/styles.css"] = 4990000,
["Module:Infobox/utilities"] = 2700,
["Module:Infobox3cols"] = 322000,
["Module:InfoboxBuilder"] = 3100,
["Module:InfoboxImage"] = 5650000,
["Module:InfoboxImage/data"] = 3390000,
["Module:Infobox_body_of_water_tracking"] = 19000,
["Module:Infobox_cyclist_tracking"] = 17000,
["Module:Infobox_dim"] = 383000,
["Module:Infobox_dim/data"] = 234000,
["Module:Infobox_election"] = 43000,
["Module:Infobox_gene"] = 14000,
["Module:Infobox_gene/orthologs"] = 14000,
["Module:Infobox_mapframe"] = 1690000,
["Module:Infobox_military_conflict"] = 28000,
["Module:Infobox_military_conflict/styles.css"] = 28000,
["Module:Infobox_multi-lingual_name"] = 24000,
["Module:Infobox_multi-lingual_name/data"] = 24000,
["Module:Infobox_power_station"] = 3400,
["Module:Infobox_road"] = 26000,
["Module:Infobox_road/browselinks"] = 26000,
["Module:Infobox_road/errors"] = 25000,
["Module:Infobox_road/length"] = 26000,
["Module:Infobox_road/locations"] = 25000,
["Module:Infobox_road/map"] = 25000,
["Module:Infobox_road/route"] = 26000,
["Module:Infobox_road/sections"] = 25000,
["Module:Infobox_ship"] = 43000,
["Module:Infobox_ship/data"] = 43000,
["Module:Infobox_ship/styles.css"] = 43000,
["Module:Infobox_television"] = 64000,
["Module:Infobox_television_disambiguation_check"] = 72000,
["Module:Infobox_television_episode"] = 13000,
["Module:Infobox_television_season_disambiguation_check"] = 10000,
["Module:Infobox_television_season_name"] = 11000,
["Module:Internet_Archive"] = 22000,
["Module:Is_article"] = 2300,
["Module:Is_infobox_in_lead"] = 462000,
["Module:Is_instance"] = 361000,
["Module:Iso2nationality"] = 96000,
["Module:Italic_title"] = 1260000,
["Module:Italic_title2"] = 5900,
}
mvg1awblmjpp8maxf9jwreh620cpua9
Module:Message box/ombox.css
828
15106
124205
114702
2026-09-13T20:36:59Z
en>Izno
0
border colors per tper
124205
sanitized-css
text/css
/* {{pp|small=y}} */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
color: var(--color-base, #202122);
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid #b32424; /* Red */
background-color: #fee7e6; /* Pink */
}
.ombox-delete {
border: 2px solid #b32424; /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border-width: 2px; /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
/* keep synced with each other type of message box as this isn't qualified */
.mbox-invalid-type {
text-align: center;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
}
/** T367463 */
body.skin--responsive table.ombox img {
max-width: none !important;
}
@media screen {
html.skin-theme-clientpref-night .ombox-speedy {
background-color: #310402; /* Dark red, same hue/saturation as light */
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ombox-speedy {
background-color: #310402; /* Dark red, same hue/saturation as light */
}
}
smmnp6ybvr30s6idatyj2wvfmnypvlu
124206
124205
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Message_box/ombox.css]]
124205
sanitized-css
text/css
/* {{pp|small=y}} */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
color: var(--color-base, #202122);
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid #b32424; /* Red */
background-color: #fee7e6; /* Pink */
}
.ombox-delete {
border: 2px solid #b32424; /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border-width: 2px; /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
/* keep synced with each other type of message box as this isn't qualified */
.mbox-invalid-type {
text-align: center;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
}
/** T367463 */
body.skin--responsive table.ombox img {
max-width: none !important;
}
@media screen {
html.skin-theme-clientpref-night .ombox-speedy {
background-color: #310402; /* Dark red, same hue/saturation as light */
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ombox-speedy {
background-color: #310402; /* Dark red, same hue/saturation as light */
}
}
smmnp6ybvr30s6idatyj2wvfmnypvlu
Template:Collapse top
10
16474
124189
116899
2026-11-02T09:09:24Z
en>MSGJ
0
adjust border colour to support dark mode, requested by [[User: Axolitl]]
124189
wikitext
text/x-wiki
{{ safesubst:<noinclude/>ifsubst||<templatestyles src="Template:Collapse top/styles.css"/>}}
<div style="margin-left:{{{indent|0}}}"><!-- NOTE: width renders incorrectly if added to main STYLE section -->
{| role="presentation" <!-- Template:Collapse top --> class="mw-collapsible mw-archivedtalk {{<includeonly>safesubst:</includeonly>#if:{{{expand|{{{collapse|}}}}}}||mw-collapsed}} {{{class|}}}" style="color:inherit; background: {{{bg1|transparent}}}; text-align: left; border: {{{border|1px}}} solid {{{b-color|var(--border-color-subtle, #c8ccd1)}}}; margin: 0.2em auto auto; width:{{<includeonly>safesubst:</includeonly>#if:{{{width|}}}|{{{width}}}|100%}}; clear: {{{clear|both}}}; padding: 1px;"
|-
! class="{{main other|cot-header-mainspace|cot-header-other}}" style="{{<includeonly>safesubst:</includeonly>#if:{{{bg|}}}|background:{{{bg}}}|{{ safesubst:<noinclude/>ifsubst|{{main other|background:#F0F2F5|background:#CCFFCC}}|}}}}; font-size:87%; padding:0.2em 0.3em; text-align:{{<includeonly>safesubst:</includeonly>#if:{{{left|}}}|left|{{<includeonly>safesubst:</includeonly>#if:{{{align|}}}|left|center}}}}; {{<includeonly>safesubst:</includeonly>#if:{{{fc|}}}|color: {{{fc}}};|{{<includeonly>safesubst:</includeonly>#if:{{{bg|}}}|color:#202122|{{ safesubst:<noinclude/>ifsubst|color:black;|}}}}}}" | <div style="font-size:115%;{{<includeonly>safesubst:</includeonly>#if:{{{left|}}}||margin:0 4em}}">{{{1|{{{title|{{{reason|{{{header|{{{heading|{{{result|Extended content}}}}}}}}}}}}}}}}}}</div>
{{<includeonly>safesubst:</includeonly>#if:{{{warning|{{{2|}}}}}}
|{{<includeonly>safesubst:</includeonly>!}}-
{{<includeonly>safesubst:</includeonly>!}} style="text-align:center; font-style:italic;" {{<includeonly>safesubst:</includeonly>!}} {{{2|The following is a closed discussion. {{strongbad|Please do not modify it.}} }}} }}
|-
| style="color:inherit; border: solid {{{border2|1px var(--border-color-subtle, #c8ccd1)}}}; padding: {{{padding|0.6em}}}; background: {{{bg2|var(--background-color-base, #fff)}}};" {{<includeonly>safesubst:</includeonly>!}}<noinclude>
{{lorem ipsum|3}}
{{Collapse bottom}}
{{Documentation}}
</noinclude>
06xs5ichmb6hawliz2r2c2rd6nw89il
124190
124189
2026-11-09T20:20:41Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Collapse_top]]
124189
wikitext
text/x-wiki
{{ safesubst:<noinclude/>ifsubst||<templatestyles src="Template:Collapse top/styles.css"/>}}
<div style="margin-left:{{{indent|0}}}"><!-- NOTE: width renders incorrectly if added to main STYLE section -->
{| role="presentation" <!-- Template:Collapse top --> class="mw-collapsible mw-archivedtalk {{<includeonly>safesubst:</includeonly>#if:{{{expand|{{{collapse|}}}}}}||mw-collapsed}} {{{class|}}}" style="color:inherit; background: {{{bg1|transparent}}}; text-align: left; border: {{{border|1px}}} solid {{{b-color|var(--border-color-subtle, #c8ccd1)}}}; margin: 0.2em auto auto; width:{{<includeonly>safesubst:</includeonly>#if:{{{width|}}}|{{{width}}}|100%}}; clear: {{{clear|both}}}; padding: 1px;"
|-
! class="{{main other|cot-header-mainspace|cot-header-other}}" style="{{<includeonly>safesubst:</includeonly>#if:{{{bg|}}}|background:{{{bg}}}|{{ safesubst:<noinclude/>ifsubst|{{main other|background:#F0F2F5|background:#CCFFCC}}|}}}}; font-size:87%; padding:0.2em 0.3em; text-align:{{<includeonly>safesubst:</includeonly>#if:{{{left|}}}|left|{{<includeonly>safesubst:</includeonly>#if:{{{align|}}}|left|center}}}}; {{<includeonly>safesubst:</includeonly>#if:{{{fc|}}}|color: {{{fc}}};|{{<includeonly>safesubst:</includeonly>#if:{{{bg|}}}|color:#202122|{{ safesubst:<noinclude/>ifsubst|color:black;|}}}}}}" | <div style="font-size:115%;{{<includeonly>safesubst:</includeonly>#if:{{{left|}}}||margin:0 4em}}">{{{1|{{{title|{{{reason|{{{header|{{{heading|{{{result|Extended content}}}}}}}}}}}}}}}}}}</div>
{{<includeonly>safesubst:</includeonly>#if:{{{warning|{{{2|}}}}}}
|{{<includeonly>safesubst:</includeonly>!}}-
{{<includeonly>safesubst:</includeonly>!}} style="text-align:center; font-style:italic;" {{<includeonly>safesubst:</includeonly>!}} {{{2|The following is a closed discussion. {{strongbad|Please do not modify it.}} }}} }}
|-
| style="color:inherit; border: solid {{{border2|1px var(--border-color-subtle, #c8ccd1)}}}; padding: {{{padding|0.6em}}}; background: {{{bg2|var(--background-color-base, #fff)}}};" {{<includeonly>safesubst:</includeonly>!}}<noinclude>
{{lorem ipsum|3}}
{{Collapse bottom}}
{{Documentation}}
</noinclude>
06xs5ichmb6hawliz2r2c2rd6nw89il
Template:Subpage other
10
17750
124193
45631
2025-08-05T04:51:03Z
en>Theknightwho
0
Make substable.
124193
wikitext
text/x-wiki
<onlyinclude>{{safesubst:<noinclude/>#ifeq:{{safesubst:<noinclude/>SUBPAGENAME}}|{{safesubst:<noinclude/>ROOTPAGENAME}}|{{{2|}}}|{{{1|}}}}}</onlyinclude><!--
-->{{documentation}}
k0itkwe4s7i80kxzt0zhv9wfh26yh2z
124194
124193
2026-11-09T20:20:41Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Subpage_other]]
124193
wikitext
text/x-wiki
<onlyinclude>{{safesubst:<noinclude/>#ifeq:{{safesubst:<noinclude/>SUBPAGENAME}}|{{safesubst:<noinclude/>ROOTPAGENAME}}|{{{2|}}}|{{{1|}}}}}</onlyinclude><!--
-->{{documentation}}
k0itkwe4s7i80kxzt0zhv9wfh26yh2z
Template:Auto short description
10
17751
124201
45633
2026-10-17T20:16:57Z
en>Alpha Beta Delta Lambda
0
improve wording - optimal implies objectiveness which it is not
124201
wikitext
text/x-wiki
{{Ombox
| type = notice
| text = This template {{#if:{{{sometimes|}}}|sometimes{{sp}}}}adds an automatically generated '''[[Wikipedia:Short description|short description]]'''{{#if:{{{category|}}}|{{sp}}({{{category}}})|}}{{#if:{{{indirect|}}}|{{sp}}via an embedded template}}{{#if:{{{conditions|}}}|{{space}}{{{conditions}}}}}.{{#if:{{{nooverride|}}}||{{space}}If the automatic short description is not desired, override it by adding {{tl|Short description}} at the top of the article.}}
}}<includeonly>{{Category handler
|nocat={{{nocat|}}}
|template={{Subpage other|<!-- do not categorise -->|[[Category:Templates that generate short descriptions{{#if:{{{category|}}}|{{sp}}for {{{category}}}|}}]]}}
}}</includeonly><noinclude>
{{Documentation}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
07blyt5lqt29d5pi8w24txj1wv4ckme
124202
124201
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Auto_short_description]]
124201
wikitext
text/x-wiki
{{Ombox
| type = notice
| text = This template {{#if:{{{sometimes|}}}|sometimes{{sp}}}}adds an automatically generated '''[[Wikipedia:Short description|short description]]'''{{#if:{{{category|}}}|{{sp}}({{{category}}})|}}{{#if:{{{indirect|}}}|{{sp}}via an embedded template}}{{#if:{{{conditions|}}}|{{space}}{{{conditions}}}}}.{{#if:{{{nooverride|}}}||{{space}}If the automatic short description is not desired, override it by adding {{tl|Short description}} at the top of the article.}}
}}<includeonly>{{Category handler
|nocat={{{nocat|}}}
|template={{Subpage other|<!-- do not categorise -->|[[Category:Templates that generate short descriptions{{#if:{{{category|}}}|{{sp}}for {{{category}}}|}}]]}}
}}</includeonly><noinclude>
{{Documentation}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
07blyt5lqt29d5pi8w24txj1wv4ckme
Module:Location map/data/Africa
828
19790
124191
50817
2023-09-27T08:20:32Z
en>MSGJ
0
+image2, per request
124191
Scribunto
text/plain
return {
name = 'Africa',
x = '48.852459016393 + 71.1 * cos($1 * pi / 180) * sin(($2 - 15) * pi / 180) * (((1 + cos($1 * pi / 180) * cos(($2 - 15) * pi / 180)) * 0.5) ^ - 0.5 )',
y = '51.180555555556 - 75.3 * sin($1 * pi / 180) * (((1 + cos($1 * pi / 180) * cos(($2 - 15) * pi / 180)) * 0.5) ^ -0.5)',
image = 'Africa location map.svg',
image1 = 'Africa relief location map.jpg',
image2 = 'Africa_land_cover_location_map.jpg'
}
6q7ndnrt8ut4fctjq2wpod8rmky9i1s
124192
124191
2026-11-09T20:20:41Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Location_map/data/Africa]]
124191
Scribunto
text/plain
return {
name = 'Africa',
x = '48.852459016393 + 71.1 * cos($1 * pi / 180) * sin(($2 - 15) * pi / 180) * (((1 + cos($1 * pi / 180) * cos(($2 - 15) * pi / 180)) * 0.5) ^ - 0.5 )',
y = '51.180555555556 - 75.3 * sin($1 * pi / 180) * (((1 + cos($1 * pi / 180) * cos(($2 - 15) * pi / 180)) * 0.5) ^ -0.5)',
image = 'Africa location map.svg',
image1 = 'Africa relief location map.jpg',
image2 = 'Africa_land_cover_location_map.jpg'
}
6q7ndnrt8ut4fctjq2wpod8rmky9i1s
Module:Mapframe
828
20573
124177
119023
2026-10-18T22:35:06Z
en>Jonesey95
0
"coordinates" is the canonical form of this parameter. "coord" is not supported by all templates that call this module, so the Lua error message should not suggest putting coordinates in "|coord=".
124177
Scribunto
text/plain
-- Note: Originally written on English Wikipedia at https://en.wikipedia.org/wiki/Module:Mapframe
--[[----------------------------------------------------------------------------
##### Localisation (L10n) settings #####
Replace values in quotes ("") with localised values
----------------------------------------------------------------------------]]--
local L10n = {}
local wb = mw.wikibase
-- Modue dependencies
local parser -- local copy of https://www.mediawiki.org/wiki/Module:WikitextParser loaded lazily
-- "strict" should not be used, at least until all other modules which require this module are not using globals.
-- Template parameter names (unnumbered versions only)
-- Specify each as either a single string, or a table of strings (aliases)
-- Aliases are checked left-to-right, i.e. `{ "one", "two" }` is equivalent to using `{{{one| {{{two|}}} }}}` in a template
L10n.para = {
display = "display",
type = "type",
id = { "id", "ids" },
from = "from",
raw = "raw",
title = "title",
description = "description",
strokeColor = { "stroke-color", "stroke-colour" },
strokeWidth = "stroke-width",
strokeOpacity = "stroke-opacity",
fill = "fill",
fillOpacity = "fill-opacity",
coord = { "coordinates", "coord" },
marker = "marker",
markerColor = { "marker-color", "marker-colour" },
markerSize = "marker-size",
radius = { "radius", "radius_m" },
radiusKm = "radius_km",
radiusFt = "radius_ft",
radiusMi = "radius_mi",
edges = "edges",
text = "text",
icon = "icon",
zoom = "zoom",
frame = "frame",
plain = "plain",
frameWidth = "frame-width",
frameHeight = "frame-height",
frameCoordinates= { "frame-coordinates", "frame-coord" },
frameLatitude = { "frame-lat", "frame-latitude" },
frameLongitude = { "frame-long", "frame-longitude" },
frameAlign = "frame-align",
switch = "switch",
overlay = "overlay",
overlayBorder = "overlay-border",
overlayHorizontalAlignment = "overlay-horizontal-alignment",
overlayVerticalAlignment = "overlay-vertical-alignment",
overlayHorizontalOffset = "overlay-horizontal-offset",
overlayVerticalOffset = "overlay-vertical-offset"
}
-- Names of other templates this module can extract coordinates from
L10n.template = {
templates = { -- The coord template, as well as templates with output that contains {{coord}}
"Coord", "Coord/sandbox",
"NRHP row", "NRHP row/sandbox",
"WikidataCoord", "WikidataCoord/sandbox", "Wikidatacoord", "Wikidata coord"
},
modules = { -- The coordinates module, as well as modules with output that contains {{coord}}
"Coordinates", "Coordinates/sandbox",
"WikidataCoord", "WikidataCoord/sandbox"
}
}
-- Error messages
L10n.error = {
badDisplayPara = "Invalid display parameter",
noCoords = "Coordinates must be specified on Wikidata or in |" .. ( type(L10n.para.coord)== 'table' and L10n.para.coord[1] or L10n.para.coord ) .. "=",
wikidataCoords = "Coordinates not found on Wikidata",
noCircleCoords = "Circle centre coordinates must be specified, or available via Wikidata",
negativeRadius = "Circle radius must be a positive number",
noRadius = "Circle radius must be specified",
negativeEdges = "Circle edges must be a positive number",
noSwitchPara = "Found only one switch value in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
oneSwitchLabel = "Found only one label in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
noSwitchLists = "At least one parameter must have a SWITCH: list",
switchMismatches = "All SWITCH: lists must have the same number of values",
-- "%s" and "%d" tokens will be replaced with strings and numbers when used
oneSwitchValue = "Found only one switch value in |%s=",
fewerSwitchLabels = "Found %d switch values but only %d labels in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
noNamedCoords = "No named coordinates found in %s"
}
-- Other strings
L10n.str = {
-- valid values for display parameter, e.g. (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline)
inline = "inline",
title = "title",
dsep = ",", -- separator between inline and title (comma in the example above)
-- valid values for type parameter
line = "line", -- geoline feature (e.g. a road)
shape = "shape", -- geoshape feature (e.g. a state or province)
shapeInverse = "shape-inverse", -- geomask feature (the inverse of a geoshape)
data = "data", -- geoJSON data page on Commons
point = "point", -- single point feature (coordinates)
circle = "circle", -- circular area around a point
named = "named", -- all named coordinates in an article or section
-- Keyword to indicate a switch list. Must NOT use the special characters ^$()%.[]*+-?
switch = "SWITCH",
-- valid values for icon, frame, and plain parameters
affirmedWords = ' '..table.concat({
"add",
"added",
"affirm",
"affirmed",
"include",
"included",
"on",
"true",
"yes",
"y"
}, ' ')..' ',
declinedWords = ' '..table.concat({
"decline",
"declined",
"exclude",
"excluded",
"false",
"none",
"not",
"no",
"n",
"off",
"omit",
"omitted",
"remove",
"removed"
}, ' ')..' '
}
-- Default values for parameters
L10n.defaults = {
display = L10n.str.inline,
text = "Map",
frameWidth = "300",
frameHeight = "200",
frameAlign = "right",
markerColor = "5E74F3",
markerSize = nil,
strokeColor = "#ff0000",
strokeWidth = 6,
edges = 32, -- number of edges used to approximate a circle
overlayBorder = "1px solid white",
overlayHorizontalAlignment = "right",
overlayHorizontalOffset = "0",
overlayVerticalAlignment = "bottom",
overlayVerticalOffset = "0"
}
-- #### End of L10n settings ####
--[[----------------------------------------------------------------------------
Utility methods
----------------------------------------------------------------------------]]--
local util = {}
--[[
Looks up a parameter value based on the id (a key from the L10n.para table) and
optionally a suffix, for parameters that can be suffixed (e.g. type2 is type
with suffix 2).
@param {table} args key-value pairs of parameter names and their values
@param {string} param_id id for parameter name (key from the L10n.para table)
@param {string} [suffix] suffix for parameter name
@returns {string|nil} parameter value if found, or nil if not found
]]--
function util.getParameterValue(args, param_id, suffix)
suffix = suffix or ''
if type( L10n.para[param_id] ) ~= 'table' then
return args[L10n.para[param_id]..suffix]
end
for _i, paramAlias in ipairs(L10n.para[param_id]) do
if args[paramAlias..suffix] then
return args[paramAlias..suffix]
end
end
return nil
end
--[[
Trim whitespace from args, and remove empty args. Also fix control characters.
@param {table} argsTable
@returns {table} trimmed args table
]]--
function util.trimArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(key) == 'string' and type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val ~= '' then
-- control characters inside json need to be escaped, but stripping them is simpler
-- See also T214984
-- However, *don't* strip control characters from wikitext (text or description parameters) or you'll break strip markers
-- Alternatively it might be better to only strip control char from raw parameter content
if util.matchesParam('text', key) or util.matchesParam('description', key, key:gsub('^%D+(%d+)$', '%1') ) then
cleanArgs[key] = val
else
cleanArgs[key] = val:gsub('%c',' ')
end
end
else
cleanArgs[key] = val
end
end
return cleanArgs
end
--[[
Check if a parameter name matches an unlocalized parameter key
@param {string} key - the unlocalized parameter name to search through
@param {string} name - the localized parameter name to check
@param {string|nil} - an optional suffix to apply to the value(s) from the localization key
@returns {boolean} true if the name matches the parameter, false otherwise
]]--
function util.matchesParam(key, name, suffix)
local param = L10n.para[key]
suffix = suffix or ''
if type(param) == 'table' then
for _, v in pairs(param) do
if (v .. suffix) == name then return true end
end
return false
end
return ((param .. suffix) == name)
end
--[[
Check if a value is affirmed (one of the values in L10n.str.affirmedWords)
@param {string} val Value to be checked
@returns {boolean} true if affirmed, false otherwise
]]--
function util.isAffirmed(val)
if not(val) then return false end
return string.find(L10n.str.affirmedWords, ' '..val..' ', 1, true ) and true or false
end
--[[
Check if a value is declined (one of the values in L10n.str.declinedWords)
@param {string} val Value to be checked
@returns {boolean} true if declined, false otherwise
]]--
function util.isDeclined(val)
if not(val) then return false end
return string.find(L10n.str.declinedWords , ' '..val..' ', 1, true ) and true or false
end
--[[
Check if the name of a template matches the known coord templates or wrappers
(in L10n.template.templates and L10n.template.modules). The name is normalised
when checked, so e.g. the names "Coord", "coord", and " Coord" all return true.
@param {string} name
@returns {boolean} true if it is a coord template or wrapper, false otherwise
]]--
function util.isCoordTemplateOrWrapper(name)
name = mw.text.trim(name)
local modName = mw.ustring.gsub(name, '#invoke:', '')
local inputTitle = mw.title.new(modName, (name ~= modName) and 'Module' or 'Template')
if not inputTitle then
return false
end
-- Create (or reuse) mw.title objects for each known coord template/wrapper.
-- Stored in L10n.template.title so that they don't need to be recreated
-- each time this function is called
if not L10n.template.titles then
L10n.template.titles = {}
for _, v in pairs(L10n.template.templates) do
table.insert(L10n.template.titles, mw.title.new(v, 'Template'))
end
for _, v in pairs(L10n.template.modules) do
table.insert(L10n.template.titles, mw.title.new(v, 'Module'))
end
end
for _, templateTitle in pairs(L10n.template.titles) do
if mw.title.equals(inputTitle, templateTitle) then
return true
end
end
return false
end
--[[
Recursively extract coord templates which have a name parameter.
@param {string} wikitext
@returns {table} table sequence of coord templates
]]--
function util.extractCoordTemplates(wikitext)
local output = {}
local templates = mw.ustring.gmatch(wikitext, '{%b{}}')
for template in templates do
local templateName = mw.ustring.match(template, '{{([^}|]+)')
local nameParam = mw.ustring.match(template, "|%s*name%s*=%s*[^}|]+")
if util.isCoordTemplateOrWrapper(templateName) then
if nameParam then table.insert(output, template) end
elseif mw.ustring.find(mw.ustring.sub(template, 2), "{{") then
local subOutput = util.extractCoordTemplates(mw.ustring.sub(template, 2))
for _, t in pairs(subOutput) do
table.insert(output, t)
end
end
end
-- ensure coords are not using title display
for k, v in pairs(output) do
output[k] = mw.ustring.gsub(v, "|%s*display%s*=[^|}]+", "|display=inline")
end
return output
end
--[[
Gets all named coordinates from a page or a section of a page.
@param {string|nil} page Page name, or name#section, to get named coordinates
from. If the name is omitted, i.e. #section or nil or empty string, then
the current page will be used.
@returns {table} sequence of {coord, name, description} tables where coord is
the coordinates in a format suitable for #util.parseCoords, name is a string,
and description is a string (coordinates in a format suitable for displaying
to the reader). If for some reason the name can't be found, the description
is nil and the name contains display-format coordinates.
@throws {L10n.error.noNamedCoords} if no named coordinates are found.
]]--
function util.getNamedCoords(page)
local parts = mw.text.split(page or "", "#", true)
local name = parts[1] == "" and mw.title.getCurrentTitle().prefixedText or parts[1]
local section = parts[2]
local title = mw.title.new(name)
if title.isRedirect then
title = title.redirectTarget
end
local pageWikitext = title:getContent()
if section then
if parser == nil then
-- load [[Module:WikitextParser]] lazily so it is only transcluded on pages that use it
parser = require("Module:WikitextParser")
end
pageWikitext = parser.getSection(pageWikitext, section) or ''
end
local coordTemplates = util.extractCoordTemplates(pageWikitext)
if #coordTemplates == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end
local frame = mw.getCurrentFrame()
local sep = "________"
local expandedContent = frame:preprocess(table.concat(coordTemplates, sep))
local expandedTemplates = mw.text.split(expandedContent, sep)
local namedCoords = {}
for _, expandedTemplate in pairs(expandedTemplates) do
local coord = mw.ustring.match(expandedTemplate, "<span class=\"geo%-dec\".->(.-)</span>")
if coord then
local coordname = (
-- name specified by a wrapper template, e.g [[Article|Name]]
mw.ustring.match(expandedTemplate, "<span class=\"mapframe%-coord%-name\">(.-)</span>") or
-- name passed into coord template
mw.ustring.match(expandedTemplate, "<span class=\"fn org\">(.-)</span>") or
-- default to the coordinates if the name can't be retrieved
coord
)
local description = coordname ~= coord and coord
table.insert(namedCoords, {
coord=mw.ustring.gsub(coord, "[° ]", "_"),
name=coordname, description=description
})
end
end
if #namedCoords == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end
return namedCoords
end
--[[
Parse coordinate values from the params passed in a GeoHack url (such as
//tools.wmflabs.org/geohack/geohack.php?pagename=Example¶ms=1_2_N_3_4_W_ or
//tools.wmflabs.org/geohack/geohack.php?pagename=Example¶ms=1.23_S_4.56_E_ )
or non-url string in the same format (such as `1_2_N_3_4_W_` or `1.23_S_4.56_E_`)
@param {string} coords string containing coordinates
@returns {number, number} latitude, longitude
]]--
function util.parseCoords(coords)
local coordsPatt
if mw.ustring.find(coords, "params=", 1, true) then
-- prevent false matches from page name, e.g. ?pagename=Lorem_S._Ipsum
coordsPatt = 'params=([_%.%d]+[NS][_%.%d]+[EW])'
else
-- not actually a geohack url, just the same format
coordsPatt = '[_%.%d]+[NS][_%.%d]+[EW]'
end
local parts = mw.text.split((mw.ustring.match(coords, coordsPatt) or ''), '_')
local lat_d = tonumber(parts[1])
assert(lat_d, "Unable to get latitude from input '"..coords.."'.")
local lat_m = tonumber(parts[2]) -- nil if coords are in decimal format
local lat_s = lat_m and tonumber(parts[3]) -- nil if coords are either in decimal format or degrees and minutes only
local lat = lat_d + (lat_m or 0)/60 + (lat_s or 0)/3600
if parts[#parts/2] == 'S' then
lat = lat * -1
end
local long_d = tonumber(parts[1+#parts/2])
assert(long_d, "Unable to get longitude from input '"..coords.."'.")
local long_m = tonumber(parts[2+#parts/2]) -- nil if coords are in decimal format
local long_s = long_m and tonumber(parts[3+#parts/2]) -- nil if coords are either in decimal format or degrees and minutes only
local long = long_d + (long_m or 0)/60 + (long_s or 0)/3600
if parts[#parts] == 'W' then
long = long * -1
end
return lat, long
end
--[[
Get coordinates from a Wikidata item
@param {string} item_id Wikidata item id (Q number)
@returns {number, number} latitude, longitude
@throws {L10n.error.noCoords} if item_id is invalid or the item does not exist
@throws {L10n.error.wikidataCoords} if the the item does not have a P625
statement (coordinates), or it is set to "no value"
]]--
function util.wikidataCoords(item_id)
if not (item_id and wb.isValidEntityId(item_id) and wb.entityExists(item_id)) then
error(L10n.error.noCoords, 0)
end
local coordStatements = wb.getBestStatements(item_id, 'P625')
if not coordStatements or #coordStatements == 0 then
error(L10n.error.wikidataCoords, 0)
end
local hasNoValue = ( coordStatements[1].mainsnak and (coordStatements[1].mainsnak.snaktype == 'novalue' or coordStatements[1].mainsnak.snaktype == 'somevalue') )
if hasNoValue then
error(L10n.error.wikidataCoords, 0)
end
local wdCoords = coordStatements[1]['mainsnak']['datavalue']['value']
return tonumber(wdCoords['latitude']), tonumber(wdCoords['longitude'])
end
--[[
Creates a polygon that approximates a circle
@param {number} lat Latitude
@param {number} long Longitude
@param {number} radius Radius in metres
@param {number} n Number of edges for the polygon
@returns {table} sequence of {latitude, longitude} table sequences, where
latitude and longitude are both numbers
]]--
function util.circleToPolygon(lat, long, radius, n) -- n is number of edges
-- Based on https://github.com/gabzim/circle-to-polygon, ISC licence
local function offset(cLat, cLon, distance, bearing)
local lat1 = math.rad(cLat)
local lon1 = math.rad(cLon)
local dByR = distance / 6378137 -- distance divided by 6378137 (radius of the earth) wgs84
local offet_lat = math.asin(
math.sin(lat1) * math.cos(dByR) +
math.cos(lat1) * math.sin(dByR) * math.cos(bearing)
)
local offet_lon = lon1 + math.atan2(
math.sin(bearing) * math.sin(dByR) * math.cos(lat1),
math.cos(dByR) - math.sin(lat1) * math.sin(offet_lat)
)
return {math.deg(offet_lon), math.deg(offet_lat)}
end
local coordinates = {};
local i = 0;
while i < n do
table.insert(coordinates,
offset(lat, long, radius, (2*math.pi*i*-1)/n)
)
i = i + 1
end
table.insert(coordinates, offset(lat, long, radius, 0))
return coordinates
end
--[[
Get the number of key-value pairs in a table, which might not be a sequence.
@param {table} t
@returns {number} count of key-value pairs
]]--
function util.tableCount(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
--[[
For a table where the values are all tables, returns either the util.tableCount
of the subtables if they are all the same, or nil if they are not all the same.
@param {table} t
@returns {number|nil} count of key-value pairs of subtable, or nil if subtables
have different counts
]]--
function util.subTablesCount(t)
local count = nil
for k, v in pairs(t) do
if count == nil then
count = util.tableCount(v)
elseif count ~= util.tableCount(v) then
return nil
end
end
return count
end
--[[
Splits a list into a table sequence. The items in the list may be separated by
commas, or by semicolons (if items may contain commas), or by "###" (if items
may contain semicolons).
@param {string} listString
@returns {table} sequence of list items
]]--
function util.tableFromList(listString)
if type(listString) ~= "string" or listString == "" then return nil end
local separator = (mw.ustring.find(listString, "###", 0, true ) and "###") or
(mw.ustring.find(listString, ";", 0, true ) and ";") or ","
local pattern = "%s*"..separator.."%s*"
return mw.text.split(listString, pattern)
end
-- Boolean in outer scope indicating if Kartographer should be able to
-- automatically calculate coordinates (see phab:T227402)
local coordsDerivedFromFeatures = false;
--[[----------------------------------------------------------------------------
Make methods: These take in a table of arguments, and return either a string
or a table to be used in the eventual output.
----------------------------------------------------------------------------]]--
local make = {}
--[[
Makes content to go inside the maplink or mapframe tag.
@param {table} args
@returns {string} tag content
]]--
function make.content(args)
if util.getParameterValue(args, 'raw') then
coordsDerivedFromFeatures = true -- Kartographer should be able to automatically calculate coords from raw geoJSON
return util.getParameterValue(args, 'raw')
end
local content = {}
local argsExpanded = {}
for k, v in pairs(args) do
local index = string.match( k, '^[^0-9]+([0-9]*)$' )
if index ~= nil then
local indexNumber
if index ~= '' then
indexNumber = tonumber(index)
else
indexNumber = 1
end
if argsExpanded[indexNumber] == nil then
argsExpanded[indexNumber] = {}
end
argsExpanded[indexNumber][ string.gsub(k, index, '') ] = v
end
end
for contentIndex, contentArgs in pairs(argsExpanded) do
local argType = util.getParameterValue(contentArgs, "type")
-- Kartographer automatically calculates coords if geolines/shapes are used (T227402)
if not coordsDerivedFromFeatures then
coordsDerivedFromFeatures = ( argType == L10n.str.line or argType == L10n.str.shape ) and true or false
end
if argType == L10n.str.named then
local namedCoords = util.getNamedCoords(util.getParameterValue(contentArgs, "from"))
local typeKey = type(L10n.para.type) == "table" and L10n.para.type[1] or L10n.para.type
local coordKey = type(L10n.para.coord) == "table" and L10n.para.coord[1] or L10n.para.coord
local titleKey = type(L10n.para.title) == "table" and L10n.para.title[1] or L10n.para.title
local descKey = type(L10n.para.description) == "table" and L10n.para.description[1] or L10n.para.description
for _, namedCoord in pairs(namedCoords) do
contentArgs[typeKey] = "point"
contentArgs[coordKey] = namedCoord.coord
contentArgs[titleKey] = namedCoord.name
contentArgs[descKey] = namedCoord.description
content[#content+1] = make.contentJson(contentArgs)
end
else
content[#content + 1] = make.contentJson(contentArgs)
end
end
--Single item, no array needed
if #content==1 then return content[1] end
--Multiple items get placed in a FeatureCollection
local contentArray = '[\n' .. table.concat( content, ',\n') .. '\n]'
return contentArray
end
--[[
Make coordinates from the coord arg, or the id arg, or the current page's
Wikidata item.
@param {table} args
@param {boolean} [plainOutput]
@returns {Mixed} Either:
{number, number} latitude, longitude if plainOutput is true; or
{table} table sequence of longitude, then latitude (gives the required format
for GeoJSON when encoded)
]]--
function make.coords(args, plainOutput)
local coords, lat, long
local frame = mw.getCurrentFrame()
if util.getParameterValue(args, 'coord') then
coords = frame:preprocess( util.getParameterValue(args, 'coord') )
lat, long = util.parseCoords(coords)
else
lat, long = util.wikidataCoords(util.getParameterValue(args, 'id') or wb.getEntityIdForCurrentPage())
end
if plainOutput then
return lat, long
end
return {[0] = long, [1] = lat}
end
--[[
Makes a table of coordinates that approximate a circle.
@param {table} args
@returns {table} sequence of {latitude, longitude} table sequences, where
latitude and longitude are both numbers
@throws {L10n.error.noCircleCoords} if centre coordinates are not specified
@throws {L10n.error.noRadius} if radius is not specified
@throws {L10n.error.negativeRadius} if radius is negative or zero
@throws {L10n.error.negativeEdges} if edges is negative or zero
]]--
function make.circleCoords(args)
local lat, long = make.coords(args, true)
local radius = util.getParameterValue(args, 'radius')
if not radius then
radius = util.getParameterValue(args, 'radiusKm') and tonumber(util.getParameterValue(args, 'radiusKm'))*1000
if not radius then
radius = util.getParameterValue(args, 'radiusMi') and tonumber(util.getParameterValue(args, 'radiusMi'))*1609.344
if not radius then
radius = util.getParameterValue(args, 'radiusFt') and tonumber(util.getParameterValue(args, 'radiusFt'))*0.3048
end
end
end
local edges = util.getParameterValue(args, 'edges') or L10n.defaults.edges
if not lat or not long then
error(L10n.error.noCircleCoords, 0)
elseif not radius then
error(L10n.error.noRadius, 0)
elseif tonumber(radius) <= 0 then
error(L10n.error.negativeRadius, 0)
elseif tonumber(edges) <= 0 then
error(L10n.error.negativeEdges, 0)
end
return util.circleToPolygon(lat, long, radius, tonumber(edges))
end
--[[
Makes JSON data for a feature
@param contentArgs args for this feature. Keys must be the non-suffixed version
of the parameter names, i.e. use type, stroke, fill,... rather than type3,
stroke3, fill3,...
@returns {string} JSON encoded data
]]--
function make.contentJson(contentArgs)
local data = {}
if util.getParameterValue(contentArgs, 'type') == L10n.str.point or util.getParameterValue(contentArgs, 'type') == L10n.str.circle then
local isCircle = util.getParameterValue(contentArgs, 'type') == L10n.str.circle
data.type = "Feature"
data.geometry = {
type = isCircle and "LineString" or "Point",
coordinates = isCircle and make.circleCoords(contentArgs) or make.coords(contentArgs)
}
data.properties = {
title = util.getParameterValue(contentArgs, 'title') or mw.getCurrentFrame():getParent():getTitle()
}
if isCircle then
-- TODO: This is very similar to below, should be extracted into a function
data.properties.stroke = util.getParameterValue(contentArgs, 'strokeColor') or L10n.defaults.strokeColor
data.properties["stroke-width"] = tonumber(util.getParameterValue(contentArgs, 'strokeWidth')) or L10n.defaults.strokeWidth
local strokeOpacity = util.getParameterValue(contentArgs, 'strokeOpacity')
if strokeOpacity then
data.properties['stroke-opacity'] = tonumber(strokeOpacity)
end
local fill = util.getParameterValue(contentArgs, 'fill')
if fill then
data.properties.fill = fill
local fillOpacity = util.getParameterValue(contentArgs, 'fillOpacity')
data.properties['fill-opacity'] = fillOpacity and tonumber(fillOpacity) or 0.6
end
else -- is a point
local markerSymbol = util.getParameterValue(contentArgs, 'marker') or L10n.defaults.marker
-- allow blank to be explicitly specified, for overriding infoboxes or other templates with a default value
if markerSymbol ~= "blank" then
data.properties["marker-symbol"] = markerSymbol
end
data.properties["marker-color"] = util.getParameterValue(contentArgs, 'markerColor') or L10n.defaults.markerColor
data.properties["marker-size"] = util.getParameterValue(contentArgs, 'markerSize') or L10n.defaults.markerSize
end
else
data.type = "ExternalData"
if util.getParameterValue(contentArgs, 'type') == L10n.str.data or util.getParameterValue(contentArgs, 'from') then
data.service = "page"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.line then
data.service = "geoline"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.shape then
data.service = "geoshape"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.shapeInverse then
data.service = "geomask"
end
if util.getParameterValue(contentArgs, 'id') or (not (util.getParameterValue(contentArgs, 'from')) and wb.getEntityIdForCurrentPage()) then
data.ids = util.getParameterValue(contentArgs, 'id') or wb.getEntityIdForCurrentPage()
else
data.title = util.getParameterValue(contentArgs, 'from')
end
data.properties = {
stroke = util.getParameterValue(contentArgs, 'strokeColor') or L10n.defaults.strokeColor,
["stroke-width"] = tonumber(util.getParameterValue(contentArgs, 'strokeWidth')) or L10n.defaults.strokeWidth
}
local strokeOpacity = util.getParameterValue(contentArgs, 'strokeOpacity')
if strokeOpacity then
data.properties['stroke-opacity'] = tonumber(strokeOpacity)
end
local fill = util.getParameterValue(contentArgs, 'fill')
if fill and (data.service == "geoshape" or data.service == "geomask") then
data.properties.fill = fill
local fillOpacity = util.getParameterValue(contentArgs, 'fillOpacity')
if fillOpacity then
data.properties['fill-opacity'] = tonumber(fillOpacity)
end
end
end
data.properties.title = util.getParameterValue(contentArgs, 'title') or mw.title.getCurrentTitle().text
if util.getParameterValue(contentArgs, 'description') then
data.properties.description = util.getParameterValue(contentArgs, 'description')
end
return mw.text.jsonEncode(data)
end
--[[
Makes attributes for the maplink or mapframe tag.
@param {table} args
@param {boolean} [isTitle] Tag is to be displayed in the title of page rather
than inline
@returns {table<string,string>} key-value pairs of attribute names and values
]]--
function make.tagAttribs(args, isTitle)
local attribs = {}
if util.getParameterValue(args, 'zoom') then
attribs.zoom = util.getParameterValue(args, 'zoom')
end
if util.isDeclined(util.getParameterValue(args, 'icon')) then
attribs.class = "no-icon"
end
if util.getParameterValue(args, 'type') == L10n.str.point and not coordsDerivedFromFeatures then
local lat, long = make.coords(args, 'plainOutput')
attribs.latitude = tostring(lat)
attribs.longitude = tostring(long)
end
if util.isAffirmed(util.getParameterValue(args, 'frame')) and not(isTitle) then
attribs.width = util.getParameterValue(args, 'frameWidth') or L10n.defaults.frameWidth
attribs.height = util.getParameterValue(args, 'frameHeight') or L10n.defaults.frameHeight
if util.getParameterValue(args, 'frameCoordinates') then
local frameLat, frameLong = util.parseCoords(util.getParameterValue(args, 'frameCoordinates'))
attribs.latitude = frameLat
attribs.longitude = frameLong
else
if util.getParameterValue(args, 'frameLatitude') then
attribs.latitude = util.getParameterValue(args, 'frameLatitude')
end
if util.getParameterValue(args, 'frameLongitude') then
attribs.longitude = util.getParameterValue(args, 'frameLongitude')
end
end
if not attribs.latitude and not attribs.longitude and not coordsDerivedFromFeatures then
local success, lat, long = pcall(util.wikidataCoords, util.getParameterValue(args, 'id') or wb.getEntityIdForCurrentPage())
if success then
attribs.latitude = tostring(lat)
attribs.longitude = tostring(long)
end
end
if util.getParameterValue(args, 'frameAlign') then
attribs.align = util.getParameterValue(args, 'frameAlign')
end
if util.isAffirmed(util.getParameterValue(args, 'plain')) then
attribs.frameless = "1"
else
attribs.text = util.getParameterValue(args, 'text') or L10n.defaults.text
end
else
attribs.text = util.getParameterValue(args, 'text') or L10n.defaults.text
end
return attribs
end
--[[
Makes maplink wikitext that will be located in the top-right of the title of the
page (the same place where coords with |display=title are positioned).
@param {table} args
@param {string} tagContent Content for the maplink tag
@returns {string}
]]--
function make.titleOutput(args, tagContent)
local titleTag = mw.text.tag('maplink', make.tagAttribs(args, true), tagContent)
local spanAttribs = {
style = "font-size: small;",
id = "mapframe-coordinates"
}
local indicatorContent = mw.text.tag('span', spanAttribs, titleTag)
return mw.getCurrentFrame():extensionTag {
name = "indicator",
content = indicatorContent,
args = {
name = "zzz-mapframe" --zzz: show as last indicator
}
}
end
--[[
Makes maplink or mapframe wikitext that will be located inline.
@param {table} args
@param {string} tagContent Content for the maplink tag
@returns {string}
]]--
function make.inlineOutput(args, tagContent)
local tagName = 'maplink'
if util.getParameterValue(args, 'frame') then
tagName = 'mapframe'
end
return mw.text.tag(tagName, make.tagAttribs(args), tagContent)
end
--[[
Makes the HTML required for the swicther to work, including the templatestyles
tag.
@param {table} params table sequence of {map, label} tables
@param {string} params{}.map Wikitext for mapframe map
@param {string} params{}.label Label text for swicther option
@param {table} options
@param {string} options.alignment "left" or "center" or "right"
@param {boolean} options.isThumbnail Display in a thumbnail
@param {string} options.width Width of frame, e.g. "200"
@param {string} [options.caption] Caption wikitext for thumnail
@retruns {string} swicther HTML
]]--
function make.switcherHtml(params, options)
options = options or {}
local frame = mw.getCurrentFrame()
local styles = frame:extensionTag{
name = "templatestyles",
args = {src = "Template:Maplink/styles-multi.css"}
}
local container = mw.html.create("div")
:addClass("switcher-container")
:addClass("mapframe-multi-container")
if options.alignment == "left" or options.alignment == "right" then
container:addClass("float"..options.alignment)
else -- alignment is "center"
container:addClass("center")
end
for i = 1, #params do
container
:tag("div")
:wikitext(params[i].map)
:tag("span")
:addClass("switcher-label")
:css("display", "none")
:wikitext(mw.text.trim(params[i].label))
end
if not options.isThumbnail then
return styles .. tostring(container)
end
local classlist = container:getAttr("class")
classlist = mw.ustring.gsub(classlist, "%a*"..options.alignment, "")
container:attr("class", classlist)
local outerCountainer = mw.html.create("div")
:addClass("mapframe-multi-outer-container")
:addClass("mw-kartographer-container")
:addClass("thumb")
if options.alignment == "left" or options.alignment == "right" then
outerCountainer:addClass("float"..options.alignment)
else -- alignment is "center"
outerCountainer
:addClass("tnone")
:addClass("center")
end
outerCountainer
:tag("div")
:addClass("thumbinner")
:css("width", options.width.."px")
:node(container)
:node(options.caption and mw.html.create("div")
:addClass("thumbcaption")
:wikitext(options.caption)
)
return styles .. tostring(outerCountainer)
end
--[[
Makes the HTML required for an overlay map to work
tag.
@param {string} overlayMap wikitext for the overlay map
@param {string} baseMap wikitext for the base map
@param {table} options various styling/display options
@param {string} options.align "left" or "center" or "right"
@param {string|number} options.width Width of the base map, e.g. "300"
@param {string|number} options.width Height of the base map, e.g. "200"
@param {string} options.border Border style for the overlayed map, e.g. "1px solid white"
@param {string} options.horizontalAlignment Horizontal alignment for overlay map, "left" or "right"
@param {string|number} options.horizontalOffset Horizontal offset in pixels from the alignment edge, e.g "10"
@param {string} options.verticalAlignment Vertical alignment for overlay map, "top" or "bottom"
@param {string|number} options.verticalOffset Vertical offset in pixels from the alignment edge, e.g. is "10"
@param {boolean} options.isThumbnail Display in a thumbnail
@param {string} [options.caption] Caption wikitext for thumnail
@retruns {string} HTML for basemap with overlay
]]--
function make.overlayHtml(overlayMap, baseMap, options)
options = options or {}
local containerFloatClass = "float"..(options.align or "none")
if options.align == "center" then
containerFloatClass = "center"
end
local containerStyle = {
position = "relative",
width = options.width .. "px",
height = options.height .. "px",
overflow = "hidden" -- mobile/minerva tends to add scrollbars for a couple of pixels
}
if options.align == "center" then
containerStyle["margin-left"] = "auto"
containerStyle["margin-right"] = "auto"
end
local container = mw.html.create("div")
:addClass("mapframe-withOverlay-container")
:addClass(containerFloatClass)
:addClass("noresize")
:css(containerStyle)
local overlayStyle = {
position = "absolute",
["z-index"] = "1",
border = options.border or "1px solid white"
}
if options.horizontalAlignment == "right" then
overlayStyle.right = options.horizontalOffset .. "px"
else
overlayStyle.left = options.horizontalOffset .. "px"
end
if options.verticalAlignment == "bottom" then
overlayStyle.bottom = options.verticalOffset .. "px"
else
overlayStyle.top = options.verticalOffset .. "px"
end
local overlayDiv = mw.html.create("div")
:css(overlayStyle)
:wikitext(overlayMap)
container
:node(overlayDiv)
:wikitext(baseMap)
if not options.isThumbnail then
return tostring(container)
end
local classlist = container:getAttr("class")
classlist = mw.ustring.gsub(classlist, "%a*"..options.align, "")
container:attr("class", classlist)
local outerCountainer = mw.html.create("div")
:addClass("mapframe-withOverlay-outerContainer")
:addClass("mw-kartographer-container")
:addClass("thumb")
if options.align == "left" or options.align == "right" then
outerCountainer:addClass("t"..options.align)
else -- alignment is "center"
outerCountainer
:addClass("tnone")
:addClass("center")
end
outerCountainer
:tag("div")
:addClass("thumbinner")
:css("width", options.width.."px")
:node(container)
:node(options.caption and mw.html.create("div")
:addClass("thumbcaption")
:wikitext(options.caption)
)
return tostring(outerCountainer)
end
--[[----------------------------------------------------------------------------
Package to be exported, i.e. methods which will available to templates and
other modules.
----------------------------------------------------------------------------]]--
local p = {}
-- Entry point for templates
function p.main(frame)
local parent = frame.getParent(frame)
-- Check for overlay option
local overlay = util.getParameterValue(parent.args, 'overlay')
local hasOverlay = overlay and mw.text.trim(overlay) ~= ""
-- Check for switch option
local switch = util.getParameterValue(parent.args, 'switch')
local isMulti = switch and mw.text.trim(switch) ~= ""
-- Create output by choosing method to suit options
local output
if hasOverlay then
output = p.withOverlay(parent.args)
elseif isMulti then
output = p.multi(parent.args)
else
output = p._main(parent.args)
end
-- Preprocess output before returning it
return frame:preprocess(output)
end
-- Entry points for modules
function p._main(_args)
local args = util.trimArgs(_args)
local tagContent = make.content(args)
local display = mw.text.split(util.getParameterValue(args, 'display') or L10n.defaults.display, '%s*' .. L10n.str.dsep .. '%s*')
local displayInTitle = display[1] == L10n.str.title or display[2] == L10n.str.title
local displayInline = display[1] == L10n.str.inline or display[2] == L10n.str.inline
local output
if displayInTitle and displayInline then
output = make.titleOutput(args, tagContent) .. make.inlineOutput(args, tagContent)
elseif displayInTitle then
output = make.titleOutput(args, tagContent)
elseif displayInline then
output = make.inlineOutput(args, tagContent)
else
error(L10n.error.badDisplayPara)
end
return output
end
function p.multi(_args)
local args = util.trimArgs(_args)
if not args[L10n.para.switch] then error(L10n.error.noSwitchPara, 0) end
local switchParamValue = util.getParameterValue(args, 'switch')
local switchLabels = util.tableFromList(switchParamValue)
if #switchLabels == 1 then error(L10n.error.oneSwitchLabel, 0) end
local mapframeArgs = {}
local switchParams = {}
for name, val in pairs(args) do
-- Copy to mapframeArgs, if not the switch labels or a switch parameter
if val ~= switchParamValue and not string.match(val, "^"..L10n.str.switch..":") then
mapframeArgs[name] = val
end
-- Check if this is a param to switch. If so, store the name and switch
-- values in switchParams table.
local switchList = string.match(val, "^"..L10n.str.switch..":(.+)")
if switchList ~= nil then
local values = util.tableFromList(switchList)
if #values == 1 then
error(string.format(L10n.error.oneSwitchValue, name), 0)
end
switchParams[name] = values
end
end
if util.tableCount(switchParams) == 0 then
error(L10n.error.noSwitchLists, 0)
end
local switchCount = util.subTablesCount(switchParams)
if not switchCount then
error(L10n.error.switchMismatches, 0)
elseif switchCount > #switchLabels then
error(string.format(L10n.error.fewerSwitchLabels, switchCount, #switchLabels), 0)
end
-- Ensure a plain frame will be used (thumbnail will be built by the
-- make.switcherHtml function if required, so that switcher options are
-- inside the thumnail)
mapframeArgs.plain = "yes"
local switcher = {}
for i = 1, switchCount do
local label = switchLabels[i]
for name, values in pairs(switchParams) do
mapframeArgs[name] = values[i]
end
table.insert(switcher, {
map = p._main(mapframeArgs),
label = "Show "..label
})
end
return make.switcherHtml(switcher, {
alignment = args["frame-align"] or "right",
isThumbnail = (args.frame and not args.plain) and true or false,
width = args["frame-width"] or L10n.defaults.frameWidth,
caption = args.text
})
end
function p.withOverlay(_args)
-- Get and trim wikitext for overlay map
local overlayMap = _args.overlay
if type(overlayMap) == 'string' then
overlayMap = overlayMap:match('^%s*(.-)%s*$')
end
local isThumbnail = (util.getParameterValue(_args, "frame") and not util.getParameterValue(_args, "plain")) and true or false
-- Get base map using the _main function, as a plain map
local args = util.trimArgs(_args)
args.plain = "yes"
local basemap = p._main(args)
-- Extract overlay options from args
local overlayOptions = {
width = util.getParameterValue(args, "frameWidth") or L10n.defaults.frameWidth,
height = util.getParameterValue(args, "frameHeight") or L10n.defaults.frameHeight,
align = util.getParameterValue(args, "frameAlign") or L10n.defaults.frameAlign,
border = util.getParameterValue(args, "overlayBorder") or L10n.defaults.overlayBorder,
horizontalAlignment = util.getParameterValue(args, "overlayHorizontalAlignment") or L10n.defaults.overlayHorizontalAlignment,
horizontalOffset = util.getParameterValue(args, "overlayHorizontalOffset") or L10n.defaults.overlayHorizontalOffset,
verticalAlignment = util.getParameterValue(args, "overlayVerticalAlignment") or L10n.defaults.overlayVerticalAlignment,
verticalOffset = util.getParameterValue(args, "overlayVerticalOffset") or L10n.defaults.overlayVerticalOffset,
isThumbnail = isThumbnail,
caption = util.getParameterValue(args, "text") or L10n.defaults.text
}
-- Make the HTML for the overlaying maps
return make.overlayHtml(overlayMap, basemap, overlayOptions)
end
-- Entry point for testcase tests
p.test = util
return p
cbg20zhedgvi7tds8motk323r37gona
124178
124177
2026-11-09T20:20:38Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Mapframe]]
124177
Scribunto
text/plain
-- Note: Originally written on English Wikipedia at https://en.wikipedia.org/wiki/Module:Mapframe
--[[----------------------------------------------------------------------------
##### Localisation (L10n) settings #####
Replace values in quotes ("") with localised values
----------------------------------------------------------------------------]]--
local L10n = {}
local wb = mw.wikibase
-- Modue dependencies
local parser -- local copy of https://www.mediawiki.org/wiki/Module:WikitextParser loaded lazily
-- "strict" should not be used, at least until all other modules which require this module are not using globals.
-- Template parameter names (unnumbered versions only)
-- Specify each as either a single string, or a table of strings (aliases)
-- Aliases are checked left-to-right, i.e. `{ "one", "two" }` is equivalent to using `{{{one| {{{two|}}} }}}` in a template
L10n.para = {
display = "display",
type = "type",
id = { "id", "ids" },
from = "from",
raw = "raw",
title = "title",
description = "description",
strokeColor = { "stroke-color", "stroke-colour" },
strokeWidth = "stroke-width",
strokeOpacity = "stroke-opacity",
fill = "fill",
fillOpacity = "fill-opacity",
coord = { "coordinates", "coord" },
marker = "marker",
markerColor = { "marker-color", "marker-colour" },
markerSize = "marker-size",
radius = { "radius", "radius_m" },
radiusKm = "radius_km",
radiusFt = "radius_ft",
radiusMi = "radius_mi",
edges = "edges",
text = "text",
icon = "icon",
zoom = "zoom",
frame = "frame",
plain = "plain",
frameWidth = "frame-width",
frameHeight = "frame-height",
frameCoordinates= { "frame-coordinates", "frame-coord" },
frameLatitude = { "frame-lat", "frame-latitude" },
frameLongitude = { "frame-long", "frame-longitude" },
frameAlign = "frame-align",
switch = "switch",
overlay = "overlay",
overlayBorder = "overlay-border",
overlayHorizontalAlignment = "overlay-horizontal-alignment",
overlayVerticalAlignment = "overlay-vertical-alignment",
overlayHorizontalOffset = "overlay-horizontal-offset",
overlayVerticalOffset = "overlay-vertical-offset"
}
-- Names of other templates this module can extract coordinates from
L10n.template = {
templates = { -- The coord template, as well as templates with output that contains {{coord}}
"Coord", "Coord/sandbox",
"NRHP row", "NRHP row/sandbox",
"WikidataCoord", "WikidataCoord/sandbox", "Wikidatacoord", "Wikidata coord"
},
modules = { -- The coordinates module, as well as modules with output that contains {{coord}}
"Coordinates", "Coordinates/sandbox",
"WikidataCoord", "WikidataCoord/sandbox"
}
}
-- Error messages
L10n.error = {
badDisplayPara = "Invalid display parameter",
noCoords = "Coordinates must be specified on Wikidata or in |" .. ( type(L10n.para.coord)== 'table' and L10n.para.coord[1] or L10n.para.coord ) .. "=",
wikidataCoords = "Coordinates not found on Wikidata",
noCircleCoords = "Circle centre coordinates must be specified, or available via Wikidata",
negativeRadius = "Circle radius must be a positive number",
noRadius = "Circle radius must be specified",
negativeEdges = "Circle edges must be a positive number",
noSwitchPara = "Found only one switch value in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
oneSwitchLabel = "Found only one label in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
noSwitchLists = "At least one parameter must have a SWITCH: list",
switchMismatches = "All SWITCH: lists must have the same number of values",
-- "%s" and "%d" tokens will be replaced with strings and numbers when used
oneSwitchValue = "Found only one switch value in |%s=",
fewerSwitchLabels = "Found %d switch values but only %d labels in |" .. ( type(L10n.para.switch)== 'table' and L10n.para.switch[1] or L10n.para.switch ) .. "=",
noNamedCoords = "No named coordinates found in %s"
}
-- Other strings
L10n.str = {
-- valid values for display parameter, e.g. (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline)
inline = "inline",
title = "title",
dsep = ",", -- separator between inline and title (comma in the example above)
-- valid values for type parameter
line = "line", -- geoline feature (e.g. a road)
shape = "shape", -- geoshape feature (e.g. a state or province)
shapeInverse = "shape-inverse", -- geomask feature (the inverse of a geoshape)
data = "data", -- geoJSON data page on Commons
point = "point", -- single point feature (coordinates)
circle = "circle", -- circular area around a point
named = "named", -- all named coordinates in an article or section
-- Keyword to indicate a switch list. Must NOT use the special characters ^$()%.[]*+-?
switch = "SWITCH",
-- valid values for icon, frame, and plain parameters
affirmedWords = ' '..table.concat({
"add",
"added",
"affirm",
"affirmed",
"include",
"included",
"on",
"true",
"yes",
"y"
}, ' ')..' ',
declinedWords = ' '..table.concat({
"decline",
"declined",
"exclude",
"excluded",
"false",
"none",
"not",
"no",
"n",
"off",
"omit",
"omitted",
"remove",
"removed"
}, ' ')..' '
}
-- Default values for parameters
L10n.defaults = {
display = L10n.str.inline,
text = "Map",
frameWidth = "300",
frameHeight = "200",
frameAlign = "right",
markerColor = "5E74F3",
markerSize = nil,
strokeColor = "#ff0000",
strokeWidth = 6,
edges = 32, -- number of edges used to approximate a circle
overlayBorder = "1px solid white",
overlayHorizontalAlignment = "right",
overlayHorizontalOffset = "0",
overlayVerticalAlignment = "bottom",
overlayVerticalOffset = "0"
}
-- #### End of L10n settings ####
--[[----------------------------------------------------------------------------
Utility methods
----------------------------------------------------------------------------]]--
local util = {}
--[[
Looks up a parameter value based on the id (a key from the L10n.para table) and
optionally a suffix, for parameters that can be suffixed (e.g. type2 is type
with suffix 2).
@param {table} args key-value pairs of parameter names and their values
@param {string} param_id id for parameter name (key from the L10n.para table)
@param {string} [suffix] suffix for parameter name
@returns {string|nil} parameter value if found, or nil if not found
]]--
function util.getParameterValue(args, param_id, suffix)
suffix = suffix or ''
if type( L10n.para[param_id] ) ~= 'table' then
return args[L10n.para[param_id]..suffix]
end
for _i, paramAlias in ipairs(L10n.para[param_id]) do
if args[paramAlias..suffix] then
return args[paramAlias..suffix]
end
end
return nil
end
--[[
Trim whitespace from args, and remove empty args. Also fix control characters.
@param {table} argsTable
@returns {table} trimmed args table
]]--
function util.trimArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(key) == 'string' and type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val ~= '' then
-- control characters inside json need to be escaped, but stripping them is simpler
-- See also T214984
-- However, *don't* strip control characters from wikitext (text or description parameters) or you'll break strip markers
-- Alternatively it might be better to only strip control char from raw parameter content
if util.matchesParam('text', key) or util.matchesParam('description', key, key:gsub('^%D+(%d+)$', '%1') ) then
cleanArgs[key] = val
else
cleanArgs[key] = val:gsub('%c',' ')
end
end
else
cleanArgs[key] = val
end
end
return cleanArgs
end
--[[
Check if a parameter name matches an unlocalized parameter key
@param {string} key - the unlocalized parameter name to search through
@param {string} name - the localized parameter name to check
@param {string|nil} - an optional suffix to apply to the value(s) from the localization key
@returns {boolean} true if the name matches the parameter, false otherwise
]]--
function util.matchesParam(key, name, suffix)
local param = L10n.para[key]
suffix = suffix or ''
if type(param) == 'table' then
for _, v in pairs(param) do
if (v .. suffix) == name then return true end
end
return false
end
return ((param .. suffix) == name)
end
--[[
Check if a value is affirmed (one of the values in L10n.str.affirmedWords)
@param {string} val Value to be checked
@returns {boolean} true if affirmed, false otherwise
]]--
function util.isAffirmed(val)
if not(val) then return false end
return string.find(L10n.str.affirmedWords, ' '..val..' ', 1, true ) and true or false
end
--[[
Check if a value is declined (one of the values in L10n.str.declinedWords)
@param {string} val Value to be checked
@returns {boolean} true if declined, false otherwise
]]--
function util.isDeclined(val)
if not(val) then return false end
return string.find(L10n.str.declinedWords , ' '..val..' ', 1, true ) and true or false
end
--[[
Check if the name of a template matches the known coord templates or wrappers
(in L10n.template.templates and L10n.template.modules). The name is normalised
when checked, so e.g. the names "Coord", "coord", and " Coord" all return true.
@param {string} name
@returns {boolean} true if it is a coord template or wrapper, false otherwise
]]--
function util.isCoordTemplateOrWrapper(name)
name = mw.text.trim(name)
local modName = mw.ustring.gsub(name, '#invoke:', '')
local inputTitle = mw.title.new(modName, (name ~= modName) and 'Module' or 'Template')
if not inputTitle then
return false
end
-- Create (or reuse) mw.title objects for each known coord template/wrapper.
-- Stored in L10n.template.title so that they don't need to be recreated
-- each time this function is called
if not L10n.template.titles then
L10n.template.titles = {}
for _, v in pairs(L10n.template.templates) do
table.insert(L10n.template.titles, mw.title.new(v, 'Template'))
end
for _, v in pairs(L10n.template.modules) do
table.insert(L10n.template.titles, mw.title.new(v, 'Module'))
end
end
for _, templateTitle in pairs(L10n.template.titles) do
if mw.title.equals(inputTitle, templateTitle) then
return true
end
end
return false
end
--[[
Recursively extract coord templates which have a name parameter.
@param {string} wikitext
@returns {table} table sequence of coord templates
]]--
function util.extractCoordTemplates(wikitext)
local output = {}
local templates = mw.ustring.gmatch(wikitext, '{%b{}}')
for template in templates do
local templateName = mw.ustring.match(template, '{{([^}|]+)')
local nameParam = mw.ustring.match(template, "|%s*name%s*=%s*[^}|]+")
if util.isCoordTemplateOrWrapper(templateName) then
if nameParam then table.insert(output, template) end
elseif mw.ustring.find(mw.ustring.sub(template, 2), "{{") then
local subOutput = util.extractCoordTemplates(mw.ustring.sub(template, 2))
for _, t in pairs(subOutput) do
table.insert(output, t)
end
end
end
-- ensure coords are not using title display
for k, v in pairs(output) do
output[k] = mw.ustring.gsub(v, "|%s*display%s*=[^|}]+", "|display=inline")
end
return output
end
--[[
Gets all named coordinates from a page or a section of a page.
@param {string|nil} page Page name, or name#section, to get named coordinates
from. If the name is omitted, i.e. #section or nil or empty string, then
the current page will be used.
@returns {table} sequence of {coord, name, description} tables where coord is
the coordinates in a format suitable for #util.parseCoords, name is a string,
and description is a string (coordinates in a format suitable for displaying
to the reader). If for some reason the name can't be found, the description
is nil and the name contains display-format coordinates.
@throws {L10n.error.noNamedCoords} if no named coordinates are found.
]]--
function util.getNamedCoords(page)
local parts = mw.text.split(page or "", "#", true)
local name = parts[1] == "" and mw.title.getCurrentTitle().prefixedText or parts[1]
local section = parts[2]
local title = mw.title.new(name)
if title.isRedirect then
title = title.redirectTarget
end
local pageWikitext = title:getContent()
if section then
if parser == nil then
-- load [[Module:WikitextParser]] lazily so it is only transcluded on pages that use it
parser = require("Module:WikitextParser")
end
pageWikitext = parser.getSection(pageWikitext, section) or ''
end
local coordTemplates = util.extractCoordTemplates(pageWikitext)
if #coordTemplates == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end
local frame = mw.getCurrentFrame()
local sep = "________"
local expandedContent = frame:preprocess(table.concat(coordTemplates, sep))
local expandedTemplates = mw.text.split(expandedContent, sep)
local namedCoords = {}
for _, expandedTemplate in pairs(expandedTemplates) do
local coord = mw.ustring.match(expandedTemplate, "<span class=\"geo%-dec\".->(.-)</span>")
if coord then
local coordname = (
-- name specified by a wrapper template, e.g [[Article|Name]]
mw.ustring.match(expandedTemplate, "<span class=\"mapframe%-coord%-name\">(.-)</span>") or
-- name passed into coord template
mw.ustring.match(expandedTemplate, "<span class=\"fn org\">(.-)</span>") or
-- default to the coordinates if the name can't be retrieved
coord
)
local description = coordname ~= coord and coord
table.insert(namedCoords, {
coord=mw.ustring.gsub(coord, "[° ]", "_"),
name=coordname, description=description
})
end
end
if #namedCoords == 0 then error(string.format(L10n.error.noNamedCoords, page or name), 0) end
return namedCoords
end
--[[
Parse coordinate values from the params passed in a GeoHack url (such as
//tools.wmflabs.org/geohack/geohack.php?pagename=Example¶ms=1_2_N_3_4_W_ or
//tools.wmflabs.org/geohack/geohack.php?pagename=Example¶ms=1.23_S_4.56_E_ )
or non-url string in the same format (such as `1_2_N_3_4_W_` or `1.23_S_4.56_E_`)
@param {string} coords string containing coordinates
@returns {number, number} latitude, longitude
]]--
function util.parseCoords(coords)
local coordsPatt
if mw.ustring.find(coords, "params=", 1, true) then
-- prevent false matches from page name, e.g. ?pagename=Lorem_S._Ipsum
coordsPatt = 'params=([_%.%d]+[NS][_%.%d]+[EW])'
else
-- not actually a geohack url, just the same format
coordsPatt = '[_%.%d]+[NS][_%.%d]+[EW]'
end
local parts = mw.text.split((mw.ustring.match(coords, coordsPatt) or ''), '_')
local lat_d = tonumber(parts[1])
assert(lat_d, "Unable to get latitude from input '"..coords.."'.")
local lat_m = tonumber(parts[2]) -- nil if coords are in decimal format
local lat_s = lat_m and tonumber(parts[3]) -- nil if coords are either in decimal format or degrees and minutes only
local lat = lat_d + (lat_m or 0)/60 + (lat_s or 0)/3600
if parts[#parts/2] == 'S' then
lat = lat * -1
end
local long_d = tonumber(parts[1+#parts/2])
assert(long_d, "Unable to get longitude from input '"..coords.."'.")
local long_m = tonumber(parts[2+#parts/2]) -- nil if coords are in decimal format
local long_s = long_m and tonumber(parts[3+#parts/2]) -- nil if coords are either in decimal format or degrees and minutes only
local long = long_d + (long_m or 0)/60 + (long_s or 0)/3600
if parts[#parts] == 'W' then
long = long * -1
end
return lat, long
end
--[[
Get coordinates from a Wikidata item
@param {string} item_id Wikidata item id (Q number)
@returns {number, number} latitude, longitude
@throws {L10n.error.noCoords} if item_id is invalid or the item does not exist
@throws {L10n.error.wikidataCoords} if the the item does not have a P625
statement (coordinates), or it is set to "no value"
]]--
function util.wikidataCoords(item_id)
if not (item_id and wb.isValidEntityId(item_id) and wb.entityExists(item_id)) then
error(L10n.error.noCoords, 0)
end
local coordStatements = wb.getBestStatements(item_id, 'P625')
if not coordStatements or #coordStatements == 0 then
error(L10n.error.wikidataCoords, 0)
end
local hasNoValue = ( coordStatements[1].mainsnak and (coordStatements[1].mainsnak.snaktype == 'novalue' or coordStatements[1].mainsnak.snaktype == 'somevalue') )
if hasNoValue then
error(L10n.error.wikidataCoords, 0)
end
local wdCoords = coordStatements[1]['mainsnak']['datavalue']['value']
return tonumber(wdCoords['latitude']), tonumber(wdCoords['longitude'])
end
--[[
Creates a polygon that approximates a circle
@param {number} lat Latitude
@param {number} long Longitude
@param {number} radius Radius in metres
@param {number} n Number of edges for the polygon
@returns {table} sequence of {latitude, longitude} table sequences, where
latitude and longitude are both numbers
]]--
function util.circleToPolygon(lat, long, radius, n) -- n is number of edges
-- Based on https://github.com/gabzim/circle-to-polygon, ISC licence
local function offset(cLat, cLon, distance, bearing)
local lat1 = math.rad(cLat)
local lon1 = math.rad(cLon)
local dByR = distance / 6378137 -- distance divided by 6378137 (radius of the earth) wgs84
local offet_lat = math.asin(
math.sin(lat1) * math.cos(dByR) +
math.cos(lat1) * math.sin(dByR) * math.cos(bearing)
)
local offet_lon = lon1 + math.atan2(
math.sin(bearing) * math.sin(dByR) * math.cos(lat1),
math.cos(dByR) - math.sin(lat1) * math.sin(offet_lat)
)
return {math.deg(offet_lon), math.deg(offet_lat)}
end
local coordinates = {};
local i = 0;
while i < n do
table.insert(coordinates,
offset(lat, long, radius, (2*math.pi*i*-1)/n)
)
i = i + 1
end
table.insert(coordinates, offset(lat, long, radius, 0))
return coordinates
end
--[[
Get the number of key-value pairs in a table, which might not be a sequence.
@param {table} t
@returns {number} count of key-value pairs
]]--
function util.tableCount(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
--[[
For a table where the values are all tables, returns either the util.tableCount
of the subtables if they are all the same, or nil if they are not all the same.
@param {table} t
@returns {number|nil} count of key-value pairs of subtable, or nil if subtables
have different counts
]]--
function util.subTablesCount(t)
local count = nil
for k, v in pairs(t) do
if count == nil then
count = util.tableCount(v)
elseif count ~= util.tableCount(v) then
return nil
end
end
return count
end
--[[
Splits a list into a table sequence. The items in the list may be separated by
commas, or by semicolons (if items may contain commas), or by "###" (if items
may contain semicolons).
@param {string} listString
@returns {table} sequence of list items
]]--
function util.tableFromList(listString)
if type(listString) ~= "string" or listString == "" then return nil end
local separator = (mw.ustring.find(listString, "###", 0, true ) and "###") or
(mw.ustring.find(listString, ";", 0, true ) and ";") or ","
local pattern = "%s*"..separator.."%s*"
return mw.text.split(listString, pattern)
end
-- Boolean in outer scope indicating if Kartographer should be able to
-- automatically calculate coordinates (see phab:T227402)
local coordsDerivedFromFeatures = false;
--[[----------------------------------------------------------------------------
Make methods: These take in a table of arguments, and return either a string
or a table to be used in the eventual output.
----------------------------------------------------------------------------]]--
local make = {}
--[[
Makes content to go inside the maplink or mapframe tag.
@param {table} args
@returns {string} tag content
]]--
function make.content(args)
if util.getParameterValue(args, 'raw') then
coordsDerivedFromFeatures = true -- Kartographer should be able to automatically calculate coords from raw geoJSON
return util.getParameterValue(args, 'raw')
end
local content = {}
local argsExpanded = {}
for k, v in pairs(args) do
local index = string.match( k, '^[^0-9]+([0-9]*)$' )
if index ~= nil then
local indexNumber
if index ~= '' then
indexNumber = tonumber(index)
else
indexNumber = 1
end
if argsExpanded[indexNumber] == nil then
argsExpanded[indexNumber] = {}
end
argsExpanded[indexNumber][ string.gsub(k, index, '') ] = v
end
end
for contentIndex, contentArgs in pairs(argsExpanded) do
local argType = util.getParameterValue(contentArgs, "type")
-- Kartographer automatically calculates coords if geolines/shapes are used (T227402)
if not coordsDerivedFromFeatures then
coordsDerivedFromFeatures = ( argType == L10n.str.line or argType == L10n.str.shape ) and true or false
end
if argType == L10n.str.named then
local namedCoords = util.getNamedCoords(util.getParameterValue(contentArgs, "from"))
local typeKey = type(L10n.para.type) == "table" and L10n.para.type[1] or L10n.para.type
local coordKey = type(L10n.para.coord) == "table" and L10n.para.coord[1] or L10n.para.coord
local titleKey = type(L10n.para.title) == "table" and L10n.para.title[1] or L10n.para.title
local descKey = type(L10n.para.description) == "table" and L10n.para.description[1] or L10n.para.description
for _, namedCoord in pairs(namedCoords) do
contentArgs[typeKey] = "point"
contentArgs[coordKey] = namedCoord.coord
contentArgs[titleKey] = namedCoord.name
contentArgs[descKey] = namedCoord.description
content[#content+1] = make.contentJson(contentArgs)
end
else
content[#content + 1] = make.contentJson(contentArgs)
end
end
--Single item, no array needed
if #content==1 then return content[1] end
--Multiple items get placed in a FeatureCollection
local contentArray = '[\n' .. table.concat( content, ',\n') .. '\n]'
return contentArray
end
--[[
Make coordinates from the coord arg, or the id arg, or the current page's
Wikidata item.
@param {table} args
@param {boolean} [plainOutput]
@returns {Mixed} Either:
{number, number} latitude, longitude if plainOutput is true; or
{table} table sequence of longitude, then latitude (gives the required format
for GeoJSON when encoded)
]]--
function make.coords(args, plainOutput)
local coords, lat, long
local frame = mw.getCurrentFrame()
if util.getParameterValue(args, 'coord') then
coords = frame:preprocess( util.getParameterValue(args, 'coord') )
lat, long = util.parseCoords(coords)
else
lat, long = util.wikidataCoords(util.getParameterValue(args, 'id') or wb.getEntityIdForCurrentPage())
end
if plainOutput then
return lat, long
end
return {[0] = long, [1] = lat}
end
--[[
Makes a table of coordinates that approximate a circle.
@param {table} args
@returns {table} sequence of {latitude, longitude} table sequences, where
latitude and longitude are both numbers
@throws {L10n.error.noCircleCoords} if centre coordinates are not specified
@throws {L10n.error.noRadius} if radius is not specified
@throws {L10n.error.negativeRadius} if radius is negative or zero
@throws {L10n.error.negativeEdges} if edges is negative or zero
]]--
function make.circleCoords(args)
local lat, long = make.coords(args, true)
local radius = util.getParameterValue(args, 'radius')
if not radius then
radius = util.getParameterValue(args, 'radiusKm') and tonumber(util.getParameterValue(args, 'radiusKm'))*1000
if not radius then
radius = util.getParameterValue(args, 'radiusMi') and tonumber(util.getParameterValue(args, 'radiusMi'))*1609.344
if not radius then
radius = util.getParameterValue(args, 'radiusFt') and tonumber(util.getParameterValue(args, 'radiusFt'))*0.3048
end
end
end
local edges = util.getParameterValue(args, 'edges') or L10n.defaults.edges
if not lat or not long then
error(L10n.error.noCircleCoords, 0)
elseif not radius then
error(L10n.error.noRadius, 0)
elseif tonumber(radius) <= 0 then
error(L10n.error.negativeRadius, 0)
elseif tonumber(edges) <= 0 then
error(L10n.error.negativeEdges, 0)
end
return util.circleToPolygon(lat, long, radius, tonumber(edges))
end
--[[
Makes JSON data for a feature
@param contentArgs args for this feature. Keys must be the non-suffixed version
of the parameter names, i.e. use type, stroke, fill,... rather than type3,
stroke3, fill3,...
@returns {string} JSON encoded data
]]--
function make.contentJson(contentArgs)
local data = {}
if util.getParameterValue(contentArgs, 'type') == L10n.str.point or util.getParameterValue(contentArgs, 'type') == L10n.str.circle then
local isCircle = util.getParameterValue(contentArgs, 'type') == L10n.str.circle
data.type = "Feature"
data.geometry = {
type = isCircle and "LineString" or "Point",
coordinates = isCircle and make.circleCoords(contentArgs) or make.coords(contentArgs)
}
data.properties = {
title = util.getParameterValue(contentArgs, 'title') or mw.getCurrentFrame():getParent():getTitle()
}
if isCircle then
-- TODO: This is very similar to below, should be extracted into a function
data.properties.stroke = util.getParameterValue(contentArgs, 'strokeColor') or L10n.defaults.strokeColor
data.properties["stroke-width"] = tonumber(util.getParameterValue(contentArgs, 'strokeWidth')) or L10n.defaults.strokeWidth
local strokeOpacity = util.getParameterValue(contentArgs, 'strokeOpacity')
if strokeOpacity then
data.properties['stroke-opacity'] = tonumber(strokeOpacity)
end
local fill = util.getParameterValue(contentArgs, 'fill')
if fill then
data.properties.fill = fill
local fillOpacity = util.getParameterValue(contentArgs, 'fillOpacity')
data.properties['fill-opacity'] = fillOpacity and tonumber(fillOpacity) or 0.6
end
else -- is a point
local markerSymbol = util.getParameterValue(contentArgs, 'marker') or L10n.defaults.marker
-- allow blank to be explicitly specified, for overriding infoboxes or other templates with a default value
if markerSymbol ~= "blank" then
data.properties["marker-symbol"] = markerSymbol
end
data.properties["marker-color"] = util.getParameterValue(contentArgs, 'markerColor') or L10n.defaults.markerColor
data.properties["marker-size"] = util.getParameterValue(contentArgs, 'markerSize') or L10n.defaults.markerSize
end
else
data.type = "ExternalData"
if util.getParameterValue(contentArgs, 'type') == L10n.str.data or util.getParameterValue(contentArgs, 'from') then
data.service = "page"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.line then
data.service = "geoline"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.shape then
data.service = "geoshape"
elseif util.getParameterValue(contentArgs, 'type') == L10n.str.shapeInverse then
data.service = "geomask"
end
if util.getParameterValue(contentArgs, 'id') or (not (util.getParameterValue(contentArgs, 'from')) and wb.getEntityIdForCurrentPage()) then
data.ids = util.getParameterValue(contentArgs, 'id') or wb.getEntityIdForCurrentPage()
else
data.title = util.getParameterValue(contentArgs, 'from')
end
data.properties = {
stroke = util.getParameterValue(contentArgs, 'strokeColor') or L10n.defaults.strokeColor,
["stroke-width"] = tonumber(util.getParameterValue(contentArgs, 'strokeWidth')) or L10n.defaults.strokeWidth
}
local strokeOpacity = util.getParameterValue(contentArgs, 'strokeOpacity')
if strokeOpacity then
data.properties['stroke-opacity'] = tonumber(strokeOpacity)
end
local fill = util.getParameterValue(contentArgs, 'fill')
if fill and (data.service == "geoshape" or data.service == "geomask") then
data.properties.fill = fill
local fillOpacity = util.getParameterValue(contentArgs, 'fillOpacity')
if fillOpacity then
data.properties['fill-opacity'] = tonumber(fillOpacity)
end
end
end
data.properties.title = util.getParameterValue(contentArgs, 'title') or mw.title.getCurrentTitle().text
if util.getParameterValue(contentArgs, 'description') then
data.properties.description = util.getParameterValue(contentArgs, 'description')
end
return mw.text.jsonEncode(data)
end
--[[
Makes attributes for the maplink or mapframe tag.
@param {table} args
@param {boolean} [isTitle] Tag is to be displayed in the title of page rather
than inline
@returns {table<string,string>} key-value pairs of attribute names and values
]]--
function make.tagAttribs(args, isTitle)
local attribs = {}
if util.getParameterValue(args, 'zoom') then
attribs.zoom = util.getParameterValue(args, 'zoom')
end
if util.isDeclined(util.getParameterValue(args, 'icon')) then
attribs.class = "no-icon"
end
if util.getParameterValue(args, 'type') == L10n.str.point and not coordsDerivedFromFeatures then
local lat, long = make.coords(args, 'plainOutput')
attribs.latitude = tostring(lat)
attribs.longitude = tostring(long)
end
if util.isAffirmed(util.getParameterValue(args, 'frame')) and not(isTitle) then
attribs.width = util.getParameterValue(args, 'frameWidth') or L10n.defaults.frameWidth
attribs.height = util.getParameterValue(args, 'frameHeight') or L10n.defaults.frameHeight
if util.getParameterValue(args, 'frameCoordinates') then
local frameLat, frameLong = util.parseCoords(util.getParameterValue(args, 'frameCoordinates'))
attribs.latitude = frameLat
attribs.longitude = frameLong
else
if util.getParameterValue(args, 'frameLatitude') then
attribs.latitude = util.getParameterValue(args, 'frameLatitude')
end
if util.getParameterValue(args, 'frameLongitude') then
attribs.longitude = util.getParameterValue(args, 'frameLongitude')
end
end
if not attribs.latitude and not attribs.longitude and not coordsDerivedFromFeatures then
local success, lat, long = pcall(util.wikidataCoords, util.getParameterValue(args, 'id') or wb.getEntityIdForCurrentPage())
if success then
attribs.latitude = tostring(lat)
attribs.longitude = tostring(long)
end
end
if util.getParameterValue(args, 'frameAlign') then
attribs.align = util.getParameterValue(args, 'frameAlign')
end
if util.isAffirmed(util.getParameterValue(args, 'plain')) then
attribs.frameless = "1"
else
attribs.text = util.getParameterValue(args, 'text') or L10n.defaults.text
end
else
attribs.text = util.getParameterValue(args, 'text') or L10n.defaults.text
end
return attribs
end
--[[
Makes maplink wikitext that will be located in the top-right of the title of the
page (the same place where coords with |display=title are positioned).
@param {table} args
@param {string} tagContent Content for the maplink tag
@returns {string}
]]--
function make.titleOutput(args, tagContent)
local titleTag = mw.text.tag('maplink', make.tagAttribs(args, true), tagContent)
local spanAttribs = {
style = "font-size: small;",
id = "mapframe-coordinates"
}
local indicatorContent = mw.text.tag('span', spanAttribs, titleTag)
return mw.getCurrentFrame():extensionTag {
name = "indicator",
content = indicatorContent,
args = {
name = "zzz-mapframe" --zzz: show as last indicator
}
}
end
--[[
Makes maplink or mapframe wikitext that will be located inline.
@param {table} args
@param {string} tagContent Content for the maplink tag
@returns {string}
]]--
function make.inlineOutput(args, tagContent)
local tagName = 'maplink'
if util.getParameterValue(args, 'frame') then
tagName = 'mapframe'
end
return mw.text.tag(tagName, make.tagAttribs(args), tagContent)
end
--[[
Makes the HTML required for the swicther to work, including the templatestyles
tag.
@param {table} params table sequence of {map, label} tables
@param {string} params{}.map Wikitext for mapframe map
@param {string} params{}.label Label text for swicther option
@param {table} options
@param {string} options.alignment "left" or "center" or "right"
@param {boolean} options.isThumbnail Display in a thumbnail
@param {string} options.width Width of frame, e.g. "200"
@param {string} [options.caption] Caption wikitext for thumnail
@retruns {string} swicther HTML
]]--
function make.switcherHtml(params, options)
options = options or {}
local frame = mw.getCurrentFrame()
local styles = frame:extensionTag{
name = "templatestyles",
args = {src = "Template:Maplink/styles-multi.css"}
}
local container = mw.html.create("div")
:addClass("switcher-container")
:addClass("mapframe-multi-container")
if options.alignment == "left" or options.alignment == "right" then
container:addClass("float"..options.alignment)
else -- alignment is "center"
container:addClass("center")
end
for i = 1, #params do
container
:tag("div")
:wikitext(params[i].map)
:tag("span")
:addClass("switcher-label")
:css("display", "none")
:wikitext(mw.text.trim(params[i].label))
end
if not options.isThumbnail then
return styles .. tostring(container)
end
local classlist = container:getAttr("class")
classlist = mw.ustring.gsub(classlist, "%a*"..options.alignment, "")
container:attr("class", classlist)
local outerCountainer = mw.html.create("div")
:addClass("mapframe-multi-outer-container")
:addClass("mw-kartographer-container")
:addClass("thumb")
if options.alignment == "left" or options.alignment == "right" then
outerCountainer:addClass("float"..options.alignment)
else -- alignment is "center"
outerCountainer
:addClass("tnone")
:addClass("center")
end
outerCountainer
:tag("div")
:addClass("thumbinner")
:css("width", options.width.."px")
:node(container)
:node(options.caption and mw.html.create("div")
:addClass("thumbcaption")
:wikitext(options.caption)
)
return styles .. tostring(outerCountainer)
end
--[[
Makes the HTML required for an overlay map to work
tag.
@param {string} overlayMap wikitext for the overlay map
@param {string} baseMap wikitext for the base map
@param {table} options various styling/display options
@param {string} options.align "left" or "center" or "right"
@param {string|number} options.width Width of the base map, e.g. "300"
@param {string|number} options.width Height of the base map, e.g. "200"
@param {string} options.border Border style for the overlayed map, e.g. "1px solid white"
@param {string} options.horizontalAlignment Horizontal alignment for overlay map, "left" or "right"
@param {string|number} options.horizontalOffset Horizontal offset in pixels from the alignment edge, e.g "10"
@param {string} options.verticalAlignment Vertical alignment for overlay map, "top" or "bottom"
@param {string|number} options.verticalOffset Vertical offset in pixels from the alignment edge, e.g. is "10"
@param {boolean} options.isThumbnail Display in a thumbnail
@param {string} [options.caption] Caption wikitext for thumnail
@retruns {string} HTML for basemap with overlay
]]--
function make.overlayHtml(overlayMap, baseMap, options)
options = options or {}
local containerFloatClass = "float"..(options.align or "none")
if options.align == "center" then
containerFloatClass = "center"
end
local containerStyle = {
position = "relative",
width = options.width .. "px",
height = options.height .. "px",
overflow = "hidden" -- mobile/minerva tends to add scrollbars for a couple of pixels
}
if options.align == "center" then
containerStyle["margin-left"] = "auto"
containerStyle["margin-right"] = "auto"
end
local container = mw.html.create("div")
:addClass("mapframe-withOverlay-container")
:addClass(containerFloatClass)
:addClass("noresize")
:css(containerStyle)
local overlayStyle = {
position = "absolute",
["z-index"] = "1",
border = options.border or "1px solid white"
}
if options.horizontalAlignment == "right" then
overlayStyle.right = options.horizontalOffset .. "px"
else
overlayStyle.left = options.horizontalOffset .. "px"
end
if options.verticalAlignment == "bottom" then
overlayStyle.bottom = options.verticalOffset .. "px"
else
overlayStyle.top = options.verticalOffset .. "px"
end
local overlayDiv = mw.html.create("div")
:css(overlayStyle)
:wikitext(overlayMap)
container
:node(overlayDiv)
:wikitext(baseMap)
if not options.isThumbnail then
return tostring(container)
end
local classlist = container:getAttr("class")
classlist = mw.ustring.gsub(classlist, "%a*"..options.align, "")
container:attr("class", classlist)
local outerCountainer = mw.html.create("div")
:addClass("mapframe-withOverlay-outerContainer")
:addClass("mw-kartographer-container")
:addClass("thumb")
if options.align == "left" or options.align == "right" then
outerCountainer:addClass("t"..options.align)
else -- alignment is "center"
outerCountainer
:addClass("tnone")
:addClass("center")
end
outerCountainer
:tag("div")
:addClass("thumbinner")
:css("width", options.width.."px")
:node(container)
:node(options.caption and mw.html.create("div")
:addClass("thumbcaption")
:wikitext(options.caption)
)
return tostring(outerCountainer)
end
--[[----------------------------------------------------------------------------
Package to be exported, i.e. methods which will available to templates and
other modules.
----------------------------------------------------------------------------]]--
local p = {}
-- Entry point for templates
function p.main(frame)
local parent = frame.getParent(frame)
-- Check for overlay option
local overlay = util.getParameterValue(parent.args, 'overlay')
local hasOverlay = overlay and mw.text.trim(overlay) ~= ""
-- Check for switch option
local switch = util.getParameterValue(parent.args, 'switch')
local isMulti = switch and mw.text.trim(switch) ~= ""
-- Create output by choosing method to suit options
local output
if hasOverlay then
output = p.withOverlay(parent.args)
elseif isMulti then
output = p.multi(parent.args)
else
output = p._main(parent.args)
end
-- Preprocess output before returning it
return frame:preprocess(output)
end
-- Entry points for modules
function p._main(_args)
local args = util.trimArgs(_args)
local tagContent = make.content(args)
local display = mw.text.split(util.getParameterValue(args, 'display') or L10n.defaults.display, '%s*' .. L10n.str.dsep .. '%s*')
local displayInTitle = display[1] == L10n.str.title or display[2] == L10n.str.title
local displayInline = display[1] == L10n.str.inline or display[2] == L10n.str.inline
local output
if displayInTitle and displayInline then
output = make.titleOutput(args, tagContent) .. make.inlineOutput(args, tagContent)
elseif displayInTitle then
output = make.titleOutput(args, tagContent)
elseif displayInline then
output = make.inlineOutput(args, tagContent)
else
error(L10n.error.badDisplayPara)
end
return output
end
function p.multi(_args)
local args = util.trimArgs(_args)
if not args[L10n.para.switch] then error(L10n.error.noSwitchPara, 0) end
local switchParamValue = util.getParameterValue(args, 'switch')
local switchLabels = util.tableFromList(switchParamValue)
if #switchLabels == 1 then error(L10n.error.oneSwitchLabel, 0) end
local mapframeArgs = {}
local switchParams = {}
for name, val in pairs(args) do
-- Copy to mapframeArgs, if not the switch labels or a switch parameter
if val ~= switchParamValue and not string.match(val, "^"..L10n.str.switch..":") then
mapframeArgs[name] = val
end
-- Check if this is a param to switch. If so, store the name and switch
-- values in switchParams table.
local switchList = string.match(val, "^"..L10n.str.switch..":(.+)")
if switchList ~= nil then
local values = util.tableFromList(switchList)
if #values == 1 then
error(string.format(L10n.error.oneSwitchValue, name), 0)
end
switchParams[name] = values
end
end
if util.tableCount(switchParams) == 0 then
error(L10n.error.noSwitchLists, 0)
end
local switchCount = util.subTablesCount(switchParams)
if not switchCount then
error(L10n.error.switchMismatches, 0)
elseif switchCount > #switchLabels then
error(string.format(L10n.error.fewerSwitchLabels, switchCount, #switchLabels), 0)
end
-- Ensure a plain frame will be used (thumbnail will be built by the
-- make.switcherHtml function if required, so that switcher options are
-- inside the thumnail)
mapframeArgs.plain = "yes"
local switcher = {}
for i = 1, switchCount do
local label = switchLabels[i]
for name, values in pairs(switchParams) do
mapframeArgs[name] = values[i]
end
table.insert(switcher, {
map = p._main(mapframeArgs),
label = "Show "..label
})
end
return make.switcherHtml(switcher, {
alignment = args["frame-align"] or "right",
isThumbnail = (args.frame and not args.plain) and true or false,
width = args["frame-width"] or L10n.defaults.frameWidth,
caption = args.text
})
end
function p.withOverlay(_args)
-- Get and trim wikitext for overlay map
local overlayMap = _args.overlay
if type(overlayMap) == 'string' then
overlayMap = overlayMap:match('^%s*(.-)%s*$')
end
local isThumbnail = (util.getParameterValue(_args, "frame") and not util.getParameterValue(_args, "plain")) and true or false
-- Get base map using the _main function, as a plain map
local args = util.trimArgs(_args)
args.plain = "yes"
local basemap = p._main(args)
-- Extract overlay options from args
local overlayOptions = {
width = util.getParameterValue(args, "frameWidth") or L10n.defaults.frameWidth,
height = util.getParameterValue(args, "frameHeight") or L10n.defaults.frameHeight,
align = util.getParameterValue(args, "frameAlign") or L10n.defaults.frameAlign,
border = util.getParameterValue(args, "overlayBorder") or L10n.defaults.overlayBorder,
horizontalAlignment = util.getParameterValue(args, "overlayHorizontalAlignment") or L10n.defaults.overlayHorizontalAlignment,
horizontalOffset = util.getParameterValue(args, "overlayHorizontalOffset") or L10n.defaults.overlayHorizontalOffset,
verticalAlignment = util.getParameterValue(args, "overlayVerticalAlignment") or L10n.defaults.overlayVerticalAlignment,
verticalOffset = util.getParameterValue(args, "overlayVerticalOffset") or L10n.defaults.overlayVerticalOffset,
isThumbnail = isThumbnail,
caption = util.getParameterValue(args, "text") or L10n.defaults.text
}
-- Make the HTML for the overlaying maps
return make.overlayHtml(overlayMap, basemap, overlayOptions)
end
-- Entry point for testcase tests
p.test = util
return p
cbg20zhedgvi7tds8motk323r37gona
Module:Location map
828
21001
124187
119027
2026-10-06T20:43:54Z
en>Paine Ellsworth
0
Undid revision [[Special:Diff/1378831002|1378831002]] by [[Special:Contributions/Paine Ellsworth|Paine Ellsworth]] ([[User talk:Paine Ellsworth|talk]])
119026
Scribunto
text/plain
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local function round(n, decimals)
local pow = 10^(decimals or 0)
return math.floor(n * pow + 0.5) / pow
end
function p.getMapParams(map, frame)
if not map then
error('The name of the location map definition to use must be specified', 2)
end
local moduletitle = mw.title.new('Module:Location map/data/' .. map)
if not moduletitle then
error(string.format('%q is not a valid name for a location map definition', map), 2)
elseif moduletitle.exists then
local mapData = mw.loadData('Module:Location map/data/' .. map)
return function(name, params)
if name == nil then
return 'Module:Location map/data/' .. map
elseif mapData[name] == nil then
return ''
elseif params then
return mw.message.newRawMessage(tostring(mapData[name]), unpack(params)):plain()
else
return mapData[name]
end
end
else
error('Unable to find the specified location map definition: "Module:Location map/data/' .. map .. '" does not exist', 2)
end
end
function p.data(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local params = {}
for k,v in ipairs(args) do
if k > 2 then
params[k-2] = v
end
end
return map(args[2], #params ~= 0 and params)
end
local hemisphereMultipliers = {
longitude = { W = -1, w = -1, E = 1, e = 1 },
latitude = { S = -1, s = -1, N = 1, n = 1 }
}
local function decdeg(degrees, minutes, seconds, hemisphere, decimal, direction)
if decimal then
if degrees then
error('Decimal and DMS degrees cannot both be provided for ' .. direction, 2)
elseif minutes then
error('Minutes can only be provided with DMS degrees for ' .. direction, 2)
elseif seconds then
error('Seconds can only be provided with DMS degrees for ' .. direction, 2)
elseif hemisphere then
error('A hemisphere can only be provided with DMS degrees for ' .. direction, 2)
end
local retval = tonumber(decimal)
if retval then
return retval
end
error('The value "' .. decimal .. '" provided for ' .. direction .. ' is not valid', 2)
elseif seconds and not minutes then
error('Seconds were provided for ' .. direction .. ' without minutes also being provided', 2)
elseif not degrees then
if minutes then
error('Minutes were provided for ' .. direction .. ' without degrees also being provided', 2)
elseif hemisphere then
error('A hemisphere was provided for ' .. direction .. ' without degrees also being provided', 2)
end
return nil
end
decimal = tonumber(degrees)
if not decimal then
error('The degree value "' .. degrees .. '" provided for ' .. direction .. ' is not valid', 2)
elseif minutes and not tonumber(minutes) then
error('The minute value "' .. minutes .. '" provided for ' .. direction .. ' is not valid', 2)
elseif seconds and not tonumber(seconds) then
error('The second value "' .. seconds .. '" provided for ' .. direction .. ' is not valid', 2)
end
decimal = decimal + (minutes or 0)/60 + (seconds or 0)/3600
if hemisphere then
local multiplier = hemisphereMultipliers[direction][hemisphere]
if not multiplier then
error('The hemisphere "' .. hemisphere .. '" provided for ' .. direction .. ' is not valid', 2)
end
decimal = decimal * multiplier
end
return decimal
end
-- Finds a parameter in a transclusion of {{Coord}}.
local function coord2text(para,coord) -- this should be changed for languages which do not use Arabic numerals or the degree sign
local lat, long = mw.ustring.match(coord,'<span class="p%-latitude latitude">([^<]+)</span><span class="p%-longitude longitude">([^<]+)</span>')
if lat then
return tonumber(para == 'longitude' and long or lat)
end
local result = mw.text.split(mw.ustring.match(coord,'%-?[%.%d]+°[NS] %-?[%.%d]+°[EW]') or '', '[ °]')
if para == 'longitude' then result = {result[3], result[4]} end
if not tonumber(result[1]) or not result[2] then
mw.log('Malformed coordinates value')
mw.logObject(para, 'para')
mw.logObject(coord, 'coord')
return error('Malformed coordinates value', 2)
end
return tonumber(result[1]) * hemisphereMultipliers[para][result[2]]
end
-- effectively make removeBlanks false for caption and maplink, and true for everything else
-- if useWikidata is present but blank, convert it to false instead of nil
-- p.top, p.bottom, and their callers need to use this
function p.valueFunc(key, value)
if value then
value = mw.text.trim(value)
end
if value ~= '' or key == 'caption' or key == 'maplink' then
return value
elseif key == 'useWikidata' then
return false
end
end
local function getContainerImage(args, map)
if args.AlternativeMap then
return args.AlternativeMap
elseif args.relief then
local digits = mw.ustring.match(args.relief,'^[1-9][0-9]?$') -- image1 to image99
if digits then
local imageDigits = map('image' .. digits)
if imageDigits ~= '' then return imageDigits end
end
local yesNo = require('Module:Yesno')
if yesNo(args.relief,true) then
local image1 = map('image1')
if image1 ~= '' then return image1 end
end
end
return map('image')
end
function p.top(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local width
local default_as_number = tonumber(mw.ustring.match(tostring(args.default_width),"%d*"))
if not args.width then
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
elseif mw.ustring.sub(args.width, -2) == 'px' then
width = mw.ustring.sub(args.width, 1, -3)
else
width = args.width
end
local width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
if width_as_number == 0 then
-- check to see if width is junk. If it is, then use default calculation
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
end
if args.max_width ~= "" and args.max_width ~= nil then
-- check to see if width bigger than max_width
local max_as_number = tonumber(mw.ustring.match(args.max_width,"%d*")) or 0;
if width_as_number>max_as_number and max_as_number>0 then
width = args.max_width;
end
end
local retval = frame:extensionTag{name = 'templatestyles', args = {src = 'Module:Location map/styles.css'}}
if args.float == 'center' then
retval = retval .. '<div class="center">'
end
if args.caption and args.caption ~= '' and args.border ~= 'infobox' then
retval = retval .. '<div class="locmap noresize thumb '
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'floatleft'
elseif args.float == '"center"' or args.float == 'center' or args.float == '"none"' or args.float == 'none' then
retval = retval .. 'tnone'
else
retval = retval .. 'floatright'
end
retval = retval .. '"><div class="thumbinner" style="width:' .. (width + 2) .. 'px'
if args.border == 'none' then
retval = retval .. ';border:none'
elseif args.border then
retval = retval .. ';border-color:' .. args.border
end
retval = retval .. '"><div style="position:relative;width:' .. width .. 'px' .. (args.border ~= 'none' and ';border:1px solid lightgray">' or '">')
else
retval = retval .. '<div class="locmap" style="width:' .. width .. 'px;'
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'float:left;clear:left'
elseif args.float == '"center"' or args.float == 'center' then
retval = retval .. 'float:none;clear:both;margin-left:auto;margin-right:auto'
elseif args.float == '"none"' or args.float == 'none' then
retval = retval .. 'float:none;clear:none'
else
retval = retval .. 'float:right;clear:right'
end
retval = retval .. '"><div style="width:' .. width .. 'px;padding:0"><div style="position:relative;width:' .. width .. 'px">'
end
local image = getContainerImage(args, map)
local currentTitle = mw.title.getCurrentTitle()
retval = string.format(
'%s[[File:%s|%spx|%s%s|class=notpageimage noviewer]]',
retval,
image,
width,
args.alt or ((args.label or currentTitle.text) .. ' is located in ' .. map('name')),
args.maplink and ('|link=' .. args.maplink) or ''
)
if args.caption and args.caption ~= '' then
if (currentTitle.namespace == 0) and mw.ustring.find(args.caption, '##') then
retval = retval .. '[[Category:Pages using location map with a double number sign in the caption]]'
end
end
if args.overlay_image then
return retval .. '<div style="position:absolute;top:0;left:0">[[File:' .. args.overlay_image .. '|' .. width .. 'px|class=notpageimage noviewer]]</div>'
else
return retval
end
end
function p.bottom(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local retval = '</div>'
local currentTitle = mw.title.getCurrentTitle()
if not args.caption or args.border == 'infobox' then
if args.border then
retval = retval .. '<div style="padding-top:0.2em">'
else
retval = retval .. '<div style="font-size:91%;padding-top:3px">'
end
retval = retval
.. (args.caption or (args.label or currentTitle.text) .. ' (' .. map('name') .. ')')
.. '</div>'
elseif args.caption ~= '' then
-- This is not the pipe trick. We're creating a link with no text on purpose, so that CSS can give us a nice image
retval = retval .. '<div class="thumbcaption"><div class="magnify">[[:File:' .. getContainerImage(args, map) .. '| ]]</div>' .. args.caption .. '</div>'
end
if args.switcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">' .. args.switcherLabel .. '</span>'
elseif args.autoSwitcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">Show map of ' .. map('name') .. '</span>'
end
retval = retval .. '</div></div>'
if args.caption_undefined then
mw.log('Removed parameter caption_undefined used.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
retval = retval .. '[[Category:Location maps with removed parameters|caption_undefined]]'
end
end
if map('skew') ~= '' or map('lat_skew') ~= '' or map('crosses180') ~= '' or map('type') ~= '' then
mw.log('Removed parameter used in map definition ' .. map())
if currentTitle.namespace == 0 then
local key = (map('skew') ~= '' and 'skew' or '') ..
(map('lat_skew') ~= '' and 'lat_skew' or '') ..
(map('crosses180') ~= '' and 'crosses180' or '') ..
(map('type') ~= '' and 'type' or '')
retval = retval .. '[[Category:Location maps with removed parameters|' .. key .. ' ]]'
end
end
if string.find(map('name'), '|', 1, true) then
mw.log('Pipe used in name of map definition ' .. map())
if currentTitle.namespace == 0 then
retval = retval .. '[[Category:Location maps with a name containing a pipe]]'
end
end
if args.float == 'center' then
retval = retval .. '</div>'
end
return retval
end
local function markOuterDiv(x, y, imageDiv, labelDiv, label_size)
return mw.html.create('div')
:addClass('od')
:addClass('notheme') -- T236137
:cssText('top:' .. round(y, 3) .. '%;left:' .. round(x, 3) .. '%;font-size:' .. label_size .. '%')
:node(imageDiv)
:node(labelDiv)
end
local function markImageDiv(mark, marksize, label, link, alt, title)
local builder = mw.html.create('div')
:addClass('id')
:cssText('left:-' .. round(marksize / 2) .. 'px;top:-' .. round(marksize / 2) .. 'px')
:attr('title', title)
if marksize ~= 0 then
builder:wikitext(string.format(
'[[File:%s|%dx%dpx|%s|link=%s%s|class=notpageimage noviewer]]',
mark,
marksize,
marksize,
label,
link,
alt and ('|alt=' .. alt) or ''
))
end
return builder
end
local function markLabelDiv(label, label_size, label_width, position, background, x, marksize)
if tonumber(label_size) == 0 then
return mw.html.create('div'):addClass('l0'):wikitext(label)
end
local builder = mw.html.create('div')
:cssText('width:' .. label_width .. 'em')
local distance = round(marksize / 2 + 1)
if position == 'top' then -- specified top
builder:addClass('pv'):cssText('bottom:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em')
elseif position == 'bottom' then -- specified bottom
builder:addClass('pv'):cssText('top:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em')
elseif position == 'left' or (tonumber(x) > 70 and position ~= 'right') then -- specified left or autodetected to left
builder:addClass('pl'):cssText('right:' .. distance .. 'px')
else -- specified right or autodetected to right
builder:addClass('pr'):cssText('left:' .. distance .. 'px')
end
builder = builder:tag('div')
:wikitext(label)
if background then
builder:cssText('background-color:' .. background)
end
return builder:done()
end
local function getX(longitude, left, right)
local width = (right - left) % 360
if width == 0 then
width = 360
end
local distanceFromLeft = (longitude - left) % 360
-- the distance needed past the map to the right equals distanceFromLeft - width. the distance needed past the map to the left equals 360 - distanceFromLeft. to minimize page stretching, go whichever way is shorter
if distanceFromLeft - width / 2 >= 180 then
distanceFromLeft = distanceFromLeft - 360
end
return 100 * distanceFromLeft / width
end
local function getY(latitude, top, bottom)
return 100 * (top - latitude) / (top - bottom)
end
function p.mark(frame, args, map)
if not args then
args = getArgs(frame, {wrappers = 'Template:Location map~'})
end
local mapnames = {}
if not map then
if args[1] then
map = {}
for mapname in mw.text.gsplit(args[1], '#', true) do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
mapnames[#mapnames + 1] = mapname
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('World', frame)
args[1] = 'World'
end
end
if type(map) == 'table' then
local outputs = {}
local oldargs = args[1]
for k,v in ipairs(map) do
args[1] = mapnames[k]
outputs[k] = tostring(p.mark(frame, args, v))
end
args[1] = oldargs
return table.concat(outputs, '#PlaceList#') .. '#PlaceList#'
end
local x, y, longitude, latitude
longitude = decdeg(args.lon_deg, args.lon_min, args.lon_sec, args.lon_dir, args.long, 'longitude')
latitude = decdeg(args.lat_deg, args.lat_min, args.lat_sec, args.lat_dir, args.lat, 'latitude')
if args.excludefrom then
-- If this mark is to be excluded from certain maps entirely (useful in the context of multiple maps)
for exclusionmap in mw.text.gsplit(args.excludefrom, '#', true) do
-- Check if this map is excluded. If so, return an empty string.
if args[1] == exclusionmap then
return ''
end
end
end
local builder = mw.html.create()
local currentTitle = mw.title.getCurrentTitle()
if args.coordinates then
-- Temporarily removed to facilitate infobox conversion. See [[Wikipedia:Coordinates in infoboxes]]
-- if longitude or latitude then
-- error('Coordinates from [[Module:Coordinates]] and individual coordinates cannot both be provided')
-- end
longitude = coord2text('longitude', args.coordinates)
latitude = coord2text('latitude', args.coordinates)
elseif not longitude and not latitude and args.useWikidata then
-- If they didn't provide either coordinate, try Wikidata. If they provided one but not the other, don't.
local entity = mw.wikibase.getEntity()
if entity and entity.claims and entity.claims.P625 and entity.claims.P625[1].mainsnak.snaktype == 'value' then
local value = entity.claims.P625[1].mainsnak.datavalue.value
longitude, latitude = value.longitude, value.latitude
end
if args.link and (currentTitle.namespace == 0) then
builder:wikitext('[[Category:Location maps with linked markers with coordinates from Wikidata]]')
end
end
if not longitude then
error('No value was provided for longitude')
elseif not latitude then
error('No value was provided for latitude')
end
if currentTitle.namespace > 0 then
if (not args.lon_deg) ~= (not args.lat_deg) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Degrees]]')
elseif (not args.lon_min) ~= (not args.lat_min) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Minutes]]')
elseif (not args.lon_sec) ~= (not args.lat_sec) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Seconds]]')
elseif (not args.lon_dir) ~= (not args.lat_dir) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Hemisphere]]')
elseif (not args.long) ~= (not args.lat) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Decimal]]')
end
end
if ((tonumber(args.lat_deg) or 0) < 0) and ((tonumber(args.lat_min) or 0) ~= 0 or (tonumber(args.lat_sec) or 0) ~= 0 or (args.lat_dir and args.lat_dir ~='')) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if ((tonumber(args.lon_deg) or 0) < 0) and ((tonumber(args.lon_min) or 0) ~= 0 or (tonumber(args.lon_sec) or 0) ~= 0 or (args.lon_dir and args.lon_dir ~= '')) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if (((tonumber(args.lat_min) or 0) < 0) or ((tonumber(args.lat_sec) or 0) < 0)) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if (((tonumber(args.lon_min) or 0) < 0) or ((tonumber(args.lon_sec) or 0) < 0)) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if args.skew or args.lon_shift or args.markhigh then
mw.log('Removed parameter used in invocation.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = (args.skew and 'skew' or '') ..
(args.lon_shift and 'lon_shift' or '') ..
(args.markhigh and 'markhigh' or '')
builder:wikitext('[[Category:Location maps with removed parameters|' .. key ..' ]]')
end
end
if map('x') ~= '' then
x = tonumber(mw.ext.ParserFunctions.expr(map('x', { latitude, longitude })))
else
x = tonumber(getX(longitude, map('left'), map('right')))
end
if map('y') ~= '' then
y = tonumber(mw.ext.ParserFunctions.expr(map('y', { latitude, longitude })))
else
y = tonumber(getY(latitude, map('top'), map('bottom')))
end
if (x < 0 or x > 100 or y < 0 or y > 100) and not args.outside then
mw.log('Mark placed outside map boundaries without outside flag set. x = ' .. x .. ', y = ' .. y)
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = currentTitle.prefixedText
builder:wikitext('[[Category:Location maps with marks outside map and outside parameter not set|' .. key .. ' ]]')
end
end
local mark = args.mark or map('mark')
if mark == '' then
mark = 'Red pog.svg'
end
local marksize = tonumber(args.marksize) or tonumber(map('marksize')) or 8
local imageDiv = markImageDiv(mark, marksize, args.label or mw.title.getCurrentTitle().text, args.link or '', args.alt, args[2])
local label_size = args.label_size or 91
local labelDiv
if args.label and args.position ~= 'none' then
labelDiv = markLabelDiv(args.label, label_size, args.label_width or 6, args.position, args.background, x, marksize)
end
return builder:node(markOuterDiv(x, y, imageDiv, labelDiv, label_size))
end
local function switcherSeparate(s)
if s == nil then return {} end
local retval = {}
for i in string.gmatch(s .. '#', '([^#]*)#') do
i = mw.text.trim(i)
retval[#retval + 1] = (i ~= '' and i)
end
return retval
end
function p.infobox_pushpin_map(frame)
--This function is designed to be invoked from an infobox template
--* Some parameters (generally starting with "pushpin_") are meant to be exposed as parameters
-- in the outer infobox, settable by editors
--* Others are meant to be "hidden" (e.g., only set inside the infobox template code)
-- First get the combined arguments from both parent and invocation frame
local raw_args = getArgs(frame,{parentFirst=true})
--If no map is supplied, return.
if not raw_args['pushpin_map'] then
return
end
-- Now get arguments from just the invocation frame
local frame_args = getArgs(frame,{frameOnly=true})
-- parsed_args will have the resulting merged parameters
local parsed_args = {}
-- Default to using wikidata coodinates if no other coordiantes supplied.
if raw_args.useWikidata == nil then
parsed_args.useWikidata = true
else
parsed_args.useWikidata = raw_args.useWikidata
end
-- Parse the arguments
parsed_args[1] = raw_args['pushpin_map']
parsed_args.float = frame_args.float or 'center'
parsed_args.border = frame_args.border or 'infobox'
parsed_args.default_width = frame_args.default_width
parsed_args.max_width = frame_args.max_width
parsed_args.coordinates = raw_args['coordinates']
parsed_args.caption = raw_args['pushpin_caption']
parsed_args.relief = raw_args['pushpin_relief']
parsed_args.label = raw_args['pushpin_label']
parsed_args.label_size = raw_args['pushpin_label_size']
parsed_args.position = raw_args['pushpin_label_position']
parsed_args.mark = raw_args['pushpin_mark']
parsed_args.marksize = raw_args['pushpin_mark_size']
parsed_args.alt = raw_args['pushpin_alt']
parsed_args.background = raw_args['pushpin_background']
parsed_args.width = raw_args['pushpin_map_size']
local map = {}
local caption_list = {}
for mapname in string.gmatch(parsed_args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
end
if parsed_args['caption'] then
for caption in mw.text.gsplit(parsed_args['caption'], '##', true) do
caption_list[#caption_list + 1] = caption
end
end
if #map == 1 then
map = map[1]
if not parsed_args.caption then
parsed_args.caption = 'Location within ' .. map('name')
end
end
if type(map) == 'table' then
mw.log('----')
mw.logObject(map)
if #caption_list > #map then
error(string.format('%d captions were provided, but only %d maps were provided', #caption_list, #map))
elseif not parsed_args.caption then
-- Set a default caption for each of the multiple maps
for i=1, #map do
caption_list[#caption_list + 1] = 'Location within '.. map[i]('name')
end
end
local outputs = {}
parsed_args.autoSwitcherLabel = true
for k,v in ipairs(map) do
parsed_args.caption = caption_list[k]
outputs[k] = p.main(frame, parsed_args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, parsed_args, map) .. tostring( p.mark(frame, parsed_args, map) ) .. p.bottom(frame, parsed_args, map)
end
end
function p.main(frame, args, map)
local caption_list = {}
if not args then
args = getArgs(frame, {wrappers = 'Template:Location map', valueFunc = p.valueFunc})
end
if args.useWikidata == nil then
args.useWikidata = true
end
if not map then
if args[1] then
map = {}
for mapname in string.gmatch(args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
end
if args['caption'] then
if args['caption'] == "" then
while #caption_list < #map do
caption_list[#caption_list + 1] = args['caption']
end
else
for caption in mw.text.gsplit(args['caption'], '##', true) do
caption_list[#caption_list + 1] = caption
end
end
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('World', frame)
end
end
if type(map) == 'table' then
local altmaps = switcherSeparate(args.AlternativeMap)
if #altmaps > #map then
error(string.format('%d AlternativeMaps were provided, but only %d maps were provided', #altmaps, #map))
end
local overlays = switcherSeparate(args.overlay_image)
if #overlays > #map then
error(string.format('%d overlay_images were provided, but only %d maps were provided', #overlays, #map))
end
if #caption_list > #map then
error(string.format('%d captions were provided, but only %d maps were provided', #caption_list, #map))
end
local outputs = {}
args.autoSwitcherLabel = true
for k,v in ipairs(map) do
args.AlternativeMap = altmaps[k]
args.overlay_image = overlays[k]
args.caption = caption_list[k]
outputs[k] = p.main(frame, args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, args, map) .. tostring( p.mark(frame, args, map) ) .. p.bottom(frame, args, map)
end
end
return p
3pqbnkg8pemwulwnvka0szt6hqc0tii
124188
124187
2026-11-09T20:20:40Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Location_map]]
119026
Scribunto
text/plain
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local function round(n, decimals)
local pow = 10^(decimals or 0)
return math.floor(n * pow + 0.5) / pow
end
function p.getMapParams(map, frame)
if not map then
error('The name of the location map definition to use must be specified', 2)
end
local moduletitle = mw.title.new('Module:Location map/data/' .. map)
if not moduletitle then
error(string.format('%q is not a valid name for a location map definition', map), 2)
elseif moduletitle.exists then
local mapData = mw.loadData('Module:Location map/data/' .. map)
return function(name, params)
if name == nil then
return 'Module:Location map/data/' .. map
elseif mapData[name] == nil then
return ''
elseif params then
return mw.message.newRawMessage(tostring(mapData[name]), unpack(params)):plain()
else
return mapData[name]
end
end
else
error('Unable to find the specified location map definition: "Module:Location map/data/' .. map .. '" does not exist', 2)
end
end
function p.data(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local params = {}
for k,v in ipairs(args) do
if k > 2 then
params[k-2] = v
end
end
return map(args[2], #params ~= 0 and params)
end
local hemisphereMultipliers = {
longitude = { W = -1, w = -1, E = 1, e = 1 },
latitude = { S = -1, s = -1, N = 1, n = 1 }
}
local function decdeg(degrees, minutes, seconds, hemisphere, decimal, direction)
if decimal then
if degrees then
error('Decimal and DMS degrees cannot both be provided for ' .. direction, 2)
elseif minutes then
error('Minutes can only be provided with DMS degrees for ' .. direction, 2)
elseif seconds then
error('Seconds can only be provided with DMS degrees for ' .. direction, 2)
elseif hemisphere then
error('A hemisphere can only be provided with DMS degrees for ' .. direction, 2)
end
local retval = tonumber(decimal)
if retval then
return retval
end
error('The value "' .. decimal .. '" provided for ' .. direction .. ' is not valid', 2)
elseif seconds and not minutes then
error('Seconds were provided for ' .. direction .. ' without minutes also being provided', 2)
elseif not degrees then
if minutes then
error('Minutes were provided for ' .. direction .. ' without degrees also being provided', 2)
elseif hemisphere then
error('A hemisphere was provided for ' .. direction .. ' without degrees also being provided', 2)
end
return nil
end
decimal = tonumber(degrees)
if not decimal then
error('The degree value "' .. degrees .. '" provided for ' .. direction .. ' is not valid', 2)
elseif minutes and not tonumber(minutes) then
error('The minute value "' .. minutes .. '" provided for ' .. direction .. ' is not valid', 2)
elseif seconds and not tonumber(seconds) then
error('The second value "' .. seconds .. '" provided for ' .. direction .. ' is not valid', 2)
end
decimal = decimal + (minutes or 0)/60 + (seconds or 0)/3600
if hemisphere then
local multiplier = hemisphereMultipliers[direction][hemisphere]
if not multiplier then
error('The hemisphere "' .. hemisphere .. '" provided for ' .. direction .. ' is not valid', 2)
end
decimal = decimal * multiplier
end
return decimal
end
-- Finds a parameter in a transclusion of {{Coord}}.
local function coord2text(para,coord) -- this should be changed for languages which do not use Arabic numerals or the degree sign
local lat, long = mw.ustring.match(coord,'<span class="p%-latitude latitude">([^<]+)</span><span class="p%-longitude longitude">([^<]+)</span>')
if lat then
return tonumber(para == 'longitude' and long or lat)
end
local result = mw.text.split(mw.ustring.match(coord,'%-?[%.%d]+°[NS] %-?[%.%d]+°[EW]') or '', '[ °]')
if para == 'longitude' then result = {result[3], result[4]} end
if not tonumber(result[1]) or not result[2] then
mw.log('Malformed coordinates value')
mw.logObject(para, 'para')
mw.logObject(coord, 'coord')
return error('Malformed coordinates value', 2)
end
return tonumber(result[1]) * hemisphereMultipliers[para][result[2]]
end
-- effectively make removeBlanks false for caption and maplink, and true for everything else
-- if useWikidata is present but blank, convert it to false instead of nil
-- p.top, p.bottom, and their callers need to use this
function p.valueFunc(key, value)
if value then
value = mw.text.trim(value)
end
if value ~= '' or key == 'caption' or key == 'maplink' then
return value
elseif key == 'useWikidata' then
return false
end
end
local function getContainerImage(args, map)
if args.AlternativeMap then
return args.AlternativeMap
elseif args.relief then
local digits = mw.ustring.match(args.relief,'^[1-9][0-9]?$') -- image1 to image99
if digits then
local imageDigits = map('image' .. digits)
if imageDigits ~= '' then return imageDigits end
end
local yesNo = require('Module:Yesno')
if yesNo(args.relief,true) then
local image1 = map('image1')
if image1 ~= '' then return image1 end
end
end
return map('image')
end
function p.top(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local width
local default_as_number = tonumber(mw.ustring.match(tostring(args.default_width),"%d*"))
if not args.width then
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
elseif mw.ustring.sub(args.width, -2) == 'px' then
width = mw.ustring.sub(args.width, 1, -3)
else
width = args.width
end
local width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
if width_as_number == 0 then
-- check to see if width is junk. If it is, then use default calculation
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
end
if args.max_width ~= "" and args.max_width ~= nil then
-- check to see if width bigger than max_width
local max_as_number = tonumber(mw.ustring.match(args.max_width,"%d*")) or 0;
if width_as_number>max_as_number and max_as_number>0 then
width = args.max_width;
end
end
local retval = frame:extensionTag{name = 'templatestyles', args = {src = 'Module:Location map/styles.css'}}
if args.float == 'center' then
retval = retval .. '<div class="center">'
end
if args.caption and args.caption ~= '' and args.border ~= 'infobox' then
retval = retval .. '<div class="locmap noresize thumb '
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'floatleft'
elseif args.float == '"center"' or args.float == 'center' or args.float == '"none"' or args.float == 'none' then
retval = retval .. 'tnone'
else
retval = retval .. 'floatright'
end
retval = retval .. '"><div class="thumbinner" style="width:' .. (width + 2) .. 'px'
if args.border == 'none' then
retval = retval .. ';border:none'
elseif args.border then
retval = retval .. ';border-color:' .. args.border
end
retval = retval .. '"><div style="position:relative;width:' .. width .. 'px' .. (args.border ~= 'none' and ';border:1px solid lightgray">' or '">')
else
retval = retval .. '<div class="locmap" style="width:' .. width .. 'px;'
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'float:left;clear:left'
elseif args.float == '"center"' or args.float == 'center' then
retval = retval .. 'float:none;clear:both;margin-left:auto;margin-right:auto'
elseif args.float == '"none"' or args.float == 'none' then
retval = retval .. 'float:none;clear:none'
else
retval = retval .. 'float:right;clear:right'
end
retval = retval .. '"><div style="width:' .. width .. 'px;padding:0"><div style="position:relative;width:' .. width .. 'px">'
end
local image = getContainerImage(args, map)
local currentTitle = mw.title.getCurrentTitle()
retval = string.format(
'%s[[File:%s|%spx|%s%s|class=notpageimage noviewer]]',
retval,
image,
width,
args.alt or ((args.label or currentTitle.text) .. ' is located in ' .. map('name')),
args.maplink and ('|link=' .. args.maplink) or ''
)
if args.caption and args.caption ~= '' then
if (currentTitle.namespace == 0) and mw.ustring.find(args.caption, '##') then
retval = retval .. '[[Category:Pages using location map with a double number sign in the caption]]'
end
end
if args.overlay_image then
return retval .. '<div style="position:absolute;top:0;left:0">[[File:' .. args.overlay_image .. '|' .. width .. 'px|class=notpageimage noviewer]]</div>'
else
return retval
end
end
function p.bottom(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local retval = '</div>'
local currentTitle = mw.title.getCurrentTitle()
if not args.caption or args.border == 'infobox' then
if args.border then
retval = retval .. '<div style="padding-top:0.2em">'
else
retval = retval .. '<div style="font-size:91%;padding-top:3px">'
end
retval = retval
.. (args.caption or (args.label or currentTitle.text) .. ' (' .. map('name') .. ')')
.. '</div>'
elseif args.caption ~= '' then
-- This is not the pipe trick. We're creating a link with no text on purpose, so that CSS can give us a nice image
retval = retval .. '<div class="thumbcaption"><div class="magnify">[[:File:' .. getContainerImage(args, map) .. '| ]]</div>' .. args.caption .. '</div>'
end
if args.switcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">' .. args.switcherLabel .. '</span>'
elseif args.autoSwitcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">Show map of ' .. map('name') .. '</span>'
end
retval = retval .. '</div></div>'
if args.caption_undefined then
mw.log('Removed parameter caption_undefined used.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
retval = retval .. '[[Category:Location maps with removed parameters|caption_undefined]]'
end
end
if map('skew') ~= '' or map('lat_skew') ~= '' or map('crosses180') ~= '' or map('type') ~= '' then
mw.log('Removed parameter used in map definition ' .. map())
if currentTitle.namespace == 0 then
local key = (map('skew') ~= '' and 'skew' or '') ..
(map('lat_skew') ~= '' and 'lat_skew' or '') ..
(map('crosses180') ~= '' and 'crosses180' or '') ..
(map('type') ~= '' and 'type' or '')
retval = retval .. '[[Category:Location maps with removed parameters|' .. key .. ' ]]'
end
end
if string.find(map('name'), '|', 1, true) then
mw.log('Pipe used in name of map definition ' .. map())
if currentTitle.namespace == 0 then
retval = retval .. '[[Category:Location maps with a name containing a pipe]]'
end
end
if args.float == 'center' then
retval = retval .. '</div>'
end
return retval
end
local function markOuterDiv(x, y, imageDiv, labelDiv, label_size)
return mw.html.create('div')
:addClass('od')
:addClass('notheme') -- T236137
:cssText('top:' .. round(y, 3) .. '%;left:' .. round(x, 3) .. '%;font-size:' .. label_size .. '%')
:node(imageDiv)
:node(labelDiv)
end
local function markImageDiv(mark, marksize, label, link, alt, title)
local builder = mw.html.create('div')
:addClass('id')
:cssText('left:-' .. round(marksize / 2) .. 'px;top:-' .. round(marksize / 2) .. 'px')
:attr('title', title)
if marksize ~= 0 then
builder:wikitext(string.format(
'[[File:%s|%dx%dpx|%s|link=%s%s|class=notpageimage noviewer]]',
mark,
marksize,
marksize,
label,
link,
alt and ('|alt=' .. alt) or ''
))
end
return builder
end
local function markLabelDiv(label, label_size, label_width, position, background, x, marksize)
if tonumber(label_size) == 0 then
return mw.html.create('div'):addClass('l0'):wikitext(label)
end
local builder = mw.html.create('div')
:cssText('width:' .. label_width .. 'em')
local distance = round(marksize / 2 + 1)
if position == 'top' then -- specified top
builder:addClass('pv'):cssText('bottom:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em')
elseif position == 'bottom' then -- specified bottom
builder:addClass('pv'):cssText('top:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em')
elseif position == 'left' or (tonumber(x) > 70 and position ~= 'right') then -- specified left or autodetected to left
builder:addClass('pl'):cssText('right:' .. distance .. 'px')
else -- specified right or autodetected to right
builder:addClass('pr'):cssText('left:' .. distance .. 'px')
end
builder = builder:tag('div')
:wikitext(label)
if background then
builder:cssText('background-color:' .. background)
end
return builder:done()
end
local function getX(longitude, left, right)
local width = (right - left) % 360
if width == 0 then
width = 360
end
local distanceFromLeft = (longitude - left) % 360
-- the distance needed past the map to the right equals distanceFromLeft - width. the distance needed past the map to the left equals 360 - distanceFromLeft. to minimize page stretching, go whichever way is shorter
if distanceFromLeft - width / 2 >= 180 then
distanceFromLeft = distanceFromLeft - 360
end
return 100 * distanceFromLeft / width
end
local function getY(latitude, top, bottom)
return 100 * (top - latitude) / (top - bottom)
end
function p.mark(frame, args, map)
if not args then
args = getArgs(frame, {wrappers = 'Template:Location map~'})
end
local mapnames = {}
if not map then
if args[1] then
map = {}
for mapname in mw.text.gsplit(args[1], '#', true) do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
mapnames[#mapnames + 1] = mapname
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('World', frame)
args[1] = 'World'
end
end
if type(map) == 'table' then
local outputs = {}
local oldargs = args[1]
for k,v in ipairs(map) do
args[1] = mapnames[k]
outputs[k] = tostring(p.mark(frame, args, v))
end
args[1] = oldargs
return table.concat(outputs, '#PlaceList#') .. '#PlaceList#'
end
local x, y, longitude, latitude
longitude = decdeg(args.lon_deg, args.lon_min, args.lon_sec, args.lon_dir, args.long, 'longitude')
latitude = decdeg(args.lat_deg, args.lat_min, args.lat_sec, args.lat_dir, args.lat, 'latitude')
if args.excludefrom then
-- If this mark is to be excluded from certain maps entirely (useful in the context of multiple maps)
for exclusionmap in mw.text.gsplit(args.excludefrom, '#', true) do
-- Check if this map is excluded. If so, return an empty string.
if args[1] == exclusionmap then
return ''
end
end
end
local builder = mw.html.create()
local currentTitle = mw.title.getCurrentTitle()
if args.coordinates then
-- Temporarily removed to facilitate infobox conversion. See [[Wikipedia:Coordinates in infoboxes]]
-- if longitude or latitude then
-- error('Coordinates from [[Module:Coordinates]] and individual coordinates cannot both be provided')
-- end
longitude = coord2text('longitude', args.coordinates)
latitude = coord2text('latitude', args.coordinates)
elseif not longitude and not latitude and args.useWikidata then
-- If they didn't provide either coordinate, try Wikidata. If they provided one but not the other, don't.
local entity = mw.wikibase.getEntity()
if entity and entity.claims and entity.claims.P625 and entity.claims.P625[1].mainsnak.snaktype == 'value' then
local value = entity.claims.P625[1].mainsnak.datavalue.value
longitude, latitude = value.longitude, value.latitude
end
if args.link and (currentTitle.namespace == 0) then
builder:wikitext('[[Category:Location maps with linked markers with coordinates from Wikidata]]')
end
end
if not longitude then
error('No value was provided for longitude')
elseif not latitude then
error('No value was provided for latitude')
end
if currentTitle.namespace > 0 then
if (not args.lon_deg) ~= (not args.lat_deg) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Degrees]]')
elseif (not args.lon_min) ~= (not args.lat_min) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Minutes]]')
elseif (not args.lon_sec) ~= (not args.lat_sec) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Seconds]]')
elseif (not args.lon_dir) ~= (not args.lat_dir) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Hemisphere]]')
elseif (not args.long) ~= (not args.lat) then
builder:wikitext('[[Category:Location maps with different longitude and latitude precisions|Decimal]]')
end
end
if ((tonumber(args.lat_deg) or 0) < 0) and ((tonumber(args.lat_min) or 0) ~= 0 or (tonumber(args.lat_sec) or 0) ~= 0 or (args.lat_dir and args.lat_dir ~='')) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if ((tonumber(args.lon_deg) or 0) < 0) and ((tonumber(args.lon_min) or 0) ~= 0 or (tonumber(args.lon_sec) or 0) ~= 0 or (args.lon_dir and args.lon_dir ~= '')) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if (((tonumber(args.lat_min) or 0) < 0) or ((tonumber(args.lat_sec) or 0) < 0)) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if (((tonumber(args.lon_min) or 0) < 0) or ((tonumber(args.lon_sec) or 0) < 0)) then
builder:wikitext('[[Category:Location maps with negative degrees and minutes or seconds]]')
end
if args.skew or args.lon_shift or args.markhigh then
mw.log('Removed parameter used in invocation.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = (args.skew and 'skew' or '') ..
(args.lon_shift and 'lon_shift' or '') ..
(args.markhigh and 'markhigh' or '')
builder:wikitext('[[Category:Location maps with removed parameters|' .. key ..' ]]')
end
end
if map('x') ~= '' then
x = tonumber(mw.ext.ParserFunctions.expr(map('x', { latitude, longitude })))
else
x = tonumber(getX(longitude, map('left'), map('right')))
end
if map('y') ~= '' then
y = tonumber(mw.ext.ParserFunctions.expr(map('y', { latitude, longitude })))
else
y = tonumber(getY(latitude, map('top'), map('bottom')))
end
if (x < 0 or x > 100 or y < 0 or y > 100) and not args.outside then
mw.log('Mark placed outside map boundaries without outside flag set. x = ' .. x .. ', y = ' .. y)
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = currentTitle.prefixedText
builder:wikitext('[[Category:Location maps with marks outside map and outside parameter not set|' .. key .. ' ]]')
end
end
local mark = args.mark or map('mark')
if mark == '' then
mark = 'Red pog.svg'
end
local marksize = tonumber(args.marksize) or tonumber(map('marksize')) or 8
local imageDiv = markImageDiv(mark, marksize, args.label or mw.title.getCurrentTitle().text, args.link or '', args.alt, args[2])
local label_size = args.label_size or 91
local labelDiv
if args.label and args.position ~= 'none' then
labelDiv = markLabelDiv(args.label, label_size, args.label_width or 6, args.position, args.background, x, marksize)
end
return builder:node(markOuterDiv(x, y, imageDiv, labelDiv, label_size))
end
local function switcherSeparate(s)
if s == nil then return {} end
local retval = {}
for i in string.gmatch(s .. '#', '([^#]*)#') do
i = mw.text.trim(i)
retval[#retval + 1] = (i ~= '' and i)
end
return retval
end
function p.infobox_pushpin_map(frame)
--This function is designed to be invoked from an infobox template
--* Some parameters (generally starting with "pushpin_") are meant to be exposed as parameters
-- in the outer infobox, settable by editors
--* Others are meant to be "hidden" (e.g., only set inside the infobox template code)
-- First get the combined arguments from both parent and invocation frame
local raw_args = getArgs(frame,{parentFirst=true})
--If no map is supplied, return.
if not raw_args['pushpin_map'] then
return
end
-- Now get arguments from just the invocation frame
local frame_args = getArgs(frame,{frameOnly=true})
-- parsed_args will have the resulting merged parameters
local parsed_args = {}
-- Default to using wikidata coodinates if no other coordiantes supplied.
if raw_args.useWikidata == nil then
parsed_args.useWikidata = true
else
parsed_args.useWikidata = raw_args.useWikidata
end
-- Parse the arguments
parsed_args[1] = raw_args['pushpin_map']
parsed_args.float = frame_args.float or 'center'
parsed_args.border = frame_args.border or 'infobox'
parsed_args.default_width = frame_args.default_width
parsed_args.max_width = frame_args.max_width
parsed_args.coordinates = raw_args['coordinates']
parsed_args.caption = raw_args['pushpin_caption']
parsed_args.relief = raw_args['pushpin_relief']
parsed_args.label = raw_args['pushpin_label']
parsed_args.label_size = raw_args['pushpin_label_size']
parsed_args.position = raw_args['pushpin_label_position']
parsed_args.mark = raw_args['pushpin_mark']
parsed_args.marksize = raw_args['pushpin_mark_size']
parsed_args.alt = raw_args['pushpin_alt']
parsed_args.background = raw_args['pushpin_background']
parsed_args.width = raw_args['pushpin_map_size']
local map = {}
local caption_list = {}
for mapname in string.gmatch(parsed_args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
end
if parsed_args['caption'] then
for caption in mw.text.gsplit(parsed_args['caption'], '##', true) do
caption_list[#caption_list + 1] = caption
end
end
if #map == 1 then
map = map[1]
if not parsed_args.caption then
parsed_args.caption = 'Location within ' .. map('name')
end
end
if type(map) == 'table' then
mw.log('----')
mw.logObject(map)
if #caption_list > #map then
error(string.format('%d captions were provided, but only %d maps were provided', #caption_list, #map))
elseif not parsed_args.caption then
-- Set a default caption for each of the multiple maps
for i=1, #map do
caption_list[#caption_list + 1] = 'Location within '.. map[i]('name')
end
end
local outputs = {}
parsed_args.autoSwitcherLabel = true
for k,v in ipairs(map) do
parsed_args.caption = caption_list[k]
outputs[k] = p.main(frame, parsed_args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, parsed_args, map) .. tostring( p.mark(frame, parsed_args, map) ) .. p.bottom(frame, parsed_args, map)
end
end
function p.main(frame, args, map)
local caption_list = {}
if not args then
args = getArgs(frame, {wrappers = 'Template:Location map', valueFunc = p.valueFunc})
end
if args.useWikidata == nil then
args.useWikidata = true
end
if not map then
if args[1] then
map = {}
for mapname in string.gmatch(args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
end
if args['caption'] then
if args['caption'] == "" then
while #caption_list < #map do
caption_list[#caption_list + 1] = args['caption']
end
else
for caption in mw.text.gsplit(args['caption'], '##', true) do
caption_list[#caption_list + 1] = caption
end
end
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('World', frame)
end
end
if type(map) == 'table' then
local altmaps = switcherSeparate(args.AlternativeMap)
if #altmaps > #map then
error(string.format('%d AlternativeMaps were provided, but only %d maps were provided', #altmaps, #map))
end
local overlays = switcherSeparate(args.overlay_image)
if #overlays > #map then
error(string.format('%d overlay_images were provided, but only %d maps were provided', #overlays, #map))
end
if #caption_list > #map then
error(string.format('%d captions were provided, but only %d maps were provided', #caption_list, #map))
end
local outputs = {}
args.autoSwitcherLabel = true
for k,v in ipairs(map) do
args.AlternativeMap = altmaps[k]
args.overlay_image = overlays[k]
args.caption = caption_list[k]
outputs[k] = p.main(frame, args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, args, map) .. tostring( p.mark(frame, args, map) ) .. p.bottom(frame, args, map)
end
end
return p
3pqbnkg8pemwulwnvka0szt6hqc0tii
Module:Infobox mapframe
828
26039
124175
119021
2026-10-02T22:57:03Z
en>Zackmann08
0
Correct edit summary this time... With all the deprecations that have been done recently, 'coord' is no longer a supported Infobox parameter anywhere. Should always be 'coordinates'
124175
Scribunto
text/plain
local mf = require('Module:Mapframe')
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local infoboxImage = require('Module:InfoboxImage').InfoboxImage
-- Defaults
local DEFAULT_FRAME_WIDTH = "270"
local DEFAULT_FRAME_HEIGHT = "200"
local DEFAULT_ZOOM = 10
local DEFAULT_GEOMASK_STROKE_WIDTH = "1"
local DEFAULT_GEOMASK_STROKE_COLOR = "#777777"
local DEFAULT_GEOMASK_FILL = "#888888"
local DEFAULT_GEOMASK_FILL_OPACITY = "0.25"
local DEFAULT_SHAPE_STROKE_WIDTH = "2"
local DEFAULT_SHAPE_STROKE_COLOR = "#FF0000"
local DEFAULT_SHAPE_FILL = "#606060"
local DEFAULT_SHAPE_FILL_OPACITY = "0.1"
local DEFAULT_LINE_STROKE_WIDTH = "5"
local DEFAULT_LINE_STROKE_COLOR = "#FF0000"
local DEFAULT_MARKER_COLOR = "#5E74F3"
local util = {}
function util.noop(info)
local DEFAULT_NOOP_OUTPUT = ""
-- uncomment this when debugging
-- DEFAULT_NOOP_OUTPUT = "debug: mapframe no-op: " .. info
-- mw.log(DEFAULT_NOOP_OUTPUT)
return DEFAULT_NOOP_OUTPUT
end
-- Trim whitespace from args, and remove empty args
function util.trimArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val ~= '' then
cleanArgs[key] = val
end
else
cleanArgs[key] = val
end
end
return cleanArgs
end
function util.getBestStatement(item_id, property_id)
if not(item_id) or not(mw.wikibase.isValidEntityId(item_id)) or not(mw.wikibase.entityExists(item_id)) then
return false
end
local statements = mw.wikibase.getBestStatements(item_id, property_id)
if not statements or #statements == 0 then
return false
end
local hasNoValue = ( statements[1].mainsnak and statements[1].mainsnak.snaktype == 'novalue' )
if hasNoValue then
return false
end
return statements[1]
end
function util.hasWikidataProperty(item_id, property_id)
return util.getBestStatement(item_id, property_id) and true or false
end
function util.getStatementValue(statement)
return statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value or nil
end
function util.relatedEntity(item_id, property_id)
local value = util.getStatementValue( util.getBestStatement(item_id, property_id) )
return value and value.id or false
end
function util.idType(id)
if not id then
return nil
elseif mw.ustring.match(id, "[Pp]%d+") then
return "property"
elseif mw.ustring.match(id, "[Qq]%d+") then
return "item"
else
return nil
end
end
function util.shouldAutoRun(frame)
-- Check if should be running
local pargs = frame.getParent(frame).args
local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or "")) -- true of false or nil
if pargs.coordinates == "{{{coordinates}}}" then explicitlyOn = false end
if type(pargs.coordinates) == 'string' and string.match(pargs.coordinates, 'coord.missing') then explicitlyOn = false end
local onByDefault = (explicitlyOn == nil) and yesno(mw.text.trim(frame.args.onByDefault or ""), false) -- true or false
return explicitlyOn or onByDefault
end
function util.argsFromAuto(frame)
-- Get args from the frame (invoke call) and the parent (template call).
-- Frame arguments are default values which are overridden by parent values
-- when both are present
local args = getArgs(frame, {parentFirst = true})
-- Discard args not prefixed with "mapframe-", remove that prefix from those that remain
local fixedArgs = {}
for name, val in pairs(args) do
local fixedName = string.match(name, "^mapframe%-(.+)$" )
if fixedName then
fixedArgs[fixedName] = val
-- allow coord, coordinates, etc to be unprefixed
elseif name == "coordinates" or name == "coordinate" and not fixedArgs.coord then
fixedArgs.coord = val
-- allow id, qid to be unprefixed, map to id (if not already present)
elseif name == "id" or name == "qid" and not fixedArgs.id then
fixedArgs.id = val
-- allow captionstyle to be unprefixed, for compatibility with [[Module:Infobox]]
elseif name == "captionstyle" and not fixedArgs.captionstyle then
fixedArgs.captionstyle = val
end
end
return fixedArgs
end
function util.parseCustomWikitext(customWikitext)
-- infoboxImage will format an image if given wikitext containing an
-- image, or else pass through the wikitext unmodified
return infoboxImage({
args = {
image = customWikitext
}
})
end
function util.trackAndWarn(trackingCat, warning)
local title = mw.title.getCurrentTitle()
local results = title and title.namespace == 0 and trackingCat and '[[Category:'..trackingCat..']]' or ''
if warning then
local warn = require('Module:If preview')._warning
results = results..warn({warning})
end
return results
end
function util.ternary(flag, other)
other = other or 'other'
flag = flag == 'none' and 'no' or flag
local yesNoOut = yesno(flag,other)
local yes = (yesNoOut == true)
local no = (yesNoOut == false)
return yes, no
end
local p = {}
p._caption = function(args)
if args.caption then
return args.caption
elseif args.switcher then
return util.noop("no caption or switcher")
end
local maskItem
local maskType = util.idType(args.geomask)
if maskType == 'item' then
maskItem = args.geomask
elseif maskType == "property" then
maskItem = util.relatedEntity(args.id or mw.wikibase.getEntityIdForCurrentPage(), args.geomask)
end
local maskItemLabel = maskItem and mw.wikibase.getLabel( maskItem )
return maskItemLabel and "Location in "..maskItemLabel
or util.noop("missing maskItemLabel with type " .. (maskType or "nil") .. " and item " .. (maskItem or "nil"))
end
--A list of types for objects that are too small to allow Kartographer to take over zoom
local tinyType = {
landmark=true,
railwaystation=true,
edu=true,
pass=true,
camera=true
}
p._main = function(_config)
-- accumulate tracking cats
local tracking = ''
-- `config` is the args passed to this module
local config = util.trimArgs(_config)
-- allow alias for config.coord
config.coord = config.coord or config.coordinates
-- Require wikidata item, or specified coords
local wikidataId = config.id or mw.wikibase.getEntityIdForCurrentPage()
if not(wikidataId) and not(config.coord) then
return false, util.trackAndWarn('Pages using infobox mapframe with missing coordinates')
end
-- Require coords (specified or from wikidata), so that map will be centred somewhere
-- (P625 = coordinate location)
local wdCoordinates = util.getStatementValue(util.getBestStatement(wikidataId, 'P625'))
if not (config.coord or wdCoordinates) then
return false, util.trackAndWarn('Pages using infobox mapframe with missing coordinates')
end
-- `args` is the arguments which will be passed to the mapframe module
local args = {}
-- Some defaults/overrides for infobox presentation
args.display = "inline"
args.frame = "yes"
args.plain = "yes"
args["frame-width"] = config["frame-width"] or config.width or DEFAULT_FRAME_WIDTH
args["frame-height"] = config["frame-height"] or config.height or DEFAULT_FRAME_HEIGHT
args["frame-align"] = "center"
args["frame-coord"] = config["frame-coordinates"] or config["frame-coord"]
-- Note: config["coordinates"] or config["coord"] should not be used for the alignment of the frame;
-- see talk page ( https://en.wikipedia.org/wiki/Special:Diff/876492931 )
-- deprecated lat and long parameters
args["frame-lat"] = config["frame-lat"] or config["frame-latitude"]
args["frame-long"] = config["frame-long"] or config["frame-longitude"]
-- if zoom isn't specified from config, first check wikidata
local zoom = config.zoom or util.getStatementValue(util.getBestStatement(wikidataId, 'P6592'))
if not zoom then
-- Calculate zoom from length or area (converted to km or km2)
-- Zoom so that length or area is completely included in mapframe
local getZoom = require('Module:Infobox dim')._zoom
zoom = getZoom({length_km=config.length_km, length_mi=config.length_mi,
width_km=config.width_km, width_mi=config.width_mi,
area_km2=config.area_km2, area_mi2=config.area_mi2,
area_ha=config.area_ha, area_acre=config.area_acre,
type=config.type, population=config.population,
viewport_px=math.min(args["frame-width"],args["frame-height"]),
latitude=wdCoordinates and wdCoordinates.latitude})
end
args.zoom = zoom or DEFAULT_ZOOM
-- Use OSM relation ID if available; otherwise use geoshape if that is available
-- (geoshape is required for defunct entities, which are outside OSM's scope)
local hasOsmRelationId = util.hasWikidataProperty(wikidataId, 'P402') -- P402 is OSM relation ID
local hasGeoshape = util.hasWikidataProperty(wikidataId, 'P3896') -- P3896 is geoshape
local wikidataProvidesGeo = hasOsmRelationId or hasGeoshape
-- determine marker argument value, determine whether to show marker
local forcePoint, suppressPoint = util.ternary(config.point)
local forceMarker, suppressMarker = util.ternary(config.marker,true)
forcePoint = forcePoint or forceMarker
suppressPoint = suppressPoint or suppressMarker
local showMarker = not suppressPoint and (forcePoint or not wikidataProvidesGeo or config.coord)
-- wikidata = "yes" turns on both shape and line
-- wikidata = "no" turns off both shape and line
-- otherwise show both if wikidata provides geo
local forceWikidata, suppressWikidata = util.ternary(config.wikidata)
local showShape = not suppressWikidata and (forceWikidata or wikidataProvidesGeo or not config.coord)
local showLine = showShape
-- determine shape parameter value, determine whether to show or suppress shape
-- also determine whether to invert shape
local forceShape, suppressShape = util.ternary(config.shape)
showShape = wikidataId and not suppressShape and (forceShape or showShape)
local shapeType = config.shape == 'inverse' and 'shape-inverse' or 'shape'
-- determine line parameter value, determine whether to show or suppress line
local forceLine, suppressLine = util.ternary(config.line)
showLine = wikidataId and not suppressLine and (forceLine or showLine)
local maskItem
-- Switcher
if config.switcher == "zooms" then
-- switching between zoom levels
local maxZoom = math.max(tonumber(args.zoom), 3) -- what zoom would have otherwise been (if 3 or more, otherwise 3)
local minZoom = 1 -- completely zoomed out
local midZoom = math.floor((maxZoom + minZoom)/2) -- midway between maxn and min
args.switch = "zoomed in, zoomed midway, zoomed out"
args.zoom = string.format("SWITCH:%d,%d,%d", maxZoom, midZoom, minZoom)
elseif config.switcher == "auto" then
-- switching between P276 and P131 areas with recursive lookup, e.g. item's city,
-- that city's state, and that state's country
args.zoom = nil -- let kartographer determine the zoom
local maskLabels = {}
local maskItems = {}
local maskItemId = util.relatedEntity(wikidataId, "P276") or util.relatedEntity(wikidataId, "P131")
local maskLabel = mw.wikibase.getLabel(maskItemId)
while maskItemId and maskLabel and mw.text.trim(maskLabel) ~= "" do
table.insert(maskLabels, maskLabel)
table.insert(maskItems, maskItemId)
maskItemId = maskItemId and util.relatedEntity(maskItemId, "P131")
maskLabel = maskItemId and mw.wikibase.getLabel(maskItemId)
end
if #maskLabels > 1 then
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
elseif #maskLabels == 1 then
maskItem = maskItemId[1]
end
elseif config.switcher == "geomasks" and config.geomask then
-- switching between items in geomask parameter
args.zoom = nil -- let kartographer determine the zoom
local separator = (mw.ustring.find(config.geomask, "###", 0, true ) and "###") or
(mw.ustring.find(config.geomask, ";", 0, true ) and ";") or ","
local pattern = "%s*"..separator.."%s*"
local maskItems = mw.text.split(mw.ustring.gsub(config.geomask, "SWITCH:", ""), pattern)
local maskLabels = {}
if #maskItems > 1 then
for i, item in ipairs(maskItems) do
table.insert(maskLabels, mw.wikibase.getLabel(item))
end
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
end
end
-- resolve geomask item id (if not using geomask switcher)
if not maskItem then --
local maskType = util.idType(config.geomask)
if maskType == 'item' then
maskItem = config.geomask
elseif maskType == "property" then
maskItem = util.relatedEntity(wikidataId, config.geomask)
end
end
-- if asking for shape or line from Wikidata
-- and if Wikidata actually has shape/line data (wikidataProvidesGeo=true)
-- and if no geomask
-- and if zoom not explicitly set
-- and if the object size inferred from its type is not too small
-- then let Kartographer "take over" zoom
if (showLine or showShape) and wikidataProvidesGeo and not maskItem
and not config.zoom and not (config.type and tinyType[config.type]) then
args.zoom = nil
end
if not maskItem and not showShape and not showLine and not showMarker then
return false, util.trackAndWarn('Pages using infobox mapframe with no geometry','No geometry specified for mapframe')
end
-- Keep track of arg numbering
local argNumber = ''
local function incrementArgNumber()
if argNumber == '' then
argNumber = 2
else
argNumber = argNumber + 1
end
end
-- Geomask
if maskItem then
args["type"..argNumber] = "shape-inverse"
args["id"..argNumber] = maskItem
args["stroke-width"..argNumber] = config["geomask-stroke-width"] or DEFAULT_GEOMASK_STROKE_WIDTH
args["stroke-color"..argNumber] = config["geomask-stroke-color"] or config["geomask-stroke-colour"] or DEFAULT_GEOMASK_STROKE_COLOR
args["fill"..argNumber] = config["geomask-fill"] or DEFAULT_GEOMASK_FILL
args["fill-opacity"..argNumber] = config["geomask-fill-opacity"] or DEFAULT_SHAPE_FILL_OPACITY
-- Let kartographer determine zoom and position, unless it is explicitly set in config
if not config.zoom and not config.switcher then
args.zoom = nil
args["frame-coord"] = nil
args["frame-lat"] = nil
args["frame-long"] = nil
local maskArea = util.getStatementValue( util.getBestStatement(maskItem, 'P2046') )
end
incrementArgNumber()
-- Hack to fix phab:T255932
if not args.zoom then
args["type"..argNumber] = "line"
args["id"..argNumber] = maskItem
args["stroke-width"..argNumber] = 0
incrementArgNumber()
end
end
-- Shape (or shape-inverse)
if showShape then
args["type"..argNumber] = shapeType
if hasGeoshape and not hasOsmRelationId then
args["from"..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, 'P3896') ), 6)
elseif config.id then
args["id"..argNumber] = config.id
end
args["stroke-width"..argNumber] = config["shape-stroke-width"] or config["stroke-width"] or DEFAULT_SHAPE_STROKE_WIDTH
args["stroke-color"..argNumber] = config["shape-stroke-color"] or config["shape-stroke-colour"] or config["stroke-color"] or config["stroke-colour"] or DEFAULT_SHAPE_STROKE_COLOR
args["fill"..argNumber] = config["shape-fill"] or DEFAULT_SHAPE_FILL
args["fill-opacity"..argNumber] = config["shape-fill-opacity"] or DEFAULT_SHAPE_FILL_OPACITY
incrementArgNumber()
end
-- Line
if showLine then
args["type"..argNumber] = "line"
if hasGeoshape and not hasOsmRelationId then
args["from"..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, 'P3896') ), 6)
elseif config.id then
args["id"..argNumber] = config.id
end
args["stroke-width"..argNumber] = config["line-stroke-width"] or config["stroke-width"] or DEFAULT_LINE_STROKE_WIDTH
args["stroke-color"..argNumber] = config["line-stroke-color"] or config["line-stroke-colour"] or config["stroke-color"] or config["stroke-colour"] or DEFAULT_LINE_STROKE_COLOR
incrementArgNumber()
end
-- Point marker
if showMarker then
args["type"..argNumber] = "point"
if config.id then args["id"..argNumber] = config.id end
if config.coord then args["coord"..argNumber] = config.coord end
if config.marker then args["marker"..argNumber] = config.marker end
args["marker-color"..argNumber] = config["marker-color"] or config["marker-colour"] or DEFAULT_MARKER_COLOR
incrementArgNumber()
end
-- if Wikidata doesn't link to OSM and the map has no mask or point,
-- then center the map on the coordinates either from the infobox or from wikidata
if not maskItem and not showMarker and not wikidataProvidesGeo then
if config.coord then
args["frame-coord"] = args["frame-coord"] or config.coord
else
args["frame-lat"] = args["frame-lat"] or wdCoordinates.latitude
args["frame-long"] = args["frame-long"] or wdCoordinates.longitude
end
tracking = tracking..util.trackAndWarn('Pages using infobox mapframe with forced centering')
end
-- protect against nil frame arguments
args["frame-coord"] = args["frame-coord"] or ""
args["frame-lat"] = args["frame-lat"] or ""
args["frame-long"] = args["frame-long"] or ""
local mapframe = args.switch and mf.multi(args) or mf._main(args)
tracking = tracking..((showLine or showShape) and not wikidataProvidesGeo
and util.trackAndWarn('Pages using infobox mapframe without shape links in Wikidata')
or '')
return true, mapframe.. tracking
end
-- Entry points
p.main = function(frame)
local parent = frame.getParent(frame)
local parentArgs = parent.args
local _, mapframe = p._main(parentArgs)
return frame:preprocess(mapframe)
end
p.auto = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("auto should not autorun")
end
local args = util.argsFromAuto(frame)
if args.custom then
return frame:preprocess(util.parseCustomWikitext(args.custom))
end
local _, mapframe = p._main(args)
return frame:preprocess(mapframe)
end
p.autocaption = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("autocaption should not autorun")
end
local args = util.argsFromAuto(frame)
local caption = p._caption(args)
return caption
end
p.autoWithCaption = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("autoWithCaption should not autorun")
end
local args = util.argsFromAuto(frame)
local wikitext
local caption
local ok
if args.custom then
ok = true
wikitext = util.parseCustomWikitext(args.custom)
else
ok, wikitext = p._main(args)
end
if not ok then return wikitext end
wikitext = frame:preprocess(wikitext)
caption = p._caption(args)
local data = mw.html.create():wikitext(wikitext)
data:tag('div')
:addClass('infobox-caption')
:cssText(args.captionstyle)
:wikitext(caption)
return tostring(data)
end
return p
875oxmrlaiy3xr3n98jl2ndg6rcmzou
124176
124175
2026-11-09T20:20:38Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Infobox_mapframe]]
124175
Scribunto
text/plain
local mf = require('Module:Mapframe')
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local infoboxImage = require('Module:InfoboxImage').InfoboxImage
-- Defaults
local DEFAULT_FRAME_WIDTH = "270"
local DEFAULT_FRAME_HEIGHT = "200"
local DEFAULT_ZOOM = 10
local DEFAULT_GEOMASK_STROKE_WIDTH = "1"
local DEFAULT_GEOMASK_STROKE_COLOR = "#777777"
local DEFAULT_GEOMASK_FILL = "#888888"
local DEFAULT_GEOMASK_FILL_OPACITY = "0.25"
local DEFAULT_SHAPE_STROKE_WIDTH = "2"
local DEFAULT_SHAPE_STROKE_COLOR = "#FF0000"
local DEFAULT_SHAPE_FILL = "#606060"
local DEFAULT_SHAPE_FILL_OPACITY = "0.1"
local DEFAULT_LINE_STROKE_WIDTH = "5"
local DEFAULT_LINE_STROKE_COLOR = "#FF0000"
local DEFAULT_MARKER_COLOR = "#5E74F3"
local util = {}
function util.noop(info)
local DEFAULT_NOOP_OUTPUT = ""
-- uncomment this when debugging
-- DEFAULT_NOOP_OUTPUT = "debug: mapframe no-op: " .. info
-- mw.log(DEFAULT_NOOP_OUTPUT)
return DEFAULT_NOOP_OUTPUT
end
-- Trim whitespace from args, and remove empty args
function util.trimArgs(argsTable)
local cleanArgs = {}
for key, val in pairs(argsTable) do
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val ~= '' then
cleanArgs[key] = val
end
else
cleanArgs[key] = val
end
end
return cleanArgs
end
function util.getBestStatement(item_id, property_id)
if not(item_id) or not(mw.wikibase.isValidEntityId(item_id)) or not(mw.wikibase.entityExists(item_id)) then
return false
end
local statements = mw.wikibase.getBestStatements(item_id, property_id)
if not statements or #statements == 0 then
return false
end
local hasNoValue = ( statements[1].mainsnak and statements[1].mainsnak.snaktype == 'novalue' )
if hasNoValue then
return false
end
return statements[1]
end
function util.hasWikidataProperty(item_id, property_id)
return util.getBestStatement(item_id, property_id) and true or false
end
function util.getStatementValue(statement)
return statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value or nil
end
function util.relatedEntity(item_id, property_id)
local value = util.getStatementValue( util.getBestStatement(item_id, property_id) )
return value and value.id or false
end
function util.idType(id)
if not id then
return nil
elseif mw.ustring.match(id, "[Pp]%d+") then
return "property"
elseif mw.ustring.match(id, "[Qq]%d+") then
return "item"
else
return nil
end
end
function util.shouldAutoRun(frame)
-- Check if should be running
local pargs = frame.getParent(frame).args
local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or "")) -- true of false or nil
if pargs.coordinates == "{{{coordinates}}}" then explicitlyOn = false end
if type(pargs.coordinates) == 'string' and string.match(pargs.coordinates, 'coord.missing') then explicitlyOn = false end
local onByDefault = (explicitlyOn == nil) and yesno(mw.text.trim(frame.args.onByDefault or ""), false) -- true or false
return explicitlyOn or onByDefault
end
function util.argsFromAuto(frame)
-- Get args from the frame (invoke call) and the parent (template call).
-- Frame arguments are default values which are overridden by parent values
-- when both are present
local args = getArgs(frame, {parentFirst = true})
-- Discard args not prefixed with "mapframe-", remove that prefix from those that remain
local fixedArgs = {}
for name, val in pairs(args) do
local fixedName = string.match(name, "^mapframe%-(.+)$" )
if fixedName then
fixedArgs[fixedName] = val
-- allow coord, coordinates, etc to be unprefixed
elseif name == "coordinates" or name == "coordinate" and not fixedArgs.coord then
fixedArgs.coord = val
-- allow id, qid to be unprefixed, map to id (if not already present)
elseif name == "id" or name == "qid" and not fixedArgs.id then
fixedArgs.id = val
-- allow captionstyle to be unprefixed, for compatibility with [[Module:Infobox]]
elseif name == "captionstyle" and not fixedArgs.captionstyle then
fixedArgs.captionstyle = val
end
end
return fixedArgs
end
function util.parseCustomWikitext(customWikitext)
-- infoboxImage will format an image if given wikitext containing an
-- image, or else pass through the wikitext unmodified
return infoboxImage({
args = {
image = customWikitext
}
})
end
function util.trackAndWarn(trackingCat, warning)
local title = mw.title.getCurrentTitle()
local results = title and title.namespace == 0 and trackingCat and '[[Category:'..trackingCat..']]' or ''
if warning then
local warn = require('Module:If preview')._warning
results = results..warn({warning})
end
return results
end
function util.ternary(flag, other)
other = other or 'other'
flag = flag == 'none' and 'no' or flag
local yesNoOut = yesno(flag,other)
local yes = (yesNoOut == true)
local no = (yesNoOut == false)
return yes, no
end
local p = {}
p._caption = function(args)
if args.caption then
return args.caption
elseif args.switcher then
return util.noop("no caption or switcher")
end
local maskItem
local maskType = util.idType(args.geomask)
if maskType == 'item' then
maskItem = args.geomask
elseif maskType == "property" then
maskItem = util.relatedEntity(args.id or mw.wikibase.getEntityIdForCurrentPage(), args.geomask)
end
local maskItemLabel = maskItem and mw.wikibase.getLabel( maskItem )
return maskItemLabel and "Location in "..maskItemLabel
or util.noop("missing maskItemLabel with type " .. (maskType or "nil") .. " and item " .. (maskItem or "nil"))
end
--A list of types for objects that are too small to allow Kartographer to take over zoom
local tinyType = {
landmark=true,
railwaystation=true,
edu=true,
pass=true,
camera=true
}
p._main = function(_config)
-- accumulate tracking cats
local tracking = ''
-- `config` is the args passed to this module
local config = util.trimArgs(_config)
-- allow alias for config.coord
config.coord = config.coord or config.coordinates
-- Require wikidata item, or specified coords
local wikidataId = config.id or mw.wikibase.getEntityIdForCurrentPage()
if not(wikidataId) and not(config.coord) then
return false, util.trackAndWarn('Pages using infobox mapframe with missing coordinates')
end
-- Require coords (specified or from wikidata), so that map will be centred somewhere
-- (P625 = coordinate location)
local wdCoordinates = util.getStatementValue(util.getBestStatement(wikidataId, 'P625'))
if not (config.coord or wdCoordinates) then
return false, util.trackAndWarn('Pages using infobox mapframe with missing coordinates')
end
-- `args` is the arguments which will be passed to the mapframe module
local args = {}
-- Some defaults/overrides for infobox presentation
args.display = "inline"
args.frame = "yes"
args.plain = "yes"
args["frame-width"] = config["frame-width"] or config.width or DEFAULT_FRAME_WIDTH
args["frame-height"] = config["frame-height"] or config.height or DEFAULT_FRAME_HEIGHT
args["frame-align"] = "center"
args["frame-coord"] = config["frame-coordinates"] or config["frame-coord"]
-- Note: config["coordinates"] or config["coord"] should not be used for the alignment of the frame;
-- see talk page ( https://en.wikipedia.org/wiki/Special:Diff/876492931 )
-- deprecated lat and long parameters
args["frame-lat"] = config["frame-lat"] or config["frame-latitude"]
args["frame-long"] = config["frame-long"] or config["frame-longitude"]
-- if zoom isn't specified from config, first check wikidata
local zoom = config.zoom or util.getStatementValue(util.getBestStatement(wikidataId, 'P6592'))
if not zoom then
-- Calculate zoom from length or area (converted to km or km2)
-- Zoom so that length or area is completely included in mapframe
local getZoom = require('Module:Infobox dim')._zoom
zoom = getZoom({length_km=config.length_km, length_mi=config.length_mi,
width_km=config.width_km, width_mi=config.width_mi,
area_km2=config.area_km2, area_mi2=config.area_mi2,
area_ha=config.area_ha, area_acre=config.area_acre,
type=config.type, population=config.population,
viewport_px=math.min(args["frame-width"],args["frame-height"]),
latitude=wdCoordinates and wdCoordinates.latitude})
end
args.zoom = zoom or DEFAULT_ZOOM
-- Use OSM relation ID if available; otherwise use geoshape if that is available
-- (geoshape is required for defunct entities, which are outside OSM's scope)
local hasOsmRelationId = util.hasWikidataProperty(wikidataId, 'P402') -- P402 is OSM relation ID
local hasGeoshape = util.hasWikidataProperty(wikidataId, 'P3896') -- P3896 is geoshape
local wikidataProvidesGeo = hasOsmRelationId or hasGeoshape
-- determine marker argument value, determine whether to show marker
local forcePoint, suppressPoint = util.ternary(config.point)
local forceMarker, suppressMarker = util.ternary(config.marker,true)
forcePoint = forcePoint or forceMarker
suppressPoint = suppressPoint or suppressMarker
local showMarker = not suppressPoint and (forcePoint or not wikidataProvidesGeo or config.coord)
-- wikidata = "yes" turns on both shape and line
-- wikidata = "no" turns off both shape and line
-- otherwise show both if wikidata provides geo
local forceWikidata, suppressWikidata = util.ternary(config.wikidata)
local showShape = not suppressWikidata and (forceWikidata or wikidataProvidesGeo or not config.coord)
local showLine = showShape
-- determine shape parameter value, determine whether to show or suppress shape
-- also determine whether to invert shape
local forceShape, suppressShape = util.ternary(config.shape)
showShape = wikidataId and not suppressShape and (forceShape or showShape)
local shapeType = config.shape == 'inverse' and 'shape-inverse' or 'shape'
-- determine line parameter value, determine whether to show or suppress line
local forceLine, suppressLine = util.ternary(config.line)
showLine = wikidataId and not suppressLine and (forceLine or showLine)
local maskItem
-- Switcher
if config.switcher == "zooms" then
-- switching between zoom levels
local maxZoom = math.max(tonumber(args.zoom), 3) -- what zoom would have otherwise been (if 3 or more, otherwise 3)
local minZoom = 1 -- completely zoomed out
local midZoom = math.floor((maxZoom + minZoom)/2) -- midway between maxn and min
args.switch = "zoomed in, zoomed midway, zoomed out"
args.zoom = string.format("SWITCH:%d,%d,%d", maxZoom, midZoom, minZoom)
elseif config.switcher == "auto" then
-- switching between P276 and P131 areas with recursive lookup, e.g. item's city,
-- that city's state, and that state's country
args.zoom = nil -- let kartographer determine the zoom
local maskLabels = {}
local maskItems = {}
local maskItemId = util.relatedEntity(wikidataId, "P276") or util.relatedEntity(wikidataId, "P131")
local maskLabel = mw.wikibase.getLabel(maskItemId)
while maskItemId and maskLabel and mw.text.trim(maskLabel) ~= "" do
table.insert(maskLabels, maskLabel)
table.insert(maskItems, maskItemId)
maskItemId = maskItemId and util.relatedEntity(maskItemId, "P131")
maskLabel = maskItemId and mw.wikibase.getLabel(maskItemId)
end
if #maskLabels > 1 then
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
elseif #maskLabels == 1 then
maskItem = maskItemId[1]
end
elseif config.switcher == "geomasks" and config.geomask then
-- switching between items in geomask parameter
args.zoom = nil -- let kartographer determine the zoom
local separator = (mw.ustring.find(config.geomask, "###", 0, true ) and "###") or
(mw.ustring.find(config.geomask, ";", 0, true ) and ";") or ","
local pattern = "%s*"..separator.."%s*"
local maskItems = mw.text.split(mw.ustring.gsub(config.geomask, "SWITCH:", ""), pattern)
local maskLabels = {}
if #maskItems > 1 then
for i, item in ipairs(maskItems) do
table.insert(maskLabels, mw.wikibase.getLabel(item))
end
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
end
end
-- resolve geomask item id (if not using geomask switcher)
if not maskItem then --
local maskType = util.idType(config.geomask)
if maskType == 'item' then
maskItem = config.geomask
elseif maskType == "property" then
maskItem = util.relatedEntity(wikidataId, config.geomask)
end
end
-- if asking for shape or line from Wikidata
-- and if Wikidata actually has shape/line data (wikidataProvidesGeo=true)
-- and if no geomask
-- and if zoom not explicitly set
-- and if the object size inferred from its type is not too small
-- then let Kartographer "take over" zoom
if (showLine or showShape) and wikidataProvidesGeo and not maskItem
and not config.zoom and not (config.type and tinyType[config.type]) then
args.zoom = nil
end
if not maskItem and not showShape and not showLine and not showMarker then
return false, util.trackAndWarn('Pages using infobox mapframe with no geometry','No geometry specified for mapframe')
end
-- Keep track of arg numbering
local argNumber = ''
local function incrementArgNumber()
if argNumber == '' then
argNumber = 2
else
argNumber = argNumber + 1
end
end
-- Geomask
if maskItem then
args["type"..argNumber] = "shape-inverse"
args["id"..argNumber] = maskItem
args["stroke-width"..argNumber] = config["geomask-stroke-width"] or DEFAULT_GEOMASK_STROKE_WIDTH
args["stroke-color"..argNumber] = config["geomask-stroke-color"] or config["geomask-stroke-colour"] or DEFAULT_GEOMASK_STROKE_COLOR
args["fill"..argNumber] = config["geomask-fill"] or DEFAULT_GEOMASK_FILL
args["fill-opacity"..argNumber] = config["geomask-fill-opacity"] or DEFAULT_SHAPE_FILL_OPACITY
-- Let kartographer determine zoom and position, unless it is explicitly set in config
if not config.zoom and not config.switcher then
args.zoom = nil
args["frame-coord"] = nil
args["frame-lat"] = nil
args["frame-long"] = nil
local maskArea = util.getStatementValue( util.getBestStatement(maskItem, 'P2046') )
end
incrementArgNumber()
-- Hack to fix phab:T255932
if not args.zoom then
args["type"..argNumber] = "line"
args["id"..argNumber] = maskItem
args["stroke-width"..argNumber] = 0
incrementArgNumber()
end
end
-- Shape (or shape-inverse)
if showShape then
args["type"..argNumber] = shapeType
if hasGeoshape and not hasOsmRelationId then
args["from"..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, 'P3896') ), 6)
elseif config.id then
args["id"..argNumber] = config.id
end
args["stroke-width"..argNumber] = config["shape-stroke-width"] or config["stroke-width"] or DEFAULT_SHAPE_STROKE_WIDTH
args["stroke-color"..argNumber] = config["shape-stroke-color"] or config["shape-stroke-colour"] or config["stroke-color"] or config["stroke-colour"] or DEFAULT_SHAPE_STROKE_COLOR
args["fill"..argNumber] = config["shape-fill"] or DEFAULT_SHAPE_FILL
args["fill-opacity"..argNumber] = config["shape-fill-opacity"] or DEFAULT_SHAPE_FILL_OPACITY
incrementArgNumber()
end
-- Line
if showLine then
args["type"..argNumber] = "line"
if hasGeoshape and not hasOsmRelationId then
args["from"..argNumber] = string.sub( util.getStatementValue( util.getBestStatement(wikidataId, 'P3896') ), 6)
elseif config.id then
args["id"..argNumber] = config.id
end
args["stroke-width"..argNumber] = config["line-stroke-width"] or config["stroke-width"] or DEFAULT_LINE_STROKE_WIDTH
args["stroke-color"..argNumber] = config["line-stroke-color"] or config["line-stroke-colour"] or config["stroke-color"] or config["stroke-colour"] or DEFAULT_LINE_STROKE_COLOR
incrementArgNumber()
end
-- Point marker
if showMarker then
args["type"..argNumber] = "point"
if config.id then args["id"..argNumber] = config.id end
if config.coord then args["coord"..argNumber] = config.coord end
if config.marker then args["marker"..argNumber] = config.marker end
args["marker-color"..argNumber] = config["marker-color"] or config["marker-colour"] or DEFAULT_MARKER_COLOR
incrementArgNumber()
end
-- if Wikidata doesn't link to OSM and the map has no mask or point,
-- then center the map on the coordinates either from the infobox or from wikidata
if not maskItem and not showMarker and not wikidataProvidesGeo then
if config.coord then
args["frame-coord"] = args["frame-coord"] or config.coord
else
args["frame-lat"] = args["frame-lat"] or wdCoordinates.latitude
args["frame-long"] = args["frame-long"] or wdCoordinates.longitude
end
tracking = tracking..util.trackAndWarn('Pages using infobox mapframe with forced centering')
end
-- protect against nil frame arguments
args["frame-coord"] = args["frame-coord"] or ""
args["frame-lat"] = args["frame-lat"] or ""
args["frame-long"] = args["frame-long"] or ""
local mapframe = args.switch and mf.multi(args) or mf._main(args)
tracking = tracking..((showLine or showShape) and not wikidataProvidesGeo
and util.trackAndWarn('Pages using infobox mapframe without shape links in Wikidata')
or '')
return true, mapframe.. tracking
end
-- Entry points
p.main = function(frame)
local parent = frame.getParent(frame)
local parentArgs = parent.args
local _, mapframe = p._main(parentArgs)
return frame:preprocess(mapframe)
end
p.auto = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("auto should not autorun")
end
local args = util.argsFromAuto(frame)
if args.custom then
return frame:preprocess(util.parseCustomWikitext(args.custom))
end
local _, mapframe = p._main(args)
return frame:preprocess(mapframe)
end
p.autocaption = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("autocaption should not autorun")
end
local args = util.argsFromAuto(frame)
local caption = p._caption(args)
return caption
end
p.autoWithCaption = function(frame)
if not util.shouldAutoRun(frame) then
return util.noop("autoWithCaption should not autorun")
end
local args = util.argsFromAuto(frame)
local wikitext
local caption
local ok
if args.custom then
ok = true
wikitext = util.parseCustomWikitext(args.custom)
else
ok, wikitext = p._main(args)
end
if not ok then return wikitext end
wikitext = frame:preprocess(wikitext)
caption = p._caption(args)
local data = mw.html.create():wikitext(wikitext)
data:tag('div')
:addClass('infobox-caption')
:cssText(args.captionstyle)
:wikitext(caption)
return tostring(data)
end
return p
875oxmrlaiy3xr3n98jl2ndg6rcmzou
Template:Infobox mapframe/doc/parameters
10
29173
124203
119043
2026-10-09T07:19:46Z
en>Joy
0
sorry, that is actually much uglier, i don't think we should do it even if it feels right Undid 2 revisions from [[Special:Diff/1379310623|1379310623]] until [[Special:Diff/1379311084|1379311084]]
124203
wikitext
text/x-wiki
<includeonly>{{navbar|Template:Infobox mapframe/doc/parameters|plain=y|style=float: right;}}</includeonly><nowiki></nowiki>
*Basic {{template link|Infobox mapframe}} parameters:{{#if:{{{noprefix|}}}||<nowiki></nowiki>
**'''mapframe''' – Specify yes or no to show or hide the map, overriding the default. ''Default:'' {{{mapframe|no}}}{{#if:{{{onByDefault|}}}|, ''but also modified by onByDefault''}}
*** Internal ''onByDefault'' parameter: {{{onByDefault|''not specified''}}}
**{{#if:{{{noprefix|}}}||'''mapframe-coordinates''' or '''mapframe-coord''' or}} '''coordinates''' or '''coord''' – Coordinates to use, instead of any on Wikidata. Use the {{template link|Coord}} template, e.g. {{parameter|coord|2={{template link expanded|Coord|12.34|N|56.78|E}}}}. ''Default:'' {{{mapframe-coordinates|{{{mapframe-coord|{{{coordinates|{{{coord|''coordinates from Wikidata [[d:Property:P625]]''}}}}}}}}}}}}
**'''mapframe-caption''' – Caption for the map. ''Default'': {{{mapframe-caption|''blank'' (or if {{parameter|mapframe-geomask}} is set, "{{xt|Location in {{em|geomask's label}}}}")}}}
**'''mapframe-custom''' – Use a custom map instead of the automatic mapframe. Specify either a {{template link expanded|maplink}} template, or another template that generates a mapframe map, or an image name. If used, most mapframe parameters will be ignored. ''Default'': ''not specified''}}
**{{#if:{{{noprefix|}}}|'''id'''|'''mapframe-id''' or '''id''' or '''qid'''}} – Id (Q-number) of Wikidata item to use. ''Default:'' ''item for current page''
**'''{{#if:{{{noprefix|}}}||mapframe-}}wikidata''' – Set to {{mono|yes}} to show all shape/line features from OpenStreetMap. ''Default:'' {{{mapframe-wikidata|''not specified''}}}
*Customise which features are displayed:
**'''{{#if:{{{noprefix|}}}||mapframe-}}point''' – Turn off display of point feature by setting to {{mono|none}}. Force point marker to be displayed by setting to {{mono|on}}. ''Default:'' {{{mapframe-point|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape''' – Turn off display of shape feature by setting to {{mono|none}}. Force display of shape by setting to {{mono|on}}. Use an inverse shape (geomask) instead of a regular shape by setting to {{mono|inverse}}. ''Default:'' {{{mapframe-shape|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}line''' – Turn off display of line feature by setting to {{mono|none}}. Force display of line by setting to {{mono|on}}. ''Default:'' {{{mapframe-line|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask''' – Wikidata item to use as a geomask (everything outside the boundary is shaded darker). Can either be a specific Wikidata item (Q-number), or a property that specifies the item to use (e.g. {{mono|P17}} for {{Wikidata entity link|P17}}, {{mono|P131}} for {{Wikidata entity link|P131}}). ''Default:'' {{{mapframe-geomask|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}switcher''' – set to {{mono|auto}} or {{mono|geomasks}} or {{mono|zooms}} to enable [[Template:Switcher]]-style switching between multiple mapframes. ''Default:'' {{{mapframe-switcher|''not specified''}}}
***{{mono|auto}} – switch geomasks found in {{Wikidata entity link|P276}} and {{Wikidata entity link|P131}} statements on the page's Wikidata item, searching recursively. E.g. an item's city, that city's state, and that state's country.
***{{mono|geomasks}} – switch between the geomasks specified as a comma-separated list of Wikidata items (Q-numbers) in the '''{{#if:{{{noprefix|}}}||mapframe-}}geomask''' parameter
***{{mono|zooms}} – switch between "zoomed in"/"zoomed midway"/"zoomed out", where "zoomed in" is the default zoom (with a minimum of {{mono|3}}), "zoomed out" is {{mono|1}}, and "zoomed midway" is the average
*Other optional parameters:
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-width''' or '''{{#if:{{{noprefix|}}}||mapframe-}}width''' – Frame width. ''Default:'' {{{mapframe-frame-width|270}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-height''' or '''{{#if:{{{noprefix|}}}||mapframe-}}height''' – Frame height. ''Default:'' {{{mapframe-frame-height|200}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape-fill''' – Color used to fill shape features. ''Default:'' {{{mapframe-shape-fill|#606060}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape-fill-opacity''' – Opacity level of shape fill, a number between 0 and 1. ''Default:'' {{{mapframe-shape-fill-opacity|0.1}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}stroke-colour''' – Color of line features, and outlines of shape features. ''Default:'' {{{mapframe-stroke-color|{{{mapframe-stroke-colour|#ff0000}}}}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-colour''' – Color of line features. ''Default:'' {{{mapframe-line-stroke-color|{{{mapframe-line-stroke-colour|#ff0000}}}}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-colour''' – Color of outlines of shape features. ''Default:'' {{{mapframe-shape-stroke-color|{{{mapframe-shape-stroke-colour|#ff0000}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}stroke-width''' – Width of line features, and outlines of shape features. ''Default:'' {{{mapframe-stroke-width|2}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-width''' – Width of outlines of shape features. ''Default:'' {{{mapframe-shape-stroke-width|2}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-width''' – Width of line features. ''Default:'' {{{mapframe-line-stroke-width|5}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}marker''' – Marker symbol to use for coordinates; see [[mw:Help:Extension:Kartographer/Icons]] for options. ''Default:'' {{{mapframe-marker|''not specified (i.e. blank)''}}}
***Can also be set to {{mono|blank}} to override any default marker symbol
**'''{{#if:{{{noprefix|}}}||mapframe-}}marker-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}marker-colour''' – Background color for the marker. ''Default:'' {{{mapframe-marker-color|{{{mapframe-marker-colour|#5E74F3}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-colour''' – Color of outline of geomask shape. ''Default:'' {{{mapframe-geomask-stroke-color|{{{mapframe-geomask-stroke-colour|#555555}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-width''' – Width of outline of geomask shape. ''Default:'' {{{mapframe-geomask-stroke-width|1}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-fill''' – Color used to fill outside geomask features. ''Default:'' {{{mapframe-geomask-fill|#606060}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-fill-opacity''' – Opacity level of fill outside geomask features, a number between 0 and 1. ''Default:'' {{{mapframe-geomask-fill-opacity|0.25}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}zoom''' – Set the zoom level, from "1" (map of earth) to "18" (maximum zoom in), to be used if the zoom level cannot be determined automatically from object length or area. ''Default:'' {{{mapframe-zoom|10}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}length_km {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}length_mi {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}area_km2 {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}area_mi2''' – Determine zoom level by passing in object's length (in kilometres or miles) or area (in square kilometres or square miles). ''Default:'' ''{{{mapframe-length_km|not specified}}} / {{{mapframe-length_mi|not specified}}} / {{{mapframe-area_km2|not specified}}} / {{{mapframe-area_mi2|not specified}}}''
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-coordinates''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-coord''' – Alternate latitude and longitude coordinates for initial placement of map, using {{template link|coord}}. ''Default:'' ''derived from item coordinates''
**'''{{#if:{{{noprefix|}}}||mapframe-}}type''' – Set the type of the object, with the same usage as {{template link|coord}}. ''Default:'' {{{mapframe-type|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}population''' – Set the population, useful with type="city", for {{template link|Infobox dim}}. ''Default:'' {{{mapframe-population|''not specified''}}}
{{#if:{{{deprecated|}}}|<nowiki></nowiki>
*Deprecated parameters
**{{gray|1='''{{#if:{{{noprefix|}}}||mapframe-}}frame-lat''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-latitude'''}} – Alternate latitude coordinate for initial placement of map; default is derived from item coordinates
**{{gray|1='''{{#if:{{{noprefix|}}}||mapframe-}}frame-long''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-longitude'''}} – Alternate longitude coordinate for initial placement of map; default is derived from item coordinates
}}<noinclude>{{Documentation}}</noinclude>
848wzme8ii3ss8czwhghd2yk6dbgcvd
124204
124203
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_mapframe/doc/parameters]]
124203
wikitext
text/x-wiki
<includeonly>{{navbar|Template:Infobox mapframe/doc/parameters|plain=y|style=float: right;}}</includeonly><nowiki></nowiki>
*Basic {{template link|Infobox mapframe}} parameters:{{#if:{{{noprefix|}}}||<nowiki></nowiki>
**'''mapframe''' – Specify yes or no to show or hide the map, overriding the default. ''Default:'' {{{mapframe|no}}}{{#if:{{{onByDefault|}}}|, ''but also modified by onByDefault''}}
*** Internal ''onByDefault'' parameter: {{{onByDefault|''not specified''}}}
**{{#if:{{{noprefix|}}}||'''mapframe-coordinates''' or '''mapframe-coord''' or}} '''coordinates''' or '''coord''' – Coordinates to use, instead of any on Wikidata. Use the {{template link|Coord}} template, e.g. {{parameter|coord|2={{template link expanded|Coord|12.34|N|56.78|E}}}}. ''Default:'' {{{mapframe-coordinates|{{{mapframe-coord|{{{coordinates|{{{coord|''coordinates from Wikidata [[d:Property:P625]]''}}}}}}}}}}}}
**'''mapframe-caption''' – Caption for the map. ''Default'': {{{mapframe-caption|''blank'' (or if {{parameter|mapframe-geomask}} is set, "{{xt|Location in {{em|geomask's label}}}}")}}}
**'''mapframe-custom''' – Use a custom map instead of the automatic mapframe. Specify either a {{template link expanded|maplink}} template, or another template that generates a mapframe map, or an image name. If used, most mapframe parameters will be ignored. ''Default'': ''not specified''}}
**{{#if:{{{noprefix|}}}|'''id'''|'''mapframe-id''' or '''id''' or '''qid'''}} – Id (Q-number) of Wikidata item to use. ''Default:'' ''item for current page''
**'''{{#if:{{{noprefix|}}}||mapframe-}}wikidata''' – Set to {{mono|yes}} to show all shape/line features from OpenStreetMap. ''Default:'' {{{mapframe-wikidata|''not specified''}}}
*Customise which features are displayed:
**'''{{#if:{{{noprefix|}}}||mapframe-}}point''' – Turn off display of point feature by setting to {{mono|none}}. Force point marker to be displayed by setting to {{mono|on}}. ''Default:'' {{{mapframe-point|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape''' – Turn off display of shape feature by setting to {{mono|none}}. Force display of shape by setting to {{mono|on}}. Use an inverse shape (geomask) instead of a regular shape by setting to {{mono|inverse}}. ''Default:'' {{{mapframe-shape|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}line''' – Turn off display of line feature by setting to {{mono|none}}. Force display of line by setting to {{mono|on}}. ''Default:'' {{{mapframe-line|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask''' – Wikidata item to use as a geomask (everything outside the boundary is shaded darker). Can either be a specific Wikidata item (Q-number), or a property that specifies the item to use (e.g. {{mono|P17}} for {{Wikidata entity link|P17}}, {{mono|P131}} for {{Wikidata entity link|P131}}). ''Default:'' {{{mapframe-geomask|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}switcher''' – set to {{mono|auto}} or {{mono|geomasks}} or {{mono|zooms}} to enable [[Template:Switcher]]-style switching between multiple mapframes. ''Default:'' {{{mapframe-switcher|''not specified''}}}
***{{mono|auto}} – switch geomasks found in {{Wikidata entity link|P276}} and {{Wikidata entity link|P131}} statements on the page's Wikidata item, searching recursively. E.g. an item's city, that city's state, and that state's country.
***{{mono|geomasks}} – switch between the geomasks specified as a comma-separated list of Wikidata items (Q-numbers) in the '''{{#if:{{{noprefix|}}}||mapframe-}}geomask''' parameter
***{{mono|zooms}} – switch between "zoomed in"/"zoomed midway"/"zoomed out", where "zoomed in" is the default zoom (with a minimum of {{mono|3}}), "zoomed out" is {{mono|1}}, and "zoomed midway" is the average
*Other optional parameters:
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-width''' or '''{{#if:{{{noprefix|}}}||mapframe-}}width''' – Frame width. ''Default:'' {{{mapframe-frame-width|270}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-height''' or '''{{#if:{{{noprefix|}}}||mapframe-}}height''' – Frame height. ''Default:'' {{{mapframe-frame-height|200}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape-fill''' – Color used to fill shape features. ''Default:'' {{{mapframe-shape-fill|#606060}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}shape-fill-opacity''' – Opacity level of shape fill, a number between 0 and 1. ''Default:'' {{{mapframe-shape-fill-opacity|0.1}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}stroke-colour''' – Color of line features, and outlines of shape features. ''Default:'' {{{mapframe-stroke-color|{{{mapframe-stroke-colour|#ff0000}}}}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-colour''' – Color of line features. ''Default:'' {{{mapframe-line-stroke-color|{{{mapframe-line-stroke-colour|#ff0000}}}}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-colour''' – Color of outlines of shape features. ''Default:'' {{{mapframe-shape-stroke-color|{{{mapframe-shape-stroke-colour|#ff0000}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}stroke-width''' – Width of line features, and outlines of shape features. ''Default:'' {{{mapframe-stroke-width|2}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}shape-stroke-width''' – Width of outlines of shape features. ''Default:'' {{{mapframe-shape-stroke-width|2}}}
***'''{{#if:{{{noprefix|}}}||mapframe-}}line-stroke-width''' – Width of line features. ''Default:'' {{{mapframe-line-stroke-width|5}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}marker''' – Marker symbol to use for coordinates; see [[mw:Help:Extension:Kartographer/Icons]] for options. ''Default:'' {{{mapframe-marker|''not specified (i.e. blank)''}}}
***Can also be set to {{mono|blank}} to override any default marker symbol
**'''{{#if:{{{noprefix|}}}||mapframe-}}marker-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}marker-colour''' – Background color for the marker. ''Default:'' {{{mapframe-marker-color|{{{mapframe-marker-colour|#5E74F3}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-color''' or '''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-colour''' – Color of outline of geomask shape. ''Default:'' {{{mapframe-geomask-stroke-color|{{{mapframe-geomask-stroke-colour|#555555}}}}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-stroke-width''' – Width of outline of geomask shape. ''Default:'' {{{mapframe-geomask-stroke-width|1}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-fill''' – Color used to fill outside geomask features. ''Default:'' {{{mapframe-geomask-fill|#606060}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}geomask-fill-opacity''' – Opacity level of fill outside geomask features, a number between 0 and 1. ''Default:'' {{{mapframe-geomask-fill-opacity|0.25}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}zoom''' – Set the zoom level, from "1" (map of earth) to "18" (maximum zoom in), to be used if the zoom level cannot be determined automatically from object length or area. ''Default:'' {{{mapframe-zoom|10}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}length_km {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}length_mi {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}area_km2 {{nobold|or}} {{#if:{{{noprefix|}}}||mapframe-}}area_mi2''' – Determine zoom level by passing in object's length (in kilometres or miles) or area (in square kilometres or square miles). ''Default:'' ''{{{mapframe-length_km|not specified}}} / {{{mapframe-length_mi|not specified}}} / {{{mapframe-area_km2|not specified}}} / {{{mapframe-area_mi2|not specified}}}''
**'''{{#if:{{{noprefix|}}}||mapframe-}}frame-coordinates''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-coord''' – Alternate latitude and longitude coordinates for initial placement of map, using {{template link|coord}}. ''Default:'' ''derived from item coordinates''
**'''{{#if:{{{noprefix|}}}||mapframe-}}type''' – Set the type of the object, with the same usage as {{template link|coord}}. ''Default:'' {{{mapframe-type|''not specified''}}}
**'''{{#if:{{{noprefix|}}}||mapframe-}}population''' – Set the population, useful with type="city", for {{template link|Infobox dim}}. ''Default:'' {{{mapframe-population|''not specified''}}}
{{#if:{{{deprecated|}}}|<nowiki></nowiki>
*Deprecated parameters
**{{gray|1='''{{#if:{{{noprefix|}}}||mapframe-}}frame-lat''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-latitude'''}} – Alternate latitude coordinate for initial placement of map; default is derived from item coordinates
**{{gray|1='''{{#if:{{{noprefix|}}}||mapframe-}}frame-long''' or '''{{#if:{{{noprefix|}}}||mapframe-}}frame-longitude'''}} – Alternate longitude coordinate for initial placement of map; default is derived from item coordinates
}}<noinclude>{{Documentation}}</noinclude>
848wzme8ii3ss8czwhghd2yk6dbgcvd
Module:Check for unknown parameters
828
44760
124171
116803
2026-10-10T08:31:06Z
en>Johnuniq
0
implement edit request from [[User:Zackmann08]] to remove 'coord' from default in mapframe_params table per [[Special:PermanentLink/1379472561#Protected edit request on 2 October 2026|talk permalink]]
124171
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
require ('strict');
local p = {}
local pushpin_map_params = {
'coordinates',
'pushpin_caption',
'pushpin_relief',
'pushpin_label',
'pushpin_label_position',
'pushpin_label_size',
'pushpin_map',
'pushpin_mark',
'pushpin_mark_size',
'pushpin_alt',
'pushpin_background',
'pushpin_map_size'
}
local mapframe_params = {
'coordinates',
'id',
'qid',
'mapframe',
'mapframe-area_km2',
'mapframe-area_mi2',
'mapframe-caption',
'mapframe-coord',
'mapframe-coordinates',
'mapframe-custom',
'mapframe-frame-coord',
'mapframe-frame-coordinates',
'mapframe-frame-height',
'mapframe-frame-width',
'mapframe-geomask',
'mapframe-geomask-fill',
'mapframe-geomask-fill-opacity',
'mapframe-geomask-stroke-color',
'mapframe-geomask-stroke-colour',
'mapframe-geomask-stroke-width',
'mapframe-height',
'mapframe-id',
'mapframe-length_km',
'mapframe-length_mi',
'mapframe-line',
'mapframe-line-stroke-color',
'mapframe-line-stroke-colour',
'mapframe-marker',
'mapframe-marker-color',
'mapframe-marker-colour',
'mapframe-point',
'mapframe-population',
'mapframe-shape',
'mapframe-shape-fill',
'mapframe-shape-fill-opacity',
'mapframe-shape-stroke-color',
'mapframe-shape-stroke-colour',
'mapframe-stroke-color',
'mapframe-stroke-colour',
'mapframe-stroke-width',
'mapframe-switcher',
'mapframe-type',
'mapframe-width',
'mapframe-wikidata',
'mapframe-zoom'
}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '<' .. tag .. '>...</' .. tag .. '>')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
if isnotempty(args['mapframe_args']) then
for _, v in ipairs(mapframe_params) do
knownargs[v] = 1
end
end
if isnotempty(args['pushpin_map_args']) then
for _, v in ipairs(pushpin_map_params) do
knownargs[v] = 1
end
end
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview_text == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
return table.concat(res)
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
return p
pn8nxt3tzckni7xgmqn4wy1q5b5c05s
124172
124171
2026-11-09T20:20:38Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Check_for_unknown_parameters]]
124171
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
require ('strict');
local p = {}
local pushpin_map_params = {
'coordinates',
'pushpin_caption',
'pushpin_relief',
'pushpin_label',
'pushpin_label_position',
'pushpin_label_size',
'pushpin_map',
'pushpin_mark',
'pushpin_mark_size',
'pushpin_alt',
'pushpin_background',
'pushpin_map_size'
}
local mapframe_params = {
'coordinates',
'id',
'qid',
'mapframe',
'mapframe-area_km2',
'mapframe-area_mi2',
'mapframe-caption',
'mapframe-coord',
'mapframe-coordinates',
'mapframe-custom',
'mapframe-frame-coord',
'mapframe-frame-coordinates',
'mapframe-frame-height',
'mapframe-frame-width',
'mapframe-geomask',
'mapframe-geomask-fill',
'mapframe-geomask-fill-opacity',
'mapframe-geomask-stroke-color',
'mapframe-geomask-stroke-colour',
'mapframe-geomask-stroke-width',
'mapframe-height',
'mapframe-id',
'mapframe-length_km',
'mapframe-length_mi',
'mapframe-line',
'mapframe-line-stroke-color',
'mapframe-line-stroke-colour',
'mapframe-marker',
'mapframe-marker-color',
'mapframe-marker-colour',
'mapframe-point',
'mapframe-population',
'mapframe-shape',
'mapframe-shape-fill',
'mapframe-shape-fill-opacity',
'mapframe-shape-stroke-color',
'mapframe-shape-stroke-colour',
'mapframe-stroke-color',
'mapframe-stroke-colour',
'mapframe-stroke-width',
'mapframe-switcher',
'mapframe-type',
'mapframe-width',
'mapframe-wikidata',
'mapframe-zoom'
}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and s:match('%S')
end
local function clean(text)
-- Return text cleaned for display and truncated if too long.
-- Strip markers are replaced with dummy text representing the original wikitext.
local pos, truncated
local function truncate(text)
if truncated then
return ''
end
if mw.ustring.len(text) > 25 then
truncated = true
text = mw.ustring.sub(text, 1, 25) .. '...'
end
return mw.text.nowiki(text)
end
local parts = {}
for before, tag, remainder in text:gmatch('([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()') do
pos = remainder
table.insert(parts, truncate(before) .. '<' .. tag .. '>...</' .. tag .. '>')
end
table.insert(parts, truncate(text:sub(pos or 1)))
return table.concat(parts)
end
function p._check(args, pargs)
if type(args) ~= "table" or type(pargs) ~= "table" then
-- TODO: error handling
return
end
-- create the list of known args, regular expressions, and the return string
local knownargs = {}
if isnotempty(args['mapframe_args']) then
for _, v in ipairs(mapframe_params) do
knownargs[v] = 1
end
end
if isnotempty(args['pushpin_map_args']) then
for _, v in ipairs(pushpin_map_params) do
knownargs[v] = 1
end
end
local regexps = {}
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
-- loop over the parent args, and make sure they are on the list
local ignoreblank = isnotempty(args['ignoreblank'])
local showblankpos = isnotempty(args['showblankpositional'])
local values = {}
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
table.insert(values, clean(k))
end
elseif type(k) == 'number' and knownargs[tostring(k)] == nil then
local knownflag = false
for _, regexp in ipairs(regexps) do
if mw.ustring.match(tostring(k), regexp) then
knownflag = true
break
end
end
if not knownflag and ( showblankpos or isnotempty(v) ) then
table.insert(values, k .. ' = ' .. clean(v))
end
end
end
-- add results to the output tables
local res = {}
if #values > 0 then
local unknown_text = args['unknown'] or 'Found _VALUE_, '
if mw.getCurrentFrame():preprocess( "{{REVISIONID}}" ) == "" then
local preview_text = args['preview']
if isnotempty(preview_text) then
preview_text = require('Module:If preview')._warning({preview_text})
elseif preview_text == nil then
preview_text = unknown_text
end
unknown_text = preview_text
end
for _, v in pairs(values) do
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
if v == '' then v = ' ' end
-- avoid error with v = 'example%2' ("invalid capture index")
local r = unknown_text:gsub('_VALUE_', {_VALUE_ = v})
table.insert(res, r)
end
end
return table.concat(res)
end
function p.check(frame)
local args = frame.args
local pargs = frame:getParent().args
return p._check(args, pargs)
end
return p
pn8nxt3tzckni7xgmqn4wy1q5b5c05s
Template:Hlist/styles.css
10
44764
124209
116733
2026-09-12T00:40:45Z
en>BD2412
0
BD2412 moved page [[Template:Horizontal list/styles.css]] to [[Template:Hlist/styles.css]] without leaving a redirect: move back for now
116732
sanitized-css
text/css
/* {{pp-template}} */
/*
* hlist styles are defined in core and Minerva and differ in Minerva. The
* current definitions here (2023-01-01) are sufficient to override Minerva
* without use of the hlist-separated class. The most problematic styles were
* related to margin, padding, and the bullet. Check files listed at
* [[MediaWiki talk:Common.css/to do#hlist-separated]]
*/
/*
* TODO: When the majority of readership supports it (or some beautiful world
* in which grade C support is above the minimum threshold), use :is()
*/
.hlist dl,
.hlist ol,
.hlist ul {
margin: 0;
padding: 0;
}
/* Display list items inline */
.hlist dd,
.hlist dt,
.hlist li {
/*
* don't trust the note that says margin doesn't work with inline
* removing margin: 0 makes dds have margins again
* We also want to reset margin-right in Minerva
*/
margin: 0;
display: inline;
}
/* Display requested top-level lists inline */
.hlist.inline,
.hlist.inline dl,
.hlist.inline ol,
.hlist.inline ul,
/* Display nested lists inline */
.hlist dl dl,
.hlist dl ol,
.hlist dl ul,
.hlist ol dl,
.hlist ol ol,
.hlist ol ul,
.hlist ul dl,
.hlist ul ol,
.hlist ul ul {
display: inline;
}
/* Hide empty list items */
.hlist .mw-empty-li {
display: none;
}
/* TODO: :not() can maybe be used here to remove the later rule. naive test
* seems to work. more testing needed. like so:
*.hlist dt:not(:last-child)::after {
* content: ": ";
*}
*.hlist dd:not(:last-child)::after,
*.hlist li:not(:last-child)::after {
* content: " · ";
* font-weight: bold;
*}
*/
/* Generate interpuncts */
.hlist dt::after {
content: ": ";
}
.hlist dd::after,
.hlist li::after {
content: "\a0· ";
font-weight: bold;
}
.hlist dd:last-child::after,
.hlist dt:last-child::after,
.hlist li:last-child::after {
content: none;
}
/* Add parentheses around nested lists */
.hlist dd dd:first-child::before,
.hlist dd dt:first-child::before,
.hlist dd li:first-child::before,
.hlist dt dd:first-child::before,
.hlist dt dt:first-child::before,
.hlist dt li:first-child::before,
.hlist li dd:first-child::before,
.hlist li dt:first-child::before,
.hlist li li:first-child::before {
content: " (";
font-weight: normal;
}
.hlist dd dd:last-child::after,
.hlist dd dt:last-child::after,
.hlist dd li:last-child::after,
.hlist dt dd:last-child::after,
.hlist dt dt:last-child::after,
.hlist dt li:last-child::after,
.hlist li dd:last-child::after,
.hlist li dt:last-child::after,
.hlist li li:last-child::after {
content: ")";
font-weight: normal;
}
/* Put ordinals in front of ordered list items */
.hlist ol {
counter-reset: listitem;
}
.hlist ol > li {
counter-increment: listitem;
}
.hlist ol > li::before {
content: " " counter(listitem) "\a0";
}
.hlist dd ol > li:first-child::before,
.hlist dt ol > li:first-child::before,
.hlist li ol > li:first-child::before {
content: " (" counter(listitem) "\a0";
}
c4a9gdxc068l0us4sz11634bne7iv2z
124210
124209
2026-11-09T20:20:43Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Hlist/styles.css]]
116732
sanitized-css
text/css
/* {{pp-template}} */
/*
* hlist styles are defined in core and Minerva and differ in Minerva. The
* current definitions here (2023-01-01) are sufficient to override Minerva
* without use of the hlist-separated class. The most problematic styles were
* related to margin, padding, and the bullet. Check files listed at
* [[MediaWiki talk:Common.css/to do#hlist-separated]]
*/
/*
* TODO: When the majority of readership supports it (or some beautiful world
* in which grade C support is above the minimum threshold), use :is()
*/
.hlist dl,
.hlist ol,
.hlist ul {
margin: 0;
padding: 0;
}
/* Display list items inline */
.hlist dd,
.hlist dt,
.hlist li {
/*
* don't trust the note that says margin doesn't work with inline
* removing margin: 0 makes dds have margins again
* We also want to reset margin-right in Minerva
*/
margin: 0;
display: inline;
}
/* Display requested top-level lists inline */
.hlist.inline,
.hlist.inline dl,
.hlist.inline ol,
.hlist.inline ul,
/* Display nested lists inline */
.hlist dl dl,
.hlist dl ol,
.hlist dl ul,
.hlist ol dl,
.hlist ol ol,
.hlist ol ul,
.hlist ul dl,
.hlist ul ol,
.hlist ul ul {
display: inline;
}
/* Hide empty list items */
.hlist .mw-empty-li {
display: none;
}
/* TODO: :not() can maybe be used here to remove the later rule. naive test
* seems to work. more testing needed. like so:
*.hlist dt:not(:last-child)::after {
* content: ": ";
*}
*.hlist dd:not(:last-child)::after,
*.hlist li:not(:last-child)::after {
* content: " · ";
* font-weight: bold;
*}
*/
/* Generate interpuncts */
.hlist dt::after {
content: ": ";
}
.hlist dd::after,
.hlist li::after {
content: "\a0· ";
font-weight: bold;
}
.hlist dd:last-child::after,
.hlist dt:last-child::after,
.hlist li:last-child::after {
content: none;
}
/* Add parentheses around nested lists */
.hlist dd dd:first-child::before,
.hlist dd dt:first-child::before,
.hlist dd li:first-child::before,
.hlist dt dd:first-child::before,
.hlist dt dt:first-child::before,
.hlist dt li:first-child::before,
.hlist li dd:first-child::before,
.hlist li dt:first-child::before,
.hlist li li:first-child::before {
content: " (";
font-weight: normal;
}
.hlist dd dd:last-child::after,
.hlist dd dt:last-child::after,
.hlist dd li:last-child::after,
.hlist dt dd:last-child::after,
.hlist dt dt:last-child::after,
.hlist dt li:last-child::after,
.hlist li dd:last-child::after,
.hlist li dt:last-child::after,
.hlist li li:last-child::after {
content: ")";
font-weight: normal;
}
/* Put ordinals in front of ordered list items */
.hlist ol {
counter-reset: listitem;
}
.hlist ol > li {
counter-increment: listitem;
}
.hlist ol > li::before {
content: " " counter(listitem) "\a0";
}
.hlist dd ol > li:first-child::before,
.hlist dt ol > li:first-child::before,
.hlist li ol > li:first-child::before {
content: " (" counter(listitem) "\a0";
}
c4a9gdxc068l0us4sz11634bne7iv2z
Module:List
828
44968
124173
116748
2026-09-12T00:43:13Z
en>JJMC89
0
move was reverted
124173
Scribunto
text/plain
local libUtil = require('libraryUtil')
local checkType = libUtil.checkType
local mTableTools = require('Module:TableTools')
local p = {}
local listTypes = {
['bulleted'] = true,
['unbulleted'] = true,
['horizontal'] = true,
['ordered'] = true,
['horizontal_ordered'] = true
}
function p.makeListData(listType, args)
-- Constructs a data table to be passed to p.renderList.
local data = {}
-- Classes and TemplateStyles
data.classes = {}
data.templatestyles = ''
if listType == 'horizontal' or listType == 'horizontal_ordered' then
table.insert(data.classes, 'hlist')
data.templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Hlist/styles.css' }
}
elseif listType == 'unbulleted' then
table.insert(data.classes, 'plainlist')
data.templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Plainlist/styles.css' }
}
end
table.insert(data.classes, args.class)
-- Main div style
data.style = args.style
-- Indent for horizontal lists
if listType == 'horizontal' or listType == 'horizontal_ordered' then
local indent = tonumber(args.indent)
indent = indent and indent * 1.6 or 0
if indent > 0 then
data.marginLeft = indent .. 'em'
end
end
-- List style types for ordered lists
-- This could be "1, 2, 3", "a, b, c", or a number of others. The list style
-- type is either set by the "type" attribute or the "list-style-type" CSS
-- property.
if listType == 'ordered' or listType == 'horizontal_ordered' then
data.listStyleType = args.list_style_type or args['list-style-type']
data.type = args['type']
-- Detect invalid type attributes and attempt to convert them to
-- list-style-type CSS properties.
if data.type
and not data.listStyleType
and not tostring(data.type):find('^%s*[1AaIi]%s*$')
then
data.listStyleType = data.type
data.type = nil
end
end
-- List tag type
if listType == 'ordered' or listType == 'horizontal_ordered' then
data.listTag = 'ol'
else
data.listTag = 'ul'
end
-- Start number for ordered lists
data.start = args.start
if listType == 'horizontal_ordered' then
-- Apply fix to get start numbers working with horizontal ordered lists.
local startNum = tonumber(data.start)
if startNum then
data.counterReset = 'listitem ' .. tostring(startNum - 1)
end
end
-- List style
-- ul_style and ol_style are included for backwards compatibility. No
-- distinction is made for ordered or unordered lists.
data.listStyle = args.list_style
-- List items
-- li_style is included for backwards compatibility. item_style was included
-- to be easier to understand for non-coders.
data.itemStyle = args.item_style or args.li_style
data.items = {}
for _, num in ipairs(mTableTools.numKeys(args)) do
local item = {}
item.content = args[num]
item.style = args['item' .. tostring(num) .. '_style']
or args['item_style' .. tostring(num)]
item.value = args['item' .. tostring(num) .. '_value']
or args['item_value' .. tostring(num)]
table.insert(data.items, item)
end
return data
end
function p.renderList(data)
-- Renders the list HTML.
-- Return the blank string if there are no list items.
if type(data.items) ~= 'table' or #data.items < 1 then
return ''
end
-- Render the main div tag.
local root = mw.html.create('div')
for _, class in ipairs(data.classes or {}) do
root:addClass(class)
end
root:css{['margin-left'] = data.marginLeft}
if data.style then
root:cssText(data.style)
end
-- Render the list tag.
local list = root:tag(data.listTag or 'ul')
list
:attr{start = data.start, type = data.type}
:css{
['counter-reset'] = data.counterReset,
['list-style-type'] = data.listStyleType
}
if data.listStyle then
list:cssText(data.listStyle)
end
-- Render the list items
for _, t in ipairs(data.items or {}) do
local item = list:tag('li')
if data.itemStyle then
item:cssText(data.itemStyle)
end
if t.style then
item:cssText(t.style)
end
item
:attr{value = t.value}
:wikitext(t.content)
end
return data.templatestyles .. tostring(root)
end
function p.makeList(listType, args)
if not listType or not listTypes[listType] then
error(string.format(
"bad argument #1 to 'makeList' ('%s' is not a valid list type)",
tostring(listType)
), 2)
end
checkType('makeList', 2, args, 'table')
local data = p.makeListData(listType, args)
local list = p.renderList(data)
return list
end
for listType in pairs(listTypes) do
p[listType] = function (frame)
local mArguments = require('Module:Arguments')
local origArgs = mArguments.getArgs(frame, {
frameOnly = ((frame and frame.args and frame.args.frameonly or '') ~= ''),
valueFunc = function (key, value)
if not value or not mw.ustring.find(value, '%S') then return nil end
if mw.ustring.find(value, '^%s*[%*#;:]') then
return value
else
return value:match('^%s*(.-)%s*$')
end
return nil
end
})
-- Copy all the arguments to a new table, for faster indexing.
local args = {}
for k, v in pairs(origArgs) do
args[k] = v
end
return p.makeList(listType, args)
end
end
return p
lyheh2t5yqhjixmg8vlktt3t9sq2ewi
124174
124173
2026-11-09T20:20:38Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:List]]
124173
Scribunto
text/plain
local libUtil = require('libraryUtil')
local checkType = libUtil.checkType
local mTableTools = require('Module:TableTools')
local p = {}
local listTypes = {
['bulleted'] = true,
['unbulleted'] = true,
['horizontal'] = true,
['ordered'] = true,
['horizontal_ordered'] = true
}
function p.makeListData(listType, args)
-- Constructs a data table to be passed to p.renderList.
local data = {}
-- Classes and TemplateStyles
data.classes = {}
data.templatestyles = ''
if listType == 'horizontal' or listType == 'horizontal_ordered' then
table.insert(data.classes, 'hlist')
data.templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Hlist/styles.css' }
}
elseif listType == 'unbulleted' then
table.insert(data.classes, 'plainlist')
data.templatestyles = mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = 'Plainlist/styles.css' }
}
end
table.insert(data.classes, args.class)
-- Main div style
data.style = args.style
-- Indent for horizontal lists
if listType == 'horizontal' or listType == 'horizontal_ordered' then
local indent = tonumber(args.indent)
indent = indent and indent * 1.6 or 0
if indent > 0 then
data.marginLeft = indent .. 'em'
end
end
-- List style types for ordered lists
-- This could be "1, 2, 3", "a, b, c", or a number of others. The list style
-- type is either set by the "type" attribute or the "list-style-type" CSS
-- property.
if listType == 'ordered' or listType == 'horizontal_ordered' then
data.listStyleType = args.list_style_type or args['list-style-type']
data.type = args['type']
-- Detect invalid type attributes and attempt to convert them to
-- list-style-type CSS properties.
if data.type
and not data.listStyleType
and not tostring(data.type):find('^%s*[1AaIi]%s*$')
then
data.listStyleType = data.type
data.type = nil
end
end
-- List tag type
if listType == 'ordered' or listType == 'horizontal_ordered' then
data.listTag = 'ol'
else
data.listTag = 'ul'
end
-- Start number for ordered lists
data.start = args.start
if listType == 'horizontal_ordered' then
-- Apply fix to get start numbers working with horizontal ordered lists.
local startNum = tonumber(data.start)
if startNum then
data.counterReset = 'listitem ' .. tostring(startNum - 1)
end
end
-- List style
-- ul_style and ol_style are included for backwards compatibility. No
-- distinction is made for ordered or unordered lists.
data.listStyle = args.list_style
-- List items
-- li_style is included for backwards compatibility. item_style was included
-- to be easier to understand for non-coders.
data.itemStyle = args.item_style or args.li_style
data.items = {}
for _, num in ipairs(mTableTools.numKeys(args)) do
local item = {}
item.content = args[num]
item.style = args['item' .. tostring(num) .. '_style']
or args['item_style' .. tostring(num)]
item.value = args['item' .. tostring(num) .. '_value']
or args['item_value' .. tostring(num)]
table.insert(data.items, item)
end
return data
end
function p.renderList(data)
-- Renders the list HTML.
-- Return the blank string if there are no list items.
if type(data.items) ~= 'table' or #data.items < 1 then
return ''
end
-- Render the main div tag.
local root = mw.html.create('div')
for _, class in ipairs(data.classes or {}) do
root:addClass(class)
end
root:css{['margin-left'] = data.marginLeft}
if data.style then
root:cssText(data.style)
end
-- Render the list tag.
local list = root:tag(data.listTag or 'ul')
list
:attr{start = data.start, type = data.type}
:css{
['counter-reset'] = data.counterReset,
['list-style-type'] = data.listStyleType
}
if data.listStyle then
list:cssText(data.listStyle)
end
-- Render the list items
for _, t in ipairs(data.items or {}) do
local item = list:tag('li')
if data.itemStyle then
item:cssText(data.itemStyle)
end
if t.style then
item:cssText(t.style)
end
item
:attr{value = t.value}
:wikitext(t.content)
end
return data.templatestyles .. tostring(root)
end
function p.makeList(listType, args)
if not listType or not listTypes[listType] then
error(string.format(
"bad argument #1 to 'makeList' ('%s' is not a valid list type)",
tostring(listType)
), 2)
end
checkType('makeList', 2, args, 'table')
local data = p.makeListData(listType, args)
local list = p.renderList(data)
return list
end
for listType in pairs(listTypes) do
p[listType] = function (frame)
local mArguments = require('Module:Arguments')
local origArgs = mArguments.getArgs(frame, {
frameOnly = ((frame and frame.args and frame.args.frameonly or '') ~= ''),
valueFunc = function (key, value)
if not value or not mw.ustring.find(value, '%S') then return nil end
if mw.ustring.find(value, '^%s*[%*#;:]') then
return value
else
return value:match('^%s*(.-)%s*$')
end
return nil
end
})
-- Copy all the arguments to a new table, for faster indexing.
local args = {}
for k, v in pairs(origArgs) do
args[k] = v
end
return p.makeList(listType, args)
end
end
return p
lyheh2t5yqhjixmg8vlktt3t9sq2ewi
Template:Infobox tracking categories
10
47948
124215
117449
2026-09-03T23:33:43Z
en>Zackmann08
0
Reverted 1 edit by [[Special:Contributions/Shkuru Afshar|Shkuru Afshar]] ([[User talk:Shkuru Afshar|talk]]): Unnecessary html comments.
117448
wikitext
text/x-wiki
<includeonly>{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with conflicting parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with conflicting parameters}}}}{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with deprecated parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with deprecated parameters}}}}{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with unknown parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with unknown parameters}}}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
bh542nwsz96fraf5o4w0gwcb8evjt92
124216
124215
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_tracking_categories]]
117448
wikitext
text/x-wiki
<includeonly>{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with conflicting parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with conflicting parameters}}}}{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with deprecated parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with deprecated parameters}}}}{{#ifexist: Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with unknown parameters|
* {{Category link with count|Category:Pages using {{lcfirst:{{If empty|{{{1|}}}|{{BASEPAGENAME}}}}}} with unknown parameters}}}}</includeonly><noinclude>
{{Documentation}}
</noinclude>
bh542nwsz96fraf5o4w0gwcb8evjt92
Template:Kbd/styles.css
10
48070
124213
117776
2026-09-10T00:11:20Z
en>Axolitl
0
Better colors in dark mode
124213
sanitized-css
text/css
/* {{pp-template}} */
.mw-tmpl-kbd {
background: #eaecf0;
color: var(--color-base);
}
@media screen {
html.skin-theme-clientpref-night .mw-tmpl-kbd {
background: #202122;
}
}
@media screen and ( prefers-color-scheme: dark ) {
html.skin-theme-clientpref-os .mw-tmpl-kbd {
background: #202122;
}
}
e88bnay3b7f4xp25s5o700e7qi2s9i7
124214
124213
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Kbd/styles.css]]
124213
sanitized-css
text/css
/* {{pp-template}} */
.mw-tmpl-kbd {
background: #eaecf0;
color: var(--color-base);
}
@media screen {
html.skin-theme-clientpref-night .mw-tmpl-kbd {
background: #202122;
}
}
@media screen and ( prefers-color-scheme: dark ) {
html.skin-theme-clientpref-os .mw-tmpl-kbd {
background: #202122;
}
}
e88bnay3b7f4xp25s5o700e7qi2s9i7
Template:Location map/doc/infobox parameters
10
48071
124217
119061
2026-09-05T03:14:14Z
en>Helpful Cat
0
ce
124217
wikitext
text/x-wiki
{{navbar|Template:Location map/doc/infobox parameters|plain=y|style=float: right;}}
Below are the parameters used by [[Module:Location map]] to produce the pushpin map in this Infobox. These parameters are available for editors to set in articles that use this infobox. For the maps available, please consult [[Template:Location map#Available maps|available maps]].
{| class="wikitable"
! Parameter
! Description
! Default
|-
|{{para|pushpin_map}}
| The map(s) to display. For example, specifying England will use the values for England in Module:Location map/data/England.Multiple maps can be shown by providing a list of map names separated by {{code|#}}. For multiple maps, the first is shown by default. A reader can select the others with radio buttons.
| ''{{if empty|{{{pushpin_map|}}}|N/A}}''
|-
|{{para|pushpin_caption}}
| The text of a caption to be displayed below the map. If not provided a default caption will be generated. Multiple captions can be shown when separated by {{code|##}} (that's two).
| ''{{if empty|{{{pushpin_caption|}}}|Location within MAPNAME}}''
|-
|{{para|pushpin_relief}}
| 0/false/off will cause the template to display the map defined as {{code|image}} (generally not a [[Cartographic relief depiction|relief map]]). 1/true/on will cause the template to display the map defined as {{code|image1}} (generally a relief map). Any non-zero numeric value such as {{code|2}} or {{code|3}} will display {{code|image2}} or {{code|image3}}, if those images are defined. Any other non-empty value will cause display of {{code|image1}}. See the example at [[Template:Location map+/relief|Location map+/relief]].
| ''{{if empty|{{{pushpin_relief|}}}|0}}''
|-
|{{para|pushpin_label}}
| The text of the label to display next to the identifying mark; a [[H:WIKILINK|wikilink]] can be used. You can enclose the label inside of {{tl|nowrap}} if you want to make sure that it stays on a single line.
| ''{{if empty|{{{pushpin_label|}}}|N/A}}''
|-
|{{para|pushpin_label_size}}
| The font size to use for the label, given as a percentage of the normal font size (<100=smaller, >100=larger); the default size is 90. Do not include {{kbd|%}}. For example, use {{para|pushpin_label_size|80}}, not {{para|pushpin_label_size|80%}}. If set to {{code|0}}, the label is only displayed when the user hovers over the mark.
| ''{{if empty|{{{pushpin_label_size|}}}|90}}''
|-
|style="white-space:nowrap;"<!--Only need to nowrap the longest one-->|{{para|pushpin_label_position}}
| The position of the label relative to the identifying mark; valid values are {{code|left}}, {{code|right}}, {{code|top}}, {{code|bottom}} and {{code|none}}. This defaults to either {{code|left}} or {{code|right}}, depending on the coordinates of the marker and its position relative to the right border of the map image. When {{para|pushpin_label_position|none}}, any defined label will not be displayed with the mark, but it will be used to create the default caption.
| ''{{if empty|{{{pushpin_label_position|}}}|N/A}}''
|-
|{{para|pushpin_mark}}
| The name of an image file to display as the identifying mark; the default is {{#if:{{{pushpin_mark|}}}|[[:File:{{{pushpin_mark|}}}]] [[File:{{{pushpin_mark|}}}|{{if empty|{{{pushpin_mark_size|}}}|8}}px]]|[[:File:Red pog.svg|Red pog.svg]] [[File:Red pog.svg|8px]]}}. See examples at [[Commons:Location markers]] and [[Commons:Category:Map icons]].
| ''{{#if:{{{pushpin_mark|}}}|[[:File:{{{pushpin_mark|}}}]] [[File:{{{pushpin_mark|}}}|{{if empty|{{{pushpin_mark_size|}}}|8}}px]]|[[:File:Red pog.svg|Red pog.svg]] [[File:Red pog.svg|8px]]}}''
|-
|{{para|pushpin_mark_size}}
| The size of the identifying mark in pixels. Do not include {{kbd|px}}
| ''{{if empty|{{{pushpin_mark_size|}}}|8}}''
|-
|{{para|pushpin_alt}}
| Alt text for map; used by [[screen reader]]s. See [[WP:ALT]].
| ''{{if empty|{{{pushpin_alt|}}}|N/A}}''
|-
|{{para|pushpin_background}}
| The background color to use for the label; see [[Web colors]]. The default is no background color, which shows the map image behind the label.
| ''{{if empty|{{{pushpin_background|}}}|N/A}}''
|-
|{{para|pushpin_map_size}}
| Determines the width of the map in [[pixel]]s, overriding any default values; do not include {{kbd|px}}.
| ''{{if empty|{{{pushpin_map_size|}}}|N/A}}''
|}
6b1yr7qzrw168dd8s3klnlgu2wy21gi
124218
124217
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Location_map/doc/infobox_parameters]]
124217
wikitext
text/x-wiki
{{navbar|Template:Location map/doc/infobox parameters|plain=y|style=float: right;}}
Below are the parameters used by [[Module:Location map]] to produce the pushpin map in this Infobox. These parameters are available for editors to set in articles that use this infobox. For the maps available, please consult [[Template:Location map#Available maps|available maps]].
{| class="wikitable"
! Parameter
! Description
! Default
|-
|{{para|pushpin_map}}
| The map(s) to display. For example, specifying England will use the values for England in Module:Location map/data/England.Multiple maps can be shown by providing a list of map names separated by {{code|#}}. For multiple maps, the first is shown by default. A reader can select the others with radio buttons.
| ''{{if empty|{{{pushpin_map|}}}|N/A}}''
|-
|{{para|pushpin_caption}}
| The text of a caption to be displayed below the map. If not provided a default caption will be generated. Multiple captions can be shown when separated by {{code|##}} (that's two).
| ''{{if empty|{{{pushpin_caption|}}}|Location within MAPNAME}}''
|-
|{{para|pushpin_relief}}
| 0/false/off will cause the template to display the map defined as {{code|image}} (generally not a [[Cartographic relief depiction|relief map]]). 1/true/on will cause the template to display the map defined as {{code|image1}} (generally a relief map). Any non-zero numeric value such as {{code|2}} or {{code|3}} will display {{code|image2}} or {{code|image3}}, if those images are defined. Any other non-empty value will cause display of {{code|image1}}. See the example at [[Template:Location map+/relief|Location map+/relief]].
| ''{{if empty|{{{pushpin_relief|}}}|0}}''
|-
|{{para|pushpin_label}}
| The text of the label to display next to the identifying mark; a [[H:WIKILINK|wikilink]] can be used. You can enclose the label inside of {{tl|nowrap}} if you want to make sure that it stays on a single line.
| ''{{if empty|{{{pushpin_label|}}}|N/A}}''
|-
|{{para|pushpin_label_size}}
| The font size to use for the label, given as a percentage of the normal font size (<100=smaller, >100=larger); the default size is 90. Do not include {{kbd|%}}. For example, use {{para|pushpin_label_size|80}}, not {{para|pushpin_label_size|80%}}. If set to {{code|0}}, the label is only displayed when the user hovers over the mark.
| ''{{if empty|{{{pushpin_label_size|}}}|90}}''
|-
|style="white-space:nowrap;"<!--Only need to nowrap the longest one-->|{{para|pushpin_label_position}}
| The position of the label relative to the identifying mark; valid values are {{code|left}}, {{code|right}}, {{code|top}}, {{code|bottom}} and {{code|none}}. This defaults to either {{code|left}} or {{code|right}}, depending on the coordinates of the marker and its position relative to the right border of the map image. When {{para|pushpin_label_position|none}}, any defined label will not be displayed with the mark, but it will be used to create the default caption.
| ''{{if empty|{{{pushpin_label_position|}}}|N/A}}''
|-
|{{para|pushpin_mark}}
| The name of an image file to display as the identifying mark; the default is {{#if:{{{pushpin_mark|}}}|[[:File:{{{pushpin_mark|}}}]] [[File:{{{pushpin_mark|}}}|{{if empty|{{{pushpin_mark_size|}}}|8}}px]]|[[:File:Red pog.svg|Red pog.svg]] [[File:Red pog.svg|8px]]}}. See examples at [[Commons:Location markers]] and [[Commons:Category:Map icons]].
| ''{{#if:{{{pushpin_mark|}}}|[[:File:{{{pushpin_mark|}}}]] [[File:{{{pushpin_mark|}}}|{{if empty|{{{pushpin_mark_size|}}}|8}}px]]|[[:File:Red pog.svg|Red pog.svg]] [[File:Red pog.svg|8px]]}}''
|-
|{{para|pushpin_mark_size}}
| The size of the identifying mark in pixels. Do not include {{kbd|px}}
| ''{{if empty|{{{pushpin_mark_size|}}}|8}}''
|-
|{{para|pushpin_alt}}
| Alt text for map; used by [[screen reader]]s. See [[WP:ALT]].
| ''{{if empty|{{{pushpin_alt|}}}|N/A}}''
|-
|{{para|pushpin_background}}
| The background color to use for the label; see [[Web colors]]. The default is no background color, which shows the map image behind the label.
| ''{{if empty|{{{pushpin_background|}}}|N/A}}''
|-
|{{para|pushpin_map_size}}
| Determines the width of the map in [[pixel]]s, overriding any default values; do not include {{kbd|px}}.
| ''{{if empty|{{{pushpin_map_size|}}}|N/A}}''
|}
6b1yr7qzrw168dd8s3klnlgu2wy21gi
Module:Protected page
828
49373
124219
120978
2026-10-29T01:57:49Z
en>Axolitl
0
Implement fix from sandbox which unlinks the images as they must be PD, per [[Module talk:Protected page|talk page]]
124219
Scribunto
text/plain
-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.
-- Initialise necessary modules.
require('strict')
local makeFileLink = require('Module:File link')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main
local yesno = require('Module:Yesno')
-- Lazily initialise modules and objects we don't always need.
local getArgs, makeMessageBox, lang
-- Set constants.
local CONFIG_MODULE = 'Module:Protected page/config'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function makeCategoryLink(cat, sort)
if cat then
return string.format(
'[[%s:%s|%s]]',
mw.site.namespaces[14].name,
cat,
sort
)
end
end
-- Validation function for the expiry and the protection date
local function validateDate(dateString, dateType)
if not lang then
lang = mw.language.getContentLanguage()
end
local success, result = pcall(lang.formatDate, lang, 'U', dateString)
if success then
result = tonumber(result)
if result then
return result
end
end
error(string.format(
'invalid %s: %s',
dateType,
tostring(dateString)
), 4)
end
local function makeFullUrl(page, query, display)
return string.format(
'[%s %s]',
tostring(mw.uri.fullUrl(page, query)),
display
)
end
-- Given a directed graph formatted as node -> table of direct successors,
-- get a table of all nodes reachable from a given node (though always
-- including the given node).
local function getReachableNodes(graph, start)
local toWalk, retval = {[start] = true}, {}
while true do
-- Can't use pairs() since we're adding and removing things as we're iterating
local k = next(toWalk) -- This always gets the "first" key
if k == nil then
return retval
end
toWalk[k] = nil
retval[k] = true
for _,v in ipairs(graph[k]) do
if not retval[v] then
toWalk[v] = true
end
end
end
end
--------------------------------------------------------------------------------
-- Protection class
--------------------------------------------------------------------------------
local Protection = {}
Protection.__index = Protection
Protection.supportedActions = {
edit = true,
move = true,
autoreview = true,
upload = true
}
Protection.bannerConfigFields = {
'text',
'explanation',
'tooltip',
'alt',
'link',
'image'
}
function Protection.new(args, cfg, title)
local obj = {}
obj._cfg = cfg
obj.title = title or mw.title.getCurrentTitle()
-- Set action
if not args.action then
obj.action = 'edit'
elseif Protection.supportedActions[args.action] then
obj.action = args.action
else
error(string.format(
'invalid action: %s',
tostring(args.action)
), 3)
end
-- Set level
obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title)
if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then
-- Users need to be autoconfirmed to move pages anyway, so treat
-- semi-move-protected pages as unprotected.
obj.level = '*'
end
-- Set expiry
local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title)
if effectiveExpiry == 'infinity' then
obj.expiry = 'indef'
elseif effectiveExpiry ~= 'unknown' then
obj.expiry = validateDate(effectiveExpiry, 'expiry date')
end
-- Set reason
if args[1] then
obj.reason = mw.ustring.lower(args[1])
if obj.reason:find('|') then
error('reasons cannot contain the pipe character ("|")', 3)
end
end
-- Set protection date
if args.date then
obj.protectionDate = validateDate(args.date, 'protection date')
end
-- Set banner config
do
obj.bannerConfig = {}
local configTables = {}
if cfg.banners[obj.action] then
configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason]
end
if cfg.defaultBanners[obj.action] then
configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level]
configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default
end
configTables[#configTables + 1] = cfg.masterBanner
for i, field in ipairs(Protection.bannerConfigFields) do
for j, t in ipairs(configTables) do
if t[field] then
obj.bannerConfig[field] = t[field]
break
end
end
end
end
return setmetatable(obj, Protection)
end
function Protection:isUserScript()
-- Whether the page is a user JavaScript or CSS page.
local title = self.title
return title.namespace == 2 and (
title.contentModel == 'javascript' or title.contentModel == 'css'
)
end
function Protection:isProtected()
return self.level ~= '*'
end
function Protection:shouldShowLock()
-- Whether we should output a banner/padlock
return self:isProtected() and not self:isUserScript()
end
-- Whether this page needs a protection category.
Protection.shouldHaveProtectionCategory = Protection.shouldShowLock
function Protection:isTemporary()
return type(self.expiry) == 'number'
end
function Protection:makeProtectionCategory()
if not self:shouldHaveProtectionCategory() then
return ''
end
local cfg = self._cfg
local title = self.title
-- Get the expiry key fragment.
local expiryFragment
if self.expiry == 'indef' then
expiryFragment = self.expiry
elseif type(self.expiry) == 'number' then
expiryFragment = 'temp'
end
-- Get the namespace key fragment.
local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace]
if not namespaceFragment and title.namespace % 2 == 1 then
namespaceFragment = 'talk'
end
-- Define the order that key fragments are tested in. This is done with an
-- array of tables containing the value to be tested, along with its
-- position in the cfg.protectionCategories table.
local order = {
{val = expiryFragment, keypos = 1},
{val = namespaceFragment, keypos = 2},
{val = self.reason, keypos = 3},
{val = self.level, keypos = 4},
{val = self.action, keypos = 5}
}
--[[
-- The old protection templates used an ad-hoc protection category system,
-- with some templates prioritising namespaces in their categories, and
-- others prioritising the protection reason. To emulate this in this module
-- we use the config table cfg.reasonsWithNamespacePriority to set the
-- reasons for which namespaces have priority over protection reason.
-- If we are dealing with one of those reasons, move the namespace table to
-- the end of the order table, i.e. give it highest priority. If not, the
-- reason should have highest priority, so move that to the end of the table
-- instead.
--]]
table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3))
--[[
-- Define the attempt order. Inactive subtables (subtables with nil "value"
-- fields) are moved to the end, where they will later be given the key
-- "all". This is to cut down on the number of table lookups in
-- cfg.protectionCategories, which grows exponentially with the number of
-- non-nil keys. We keep track of the number of active subtables with the
-- noActive parameter.
--]]
local noActive, attemptOrder
do
local active, inactive = {}, {}
for i, t in ipairs(order) do
if t.val then
active[#active + 1] = t
else
inactive[#inactive + 1] = t
end
end
noActive = #active
attemptOrder = active
for i, t in ipairs(inactive) do
attemptOrder[#attemptOrder + 1] = t
end
end
--[[
-- Check increasingly generic key combinations until we find a match. If a
-- specific category exists for the combination of key fragments we are
-- given, that match will be found first. If not, we keep trying different
-- key fragment combinations until we match using the key
-- "all-all-all-all-all".
--
-- To generate the keys, we index the key subtables using a binary matrix
-- with indexes i and j. j is only calculated up to the number of active
-- subtables. For example, if there were three active subtables, the matrix
-- would look like this, with 0 corresponding to the key fragment "all", and
-- 1 corresponding to other key fragments.
--
-- j 1 2 3
-- i
-- 1 1 1 1
-- 2 0 1 1
-- 3 1 0 1
-- 4 0 0 1
-- 5 1 1 0
-- 6 0 1 0
-- 7 1 0 0
-- 8 0 0 0
--
-- Values of j higher than the number of active subtables are set
-- to the string "all".
--
-- A key for cfg.protectionCategories is constructed for each value of i.
-- The position of the value in the key is determined by the keypos field in
-- each subtable.
--]]
local cats = cfg.protectionCategories
for i = 1, 2^noActive do
local key = {}
for j, t in ipairs(attemptOrder) do
if j > noActive then
key[t.keypos] = 'all'
else
local quotient = i / 2 ^ (j - 1)
quotient = math.ceil(quotient)
if quotient % 2 == 1 then
key[t.keypos] = t.val
else
key[t.keypos] = 'all'
end
end
end
key = table.concat(key, '|')
local attempt = cats[key]
if attempt then
return makeCategoryLink(attempt, title.text)
end
end
return ''
end
function Protection:isIncorrect()
if not self:shouldHaveProtectionCategory() then
return true
end
if type(self.expiry) ~= 'number' then
return false
end
local expiry = os.date('*t', self.expiry)
-- Avoid checking today.day or os.time(), unless close. https://phabricator.wikimedia.org/T416616
local today = os.date('*t')
return (expiry.year < today.year)
or (expiry.year == today.year and expiry.month < today.month)
or (expiry.year == today.year and expiry.month == today.month and expiry.day < today.day)
or (expiry.year == today.year and expiry.month == today.month and expiry.day == today.day and self.expiry < os.time())
end
function Protection:isTemplateProtectedNonTemplate()
local action, namespace = self.action, self.title.namespace
return self.level == 'templateeditor'
and (
(action ~= 'edit' and action ~= 'move')
or (namespace ~= 10 and namespace ~= 828)
)
end
function Protection:makeCategoryLinks()
local msg = self._cfg.msg
local ret = {self:makeProtectionCategory()}
if self:isIncorrect() then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-incorrect'],
self.title.text
)
end
if self:isTemplateProtectedNonTemplate() then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-template'],
self.title.text
)
end
return table.concat(ret)
end
--------------------------------------------------------------------------------
-- Blurb class
--------------------------------------------------------------------------------
local Blurb = {}
Blurb.__index = Blurb
Blurb.bannerTextFields = {
text = true,
explanation = true,
tooltip = true,
alt = true,
link = true
}
function Blurb.new(protectionObj, args, cfg)
return setmetatable({
_cfg = cfg,
_protectionObj = protectionObj,
_args = args
}, Blurb)
end
-- Private methods --
function Blurb:_formatDate(num)
-- Formats a Unix timestamp into dd Month, YYYY format.
lang = lang or mw.language.getContentLanguage()
local success, date = pcall(
lang.formatDate,
lang,
self._cfg.msg['expiry-date-format'] or 'j F Y',
'@' .. tostring(num)
)
if success then
return date
end
end
function Blurb:_getExpandedMessage(msgKey)
return self:_substituteParameters(self._cfg.msg[msgKey])
end
function Blurb:_substituteParameters(msg)
if not self._params then
local parameterFuncs = {}
parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter
parameterFuncs.EDITREQUEST = self._makeEditRequestParameter
parameterFuncs.EXPIRY = self._makeExpiryParameter
parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter
parameterFuncs.IMAGELINK = self._makeImageLinkParameter
parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter
parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter
parameterFuncs.PAGETYPE = self._makePagetypeParameter
parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter
parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter
parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter
parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter
parameterFuncs.TALKPAGE = self._makeTalkPageParameter
parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter
parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter
parameterFuncs.VANDAL = self._makeVandalTemplateParameter
self._params = setmetatable({}, {
__index = function (t, k)
local param
if parameterFuncs[k] then
param = parameterFuncs[k](self)
end
param = param or ''
t[k] = param
return param
end
})
end
msg = msg:gsub('${(%u+)}', self._params)
return msg
end
function Blurb:_makeCurrentVersionParameter()
-- A link to the page history or the move log, depending on the kind of
-- protection.
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'move' then
-- We need the move log link.
return makeFullUrl(
'Special:Log',
{type = 'move', page = pagename},
self:_getExpandedMessage('current-version-move-display')
)
else
-- We need the history link.
return makeFullUrl(
pagename,
{action = 'history'},
self:_getExpandedMessage('current-version-edit-display')
)
end
end
function Blurb:_makeEditRequestParameter()
local mEditRequest = require('Module:Submit an edit request')
local action = self._protectionObj.action
local level = self._protectionObj.level
-- Get the edit request type.
local requestType
if action == 'edit' then
if level == 'autoconfirmed' then
requestType = 'semi'
elseif level == 'extendedconfirmed' then
requestType = 'extended'
elseif level == 'templateeditor' then
requestType = 'template'
end
end
requestType = requestType or 'full'
-- Get the display value.
local display = self:_getExpandedMessage('edit-request-display')
return mEditRequest._link{type = requestType, display = display}
end
function Blurb:_makeExpiryParameter()
local expiry = self._protectionObj.expiry
if type(expiry) == 'number' then
return self:_formatDate(expiry)
else
return expiry
end
end
function Blurb:_makeExplanationBlurbParameter()
-- Cover special cases first.
if self._protectionObj.title.namespace == 8 then
-- MediaWiki namespace
return self:_getExpandedMessage('explanation-blurb-nounprotect')
end
-- Get explanation blurb table keys
local action = self._protectionObj.action
local level = self._protectionObj.level
local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject'
-- Find the message in the explanation blurb table and substitute any
-- parameters.
local explanations = self._cfg.explanationBlurbs
local msg
if explanations[action][level] and explanations[action][level][talkKey] then
msg = explanations[action][level][talkKey]
elseif explanations[action][level] and explanations[action][level].default then
msg = explanations[action][level].default
elseif explanations[action].default and explanations[action].default[talkKey] then
msg = explanations[action].default[talkKey]
elseif explanations[action].default and explanations[action].default.default then
msg = explanations[action].default.default
else
error(string.format(
'could not find explanation blurb for action "%s", level "%s" and talk key "%s"',
action,
level,
talkKey
), 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeImageLinkParameter()
local imageLinks = self._cfg.imageLinks
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if imageLinks[action][level] then
msg = imageLinks[action][level]
elseif imageLinks[action].default then
msg = imageLinks[action].default
else
msg = imageLinks.edit.default
end
return self:_substituteParameters(msg)
end
function Blurb:_makeIntroBlurbParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-blurb-expiry')
else
return self:_getExpandedMessage('intro-blurb-noexpiry')
end
end
function Blurb:_makeIntroFragmentParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-fragment-expiry')
else
return self:_getExpandedMessage('intro-fragment-noexpiry')
end
end
function Blurb:_makePagetypeParameter()
local pagetypes = self._cfg.pagetypes
return pagetypes[self._protectionObj.title.namespace]
or pagetypes.default
or error('no default pagetype defined', 8)
end
function Blurb:_makeProtectionBlurbParameter()
local protectionBlurbs = self._cfg.protectionBlurbs
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionBlurbs[action][level] then
msg = protectionBlurbs[action][level]
elseif protectionBlurbs[action].default then
msg = protectionBlurbs[action].default
elseif protectionBlurbs.edit.default then
msg = protectionBlurbs.edit.default
else
error('no protection blurb defined for protectionBlurbs.edit.default', 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeProtectionDateParameter()
local protectionDate = self._protectionObj.protectionDate
if type(protectionDate) == 'number' then
return self:_formatDate(protectionDate)
else
return protectionDate
end
end
function Blurb:_makeProtectionLevelParameter()
local protectionLevels = self._cfg.protectionLevels
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionLevels[action][level] then
msg = protectionLevels[action][level]
elseif protectionLevels[action].default then
msg = protectionLevels[action].default
elseif protectionLevels.edit.default then
msg = protectionLevels.edit.default
else
error('no protection level defined for protectionLevels.edit.default', 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeProtectionLogParameter()
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'autoreview' then
-- We need the pending changes log.
return makeFullUrl(
'Special:Log',
{type = 'stable', page = pagename},
self:_getExpandedMessage('pc-log-display')
)
else
-- We need the protection log.
return makeFullUrl(
'Special:Log',
{type = 'protect', page = pagename},
self:_getExpandedMessage('protection-log-display')
)
end
end
function Blurb:_makeTalkPageParameter()
return string.format(
'[[%s:%s#%s|%s]]',
mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
self._protectionObj.title.text,
self._args.section or 'top',
self:_getExpandedMessage('talk-page-link-display')
)
end
function Blurb:_makeTooltipBlurbParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-blurb-expiry')
else
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
end
end
function Blurb:_makeTooltipFragmentParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-fragment-expiry')
else
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
end
end
function Blurb:_makeVandalTemplateParameter()
return mw.getCurrentFrame():expandTemplate{
title="vandal-m",
args={self._args.user or self._protectionObj.title.baseText}
}
end
-- Public methods --
function Blurb:makeBannerText(key)
-- Validate input.
if not key or not Blurb.bannerTextFields[key] then
error(string.format(
'"%s" is not a valid banner config field',
tostring(key)
), 2)
end
-- Generate the text.
local msg = self._protectionObj.bannerConfig[key]
if type(msg) == 'string' then
return self:_substituteParameters(msg)
elseif type(msg) == 'function' then
msg = msg(self._protectionObj, self._args)
if type(msg) ~= 'string' then
error(string.format(
'bad output from banner config function with key "%s"'
.. ' (expected string, got %s)',
tostring(key),
type(msg)
), 4)
end
return self:_substituteParameters(msg)
end
end
--------------------------------------------------------------------------------
-- BannerTemplate class
--------------------------------------------------------------------------------
local BannerTemplate = {}
BannerTemplate.__index = BannerTemplate
function BannerTemplate.new(protectionObj, cfg)
local obj = {}
obj._cfg = cfg
-- Set the image filename.
local imageFilename = protectionObj.bannerConfig.image
if imageFilename then
obj._imageFilename = imageFilename
else
-- If an image filename isn't specified explicitly in the banner config,
-- generate it from the protection status and the namespace.
local action = protectionObj.action
local level = protectionObj.level
local namespace = protectionObj.title.namespace
local reason = protectionObj.reason
-- Deal with special cases first.
if (
namespace == 10
or namespace == 828
or reason and obj._cfg.indefImageReasons[reason]
)
and action == 'edit'
and level == 'sysop'
and not protectionObj:isTemporary()
then
-- Fully protected modules and templates get the special red "indef"
-- padlock.
obj._imageFilename = obj._cfg.msg['image-filename-indef']
else
-- Deal with regular protection types.
local images = obj._cfg.images
if images[action] then
if images[action][level] then
obj._imageFilename = images[action][level]
elseif images[action].default then
obj._imageFilename = images[action].default
end
end
end
end
return setmetatable(obj, BannerTemplate)
end
function BannerTemplate:renderImage()
local filename = self._imageFilename
or self._cfg.msg['image-filename-default']
or 'Transparent.gif'
return makeFileLink{
file = filename,
size = (self.imageWidth or 20) .. 'px',
alt = self._imageAlt,
link = self._imageLink or "",
caption = self.imageCaption
}
end
--------------------------------------------------------------------------------
-- Banner class
--------------------------------------------------------------------------------
local Banner = setmetatable({}, BannerTemplate)
Banner.__index = Banner
function Banner.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 40
obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip.
obj._reasonText = blurbObj:makeBannerText('text')
obj._explanationText = blurbObj:makeBannerText('explanation')
obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing.
return setmetatable(obj, Banner)
end
function Banner:__tostring()
-- Renders the banner.
makeMessageBox = makeMessageBox or require('Module:Message box').main
local reasonText = self._reasonText or error('no reason text set', 2)
local explanationText = self._explanationText
local mbargs = {
page = self._page,
type = 'protection',
image = self:renderImage(),
text = string.format(
"'''%s'''%s",
reasonText,
explanationText and '<br />' .. explanationText or ''
)
}
return makeMessageBox('mbox', mbargs)
end
--------------------------------------------------------------------------------
-- Padlock class
--------------------------------------------------------------------------------
local Padlock = setmetatable({}, BannerTemplate)
Padlock.__index = Padlock
function Padlock.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 20
obj.imageCaption = blurbObj:makeBannerText('tooltip')
obj._imageAlt = blurbObj:makeBannerText('alt')
obj._imageLink = blurbObj:makeBannerText('link')
obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action]
or cfg.padlockIndicatorNames.default
or 'pp-default'
return setmetatable(obj, Padlock)
end
function Padlock:__tostring()
local frame = mw.getCurrentFrame()
-- The nowiki tag helps prevent whitespace at the top of articles.
return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{
name = 'indicator',
args = {name = self._indicatorName},
content = self:renderImage()
}
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- This is used for testing purposes.
return {
Protection = Protection,
Blurb = Blurb,
BannerTemplate = BannerTemplate,
Banner = Banner,
Padlock = Padlock,
}
end
function p._main(args, cfg, title)
args = args or {}
cfg = cfg or require(CONFIG_MODULE)
local protectionObj = Protection.new(args, cfg, title)
local ret = {}
-- If a page's edit protection is equally or more restrictive than its
-- protection from some other action, then don't bother displaying anything
-- for the other action (except categories).
if not yesno(args.catonly) and (protectionObj.action == 'edit' or
args.demolevel or
not getReachableNodes(
cfg.hierarchy,
protectionObj.level
)[effectiveProtectionLevel('edit', protectionObj.title)])
then
-- Initialise the blurb object
local blurbObj = Blurb.new(protectionObj, args, cfg)
-- Render the banner
if protectionObj:shouldShowLock() then
ret[#ret + 1] = tostring(
(yesno(args.small) and Padlock or Banner)
.new(protectionObj, blurbObj, cfg)
)
end
end
-- Render the categories
if yesno(args.category) ~= false then
ret[#ret + 1] = protectionObj:makeCategoryLinks()
end
-- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them
if protectionObj.level == "extendedconfirmed" then
if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then
ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>"
end
end
return table.concat(ret)
end
function p.main(frame, cfg)
cfg = cfg or require(CONFIG_MODULE)
-- Find default args, if any.
local parent = frame.getParent and frame:getParent()
local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')]
-- Find user args, and use the parent frame if we are being called from a
-- wrapper template.
getArgs = getArgs or require('Module:Arguments').getArgs
local userArgs = getArgs(frame, {
parentOnly = defaultArgs,
frameOnly = not defaultArgs
})
-- Build the args table. User-specified args overwrite default args.
local args = {}
for k, v in pairs(defaultArgs or {}) do
args[k] = v
end
for k, v in pairs(userArgs) do
args[k] = v
end
return p._main(args, cfg)
end
return p
2l9tbl06cepi1tkxnuv28whatem2k19
124220
124219
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Protected_page]]
124219
Scribunto
text/plain
-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.
-- Initialise necessary modules.
require('strict')
local makeFileLink = require('Module:File link')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionExpiry = require('Module:Effective protection expiry')._main
local yesno = require('Module:Yesno')
-- Lazily initialise modules and objects we don't always need.
local getArgs, makeMessageBox, lang
-- Set constants.
local CONFIG_MODULE = 'Module:Protected page/config'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function makeCategoryLink(cat, sort)
if cat then
return string.format(
'[[%s:%s|%s]]',
mw.site.namespaces[14].name,
cat,
sort
)
end
end
-- Validation function for the expiry and the protection date
local function validateDate(dateString, dateType)
if not lang then
lang = mw.language.getContentLanguage()
end
local success, result = pcall(lang.formatDate, lang, 'U', dateString)
if success then
result = tonumber(result)
if result then
return result
end
end
error(string.format(
'invalid %s: %s',
dateType,
tostring(dateString)
), 4)
end
local function makeFullUrl(page, query, display)
return string.format(
'[%s %s]',
tostring(mw.uri.fullUrl(page, query)),
display
)
end
-- Given a directed graph formatted as node -> table of direct successors,
-- get a table of all nodes reachable from a given node (though always
-- including the given node).
local function getReachableNodes(graph, start)
local toWalk, retval = {[start] = true}, {}
while true do
-- Can't use pairs() since we're adding and removing things as we're iterating
local k = next(toWalk) -- This always gets the "first" key
if k == nil then
return retval
end
toWalk[k] = nil
retval[k] = true
for _,v in ipairs(graph[k]) do
if not retval[v] then
toWalk[v] = true
end
end
end
end
--------------------------------------------------------------------------------
-- Protection class
--------------------------------------------------------------------------------
local Protection = {}
Protection.__index = Protection
Protection.supportedActions = {
edit = true,
move = true,
autoreview = true,
upload = true
}
Protection.bannerConfigFields = {
'text',
'explanation',
'tooltip',
'alt',
'link',
'image'
}
function Protection.new(args, cfg, title)
local obj = {}
obj._cfg = cfg
obj.title = title or mw.title.getCurrentTitle()
-- Set action
if not args.action then
obj.action = 'edit'
elseif Protection.supportedActions[args.action] then
obj.action = args.action
else
error(string.format(
'invalid action: %s',
tostring(args.action)
), 3)
end
-- Set level
obj.level = args.demolevel or effectiveProtectionLevel(obj.action, obj.title)
if not obj.level or (obj.action == 'move' and obj.level == 'autoconfirmed') then
-- Users need to be autoconfirmed to move pages anyway, so treat
-- semi-move-protected pages as unprotected.
obj.level = '*'
end
-- Set expiry
local effectiveExpiry = effectiveProtectionExpiry(obj.action, obj.title)
if effectiveExpiry == 'infinity' then
obj.expiry = 'indef'
elseif effectiveExpiry ~= 'unknown' then
obj.expiry = validateDate(effectiveExpiry, 'expiry date')
end
-- Set reason
if args[1] then
obj.reason = mw.ustring.lower(args[1])
if obj.reason:find('|') then
error('reasons cannot contain the pipe character ("|")', 3)
end
end
-- Set protection date
if args.date then
obj.protectionDate = validateDate(args.date, 'protection date')
end
-- Set banner config
do
obj.bannerConfig = {}
local configTables = {}
if cfg.banners[obj.action] then
configTables[#configTables + 1] = cfg.banners[obj.action][obj.reason]
end
if cfg.defaultBanners[obj.action] then
configTables[#configTables + 1] = cfg.defaultBanners[obj.action][obj.level]
configTables[#configTables + 1] = cfg.defaultBanners[obj.action].default
end
configTables[#configTables + 1] = cfg.masterBanner
for i, field in ipairs(Protection.bannerConfigFields) do
for j, t in ipairs(configTables) do
if t[field] then
obj.bannerConfig[field] = t[field]
break
end
end
end
end
return setmetatable(obj, Protection)
end
function Protection:isUserScript()
-- Whether the page is a user JavaScript or CSS page.
local title = self.title
return title.namespace == 2 and (
title.contentModel == 'javascript' or title.contentModel == 'css'
)
end
function Protection:isProtected()
return self.level ~= '*'
end
function Protection:shouldShowLock()
-- Whether we should output a banner/padlock
return self:isProtected() and not self:isUserScript()
end
-- Whether this page needs a protection category.
Protection.shouldHaveProtectionCategory = Protection.shouldShowLock
function Protection:isTemporary()
return type(self.expiry) == 'number'
end
function Protection:makeProtectionCategory()
if not self:shouldHaveProtectionCategory() then
return ''
end
local cfg = self._cfg
local title = self.title
-- Get the expiry key fragment.
local expiryFragment
if self.expiry == 'indef' then
expiryFragment = self.expiry
elseif type(self.expiry) == 'number' then
expiryFragment = 'temp'
end
-- Get the namespace key fragment.
local namespaceFragment = cfg.categoryNamespaceKeys[title.namespace]
if not namespaceFragment and title.namespace % 2 == 1 then
namespaceFragment = 'talk'
end
-- Define the order that key fragments are tested in. This is done with an
-- array of tables containing the value to be tested, along with its
-- position in the cfg.protectionCategories table.
local order = {
{val = expiryFragment, keypos = 1},
{val = namespaceFragment, keypos = 2},
{val = self.reason, keypos = 3},
{val = self.level, keypos = 4},
{val = self.action, keypos = 5}
}
--[[
-- The old protection templates used an ad-hoc protection category system,
-- with some templates prioritising namespaces in their categories, and
-- others prioritising the protection reason. To emulate this in this module
-- we use the config table cfg.reasonsWithNamespacePriority to set the
-- reasons for which namespaces have priority over protection reason.
-- If we are dealing with one of those reasons, move the namespace table to
-- the end of the order table, i.e. give it highest priority. If not, the
-- reason should have highest priority, so move that to the end of the table
-- instead.
--]]
table.insert(order, table.remove(order, self.reason and cfg.reasonsWithNamespacePriority[self.reason] and 2 or 3))
--[[
-- Define the attempt order. Inactive subtables (subtables with nil "value"
-- fields) are moved to the end, where they will later be given the key
-- "all". This is to cut down on the number of table lookups in
-- cfg.protectionCategories, which grows exponentially with the number of
-- non-nil keys. We keep track of the number of active subtables with the
-- noActive parameter.
--]]
local noActive, attemptOrder
do
local active, inactive = {}, {}
for i, t in ipairs(order) do
if t.val then
active[#active + 1] = t
else
inactive[#inactive + 1] = t
end
end
noActive = #active
attemptOrder = active
for i, t in ipairs(inactive) do
attemptOrder[#attemptOrder + 1] = t
end
end
--[[
-- Check increasingly generic key combinations until we find a match. If a
-- specific category exists for the combination of key fragments we are
-- given, that match will be found first. If not, we keep trying different
-- key fragment combinations until we match using the key
-- "all-all-all-all-all".
--
-- To generate the keys, we index the key subtables using a binary matrix
-- with indexes i and j. j is only calculated up to the number of active
-- subtables. For example, if there were three active subtables, the matrix
-- would look like this, with 0 corresponding to the key fragment "all", and
-- 1 corresponding to other key fragments.
--
-- j 1 2 3
-- i
-- 1 1 1 1
-- 2 0 1 1
-- 3 1 0 1
-- 4 0 0 1
-- 5 1 1 0
-- 6 0 1 0
-- 7 1 0 0
-- 8 0 0 0
--
-- Values of j higher than the number of active subtables are set
-- to the string "all".
--
-- A key for cfg.protectionCategories is constructed for each value of i.
-- The position of the value in the key is determined by the keypos field in
-- each subtable.
--]]
local cats = cfg.protectionCategories
for i = 1, 2^noActive do
local key = {}
for j, t in ipairs(attemptOrder) do
if j > noActive then
key[t.keypos] = 'all'
else
local quotient = i / 2 ^ (j - 1)
quotient = math.ceil(quotient)
if quotient % 2 == 1 then
key[t.keypos] = t.val
else
key[t.keypos] = 'all'
end
end
end
key = table.concat(key, '|')
local attempt = cats[key]
if attempt then
return makeCategoryLink(attempt, title.text)
end
end
return ''
end
function Protection:isIncorrect()
if not self:shouldHaveProtectionCategory() then
return true
end
if type(self.expiry) ~= 'number' then
return false
end
local expiry = os.date('*t', self.expiry)
-- Avoid checking today.day or os.time(), unless close. https://phabricator.wikimedia.org/T416616
local today = os.date('*t')
return (expiry.year < today.year)
or (expiry.year == today.year and expiry.month < today.month)
or (expiry.year == today.year and expiry.month == today.month and expiry.day < today.day)
or (expiry.year == today.year and expiry.month == today.month and expiry.day == today.day and self.expiry < os.time())
end
function Protection:isTemplateProtectedNonTemplate()
local action, namespace = self.action, self.title.namespace
return self.level == 'templateeditor'
and (
(action ~= 'edit' and action ~= 'move')
or (namespace ~= 10 and namespace ~= 828)
)
end
function Protection:makeCategoryLinks()
local msg = self._cfg.msg
local ret = {self:makeProtectionCategory()}
if self:isIncorrect() then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-incorrect'],
self.title.text
)
end
if self:isTemplateProtectedNonTemplate() then
ret[#ret + 1] = makeCategoryLink(
msg['tracking-category-template'],
self.title.text
)
end
return table.concat(ret)
end
--------------------------------------------------------------------------------
-- Blurb class
--------------------------------------------------------------------------------
local Blurb = {}
Blurb.__index = Blurb
Blurb.bannerTextFields = {
text = true,
explanation = true,
tooltip = true,
alt = true,
link = true
}
function Blurb.new(protectionObj, args, cfg)
return setmetatable({
_cfg = cfg,
_protectionObj = protectionObj,
_args = args
}, Blurb)
end
-- Private methods --
function Blurb:_formatDate(num)
-- Formats a Unix timestamp into dd Month, YYYY format.
lang = lang or mw.language.getContentLanguage()
local success, date = pcall(
lang.formatDate,
lang,
self._cfg.msg['expiry-date-format'] or 'j F Y',
'@' .. tostring(num)
)
if success then
return date
end
end
function Blurb:_getExpandedMessage(msgKey)
return self:_substituteParameters(self._cfg.msg[msgKey])
end
function Blurb:_substituteParameters(msg)
if not self._params then
local parameterFuncs = {}
parameterFuncs.CURRENTVERSION = self._makeCurrentVersionParameter
parameterFuncs.EDITREQUEST = self._makeEditRequestParameter
parameterFuncs.EXPIRY = self._makeExpiryParameter
parameterFuncs.EXPLANATIONBLURB = self._makeExplanationBlurbParameter
parameterFuncs.IMAGELINK = self._makeImageLinkParameter
parameterFuncs.INTROBLURB = self._makeIntroBlurbParameter
parameterFuncs.INTROFRAGMENT = self._makeIntroFragmentParameter
parameterFuncs.PAGETYPE = self._makePagetypeParameter
parameterFuncs.PROTECTIONBLURB = self._makeProtectionBlurbParameter
parameterFuncs.PROTECTIONDATE = self._makeProtectionDateParameter
parameterFuncs.PROTECTIONLEVEL = self._makeProtectionLevelParameter
parameterFuncs.PROTECTIONLOG = self._makeProtectionLogParameter
parameterFuncs.TALKPAGE = self._makeTalkPageParameter
parameterFuncs.TOOLTIPBLURB = self._makeTooltipBlurbParameter
parameterFuncs.TOOLTIPFRAGMENT = self._makeTooltipFragmentParameter
parameterFuncs.VANDAL = self._makeVandalTemplateParameter
self._params = setmetatable({}, {
__index = function (t, k)
local param
if parameterFuncs[k] then
param = parameterFuncs[k](self)
end
param = param or ''
t[k] = param
return param
end
})
end
msg = msg:gsub('${(%u+)}', self._params)
return msg
end
function Blurb:_makeCurrentVersionParameter()
-- A link to the page history or the move log, depending on the kind of
-- protection.
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'move' then
-- We need the move log link.
return makeFullUrl(
'Special:Log',
{type = 'move', page = pagename},
self:_getExpandedMessage('current-version-move-display')
)
else
-- We need the history link.
return makeFullUrl(
pagename,
{action = 'history'},
self:_getExpandedMessage('current-version-edit-display')
)
end
end
function Blurb:_makeEditRequestParameter()
local mEditRequest = require('Module:Submit an edit request')
local action = self._protectionObj.action
local level = self._protectionObj.level
-- Get the edit request type.
local requestType
if action == 'edit' then
if level == 'autoconfirmed' then
requestType = 'semi'
elseif level == 'extendedconfirmed' then
requestType = 'extended'
elseif level == 'templateeditor' then
requestType = 'template'
end
end
requestType = requestType or 'full'
-- Get the display value.
local display = self:_getExpandedMessage('edit-request-display')
return mEditRequest._link{type = requestType, display = display}
end
function Blurb:_makeExpiryParameter()
local expiry = self._protectionObj.expiry
if type(expiry) == 'number' then
return self:_formatDate(expiry)
else
return expiry
end
end
function Blurb:_makeExplanationBlurbParameter()
-- Cover special cases first.
if self._protectionObj.title.namespace == 8 then
-- MediaWiki namespace
return self:_getExpandedMessage('explanation-blurb-nounprotect')
end
-- Get explanation blurb table keys
local action = self._protectionObj.action
local level = self._protectionObj.level
local talkKey = self._protectionObj.title.isTalkPage and 'talk' or 'subject'
-- Find the message in the explanation blurb table and substitute any
-- parameters.
local explanations = self._cfg.explanationBlurbs
local msg
if explanations[action][level] and explanations[action][level][talkKey] then
msg = explanations[action][level][talkKey]
elseif explanations[action][level] and explanations[action][level].default then
msg = explanations[action][level].default
elseif explanations[action].default and explanations[action].default[talkKey] then
msg = explanations[action].default[talkKey]
elseif explanations[action].default and explanations[action].default.default then
msg = explanations[action].default.default
else
error(string.format(
'could not find explanation blurb for action "%s", level "%s" and talk key "%s"',
action,
level,
talkKey
), 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeImageLinkParameter()
local imageLinks = self._cfg.imageLinks
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if imageLinks[action][level] then
msg = imageLinks[action][level]
elseif imageLinks[action].default then
msg = imageLinks[action].default
else
msg = imageLinks.edit.default
end
return self:_substituteParameters(msg)
end
function Blurb:_makeIntroBlurbParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-blurb-expiry')
else
return self:_getExpandedMessage('intro-blurb-noexpiry')
end
end
function Blurb:_makeIntroFragmentParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-fragment-expiry')
else
return self:_getExpandedMessage('intro-fragment-noexpiry')
end
end
function Blurb:_makePagetypeParameter()
local pagetypes = self._cfg.pagetypes
return pagetypes[self._protectionObj.title.namespace]
or pagetypes.default
or error('no default pagetype defined', 8)
end
function Blurb:_makeProtectionBlurbParameter()
local protectionBlurbs = self._cfg.protectionBlurbs
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionBlurbs[action][level] then
msg = protectionBlurbs[action][level]
elseif protectionBlurbs[action].default then
msg = protectionBlurbs[action].default
elseif protectionBlurbs.edit.default then
msg = protectionBlurbs.edit.default
else
error('no protection blurb defined for protectionBlurbs.edit.default', 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeProtectionDateParameter()
local protectionDate = self._protectionObj.protectionDate
if type(protectionDate) == 'number' then
return self:_formatDate(protectionDate)
else
return protectionDate
end
end
function Blurb:_makeProtectionLevelParameter()
local protectionLevels = self._cfg.protectionLevels
local action = self._protectionObj.action
local level = self._protectionObj.level
local msg
if protectionLevels[action][level] then
msg = protectionLevels[action][level]
elseif protectionLevels[action].default then
msg = protectionLevels[action].default
elseif protectionLevels.edit.default then
msg = protectionLevels.edit.default
else
error('no protection level defined for protectionLevels.edit.default', 8)
end
return self:_substituteParameters(msg)
end
function Blurb:_makeProtectionLogParameter()
local pagename = self._protectionObj.title.prefixedText
if self._protectionObj.action == 'autoreview' then
-- We need the pending changes log.
return makeFullUrl(
'Special:Log',
{type = 'stable', page = pagename},
self:_getExpandedMessage('pc-log-display')
)
else
-- We need the protection log.
return makeFullUrl(
'Special:Log',
{type = 'protect', page = pagename},
self:_getExpandedMessage('protection-log-display')
)
end
end
function Blurb:_makeTalkPageParameter()
return string.format(
'[[%s:%s#%s|%s]]',
mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
self._protectionObj.title.text,
self._args.section or 'top',
self:_getExpandedMessage('talk-page-link-display')
)
end
function Blurb:_makeTooltipBlurbParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-blurb-expiry')
else
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
end
end
function Blurb:_makeTooltipFragmentParameter()
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-fragment-expiry')
else
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
end
end
function Blurb:_makeVandalTemplateParameter()
return mw.getCurrentFrame():expandTemplate{
title="vandal-m",
args={self._args.user or self._protectionObj.title.baseText}
}
end
-- Public methods --
function Blurb:makeBannerText(key)
-- Validate input.
if not key or not Blurb.bannerTextFields[key] then
error(string.format(
'"%s" is not a valid banner config field',
tostring(key)
), 2)
end
-- Generate the text.
local msg = self._protectionObj.bannerConfig[key]
if type(msg) == 'string' then
return self:_substituteParameters(msg)
elseif type(msg) == 'function' then
msg = msg(self._protectionObj, self._args)
if type(msg) ~= 'string' then
error(string.format(
'bad output from banner config function with key "%s"'
.. ' (expected string, got %s)',
tostring(key),
type(msg)
), 4)
end
return self:_substituteParameters(msg)
end
end
--------------------------------------------------------------------------------
-- BannerTemplate class
--------------------------------------------------------------------------------
local BannerTemplate = {}
BannerTemplate.__index = BannerTemplate
function BannerTemplate.new(protectionObj, cfg)
local obj = {}
obj._cfg = cfg
-- Set the image filename.
local imageFilename = protectionObj.bannerConfig.image
if imageFilename then
obj._imageFilename = imageFilename
else
-- If an image filename isn't specified explicitly in the banner config,
-- generate it from the protection status and the namespace.
local action = protectionObj.action
local level = protectionObj.level
local namespace = protectionObj.title.namespace
local reason = protectionObj.reason
-- Deal with special cases first.
if (
namespace == 10
or namespace == 828
or reason and obj._cfg.indefImageReasons[reason]
)
and action == 'edit'
and level == 'sysop'
and not protectionObj:isTemporary()
then
-- Fully protected modules and templates get the special red "indef"
-- padlock.
obj._imageFilename = obj._cfg.msg['image-filename-indef']
else
-- Deal with regular protection types.
local images = obj._cfg.images
if images[action] then
if images[action][level] then
obj._imageFilename = images[action][level]
elseif images[action].default then
obj._imageFilename = images[action].default
end
end
end
end
return setmetatable(obj, BannerTemplate)
end
function BannerTemplate:renderImage()
local filename = self._imageFilename
or self._cfg.msg['image-filename-default']
or 'Transparent.gif'
return makeFileLink{
file = filename,
size = (self.imageWidth or 20) .. 'px',
alt = self._imageAlt,
link = self._imageLink or "",
caption = self.imageCaption
}
end
--------------------------------------------------------------------------------
-- Banner class
--------------------------------------------------------------------------------
local Banner = setmetatable({}, BannerTemplate)
Banner.__index = Banner
function Banner.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 40
obj.imageCaption = blurbObj:makeBannerText('alt') -- Large banners use the alt text for the tooltip.
obj._reasonText = blurbObj:makeBannerText('text')
obj._explanationText = blurbObj:makeBannerText('explanation')
obj._page = protectionObj.title.prefixedText -- Only makes a difference in testing.
return setmetatable(obj, Banner)
end
function Banner:__tostring()
-- Renders the banner.
makeMessageBox = makeMessageBox or require('Module:Message box').main
local reasonText = self._reasonText or error('no reason text set', 2)
local explanationText = self._explanationText
local mbargs = {
page = self._page,
type = 'protection',
image = self:renderImage(),
text = string.format(
"'''%s'''%s",
reasonText,
explanationText and '<br />' .. explanationText or ''
)
}
return makeMessageBox('mbox', mbargs)
end
--------------------------------------------------------------------------------
-- Padlock class
--------------------------------------------------------------------------------
local Padlock = setmetatable({}, BannerTemplate)
Padlock.__index = Padlock
function Padlock.new(protectionObj, blurbObj, cfg)
local obj = BannerTemplate.new(protectionObj, cfg) -- This doesn't need the blurb.
obj.imageWidth = 20
obj.imageCaption = blurbObj:makeBannerText('tooltip')
obj._imageAlt = blurbObj:makeBannerText('alt')
obj._imageLink = blurbObj:makeBannerText('link')
obj._indicatorName = cfg.padlockIndicatorNames[protectionObj.action]
or cfg.padlockIndicatorNames.default
or 'pp-default'
return setmetatable(obj, Padlock)
end
function Padlock:__tostring()
local frame = mw.getCurrentFrame()
-- The nowiki tag helps prevent whitespace at the top of articles.
return frame:extensionTag{name = 'nowiki'} .. frame:extensionTag{
name = 'indicator',
args = {name = self._indicatorName},
content = self:renderImage()
}
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- This is used for testing purposes.
return {
Protection = Protection,
Blurb = Blurb,
BannerTemplate = BannerTemplate,
Banner = Banner,
Padlock = Padlock,
}
end
function p._main(args, cfg, title)
args = args or {}
cfg = cfg or require(CONFIG_MODULE)
local protectionObj = Protection.new(args, cfg, title)
local ret = {}
-- If a page's edit protection is equally or more restrictive than its
-- protection from some other action, then don't bother displaying anything
-- for the other action (except categories).
if not yesno(args.catonly) and (protectionObj.action == 'edit' or
args.demolevel or
not getReachableNodes(
cfg.hierarchy,
protectionObj.level
)[effectiveProtectionLevel('edit', protectionObj.title)])
then
-- Initialise the blurb object
local blurbObj = Blurb.new(protectionObj, args, cfg)
-- Render the banner
if protectionObj:shouldShowLock() then
ret[#ret + 1] = tostring(
(yesno(args.small) and Padlock or Banner)
.new(protectionObj, blurbObj, cfg)
)
end
end
-- Render the categories
if yesno(args.category) ~= false then
ret[#ret + 1] = protectionObj:makeCategoryLinks()
end
-- For arbitration enforcement, flagging [[WP:PIA]] pages to enable [[Special:AbuseFilter/1339]] to flag edits to them
if protectionObj.level == "extendedconfirmed" then
if require("Module:TableTools").inArray(protectionObj.title.talkPageTitle.categories, "Wikipedia pages subject to the extended confirmed restriction related to the Arab-Israeli conflict") then
ret[#ret + 1] = "<p class='PIA-flag' style='display:none; visibility:hidden;' title='This page is subject to the extended confirmed restriction related to the Arab-Israeli conflict.'></p>"
end
end
return table.concat(ret)
end
function p.main(frame, cfg)
cfg = cfg or require(CONFIG_MODULE)
-- Find default args, if any.
local parent = frame.getParent and frame:getParent()
local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')]
-- Find user args, and use the parent frame if we are being called from a
-- wrapper template.
getArgs = getArgs or require('Module:Arguments').getArgs
local userArgs = getArgs(frame, {
parentOnly = defaultArgs,
frameOnly = not defaultArgs
})
-- Build the args table. User-specified args overwrite default args.
local args = {}
for k, v in pairs(defaultArgs or {}) do
args[k] = v
end
for k, v in pairs(userArgs) do
args[k] = v
end
return p._main(args, cfg)
end
return p
2l9tbl06cepi1tkxnuv28whatem2k19
Module:Protected page/config
828
49374
124221
120980
2026-11-05T15:15:23Z
en>Axolitl
0
Fix wrapper name
124221
Scribunto
text/plain
-- This module provides configuration data for [[Module:Protection banner]].
return {
--------------------------------------------------------------------------------
--
-- BANNER DATA
--
--------------------------------------------------------------------------------
--[[
-- Banner data consists of six fields:
-- * text - the main protection text that appears at the top of protection
-- banners.
-- * explanation - the text that appears below the main protection text, used
-- to explain the details of the protection.
-- * tooltip - the tooltip text you see when you move the mouse over a small
-- padlock icon.
-- * link - the page that the small padlock icon links to.
-- * alt - the alt text for the small padlock icon. This is also used as tooltip
-- text for the large protection banners.
-- * image - the padlock image used in both protection banners and small padlock
-- icons.
--
-- The module checks in three separate tables to find a value for each field.
-- First it checks the banners table, which has values specific to the reason
-- for the page being protected. Then the module checks the defaultBanners
-- table, which has values specific to each protection level. Finally, the
-- module checks the masterBanner table, which holds data for protection
-- templates to use if no data has been found in the previous two tables.
--
-- The values in the banner data can take parameters. These are specified
-- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name
-- enclosed in curly braces).
--
-- Available parameters:
--
-- ${CURRENTVERSION} - a link to the page history or the move log, with the
-- display message "current-version-edit-display" or
-- "current-version-move-display".
--
-- ${EDITREQUEST} - a link to create an edit request for the current page.
--
-- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes
-- on the talk page; you may submit a request to ask an administrator to make
-- an edit if it is minor or supported by consensus."
--
-- ${IMAGELINK} - a link to set the image to, depending on the protection
-- action and protection level.
--
-- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry
-- is set. E.g. "Editing of this page by new or unregistered users is currently
-- disabled until dd Month YYYY."
--
-- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation
-- so that it can be used in run-on sentences.
--
-- ${PAGETYPE} - the type of the page, e.g. "article" or "template".
-- Defined in the cfg.pagetypes table.
--
-- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g.
-- "Editing of this page by new or unregistered users is currently disabled"
--
-- ${PROTECTIONDATE} - the protection date, if it has been supplied to the
-- template.
--
-- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or
-- "semi-protected".
--
-- ${PROTECTIONLOG} - a link to the protection log or the pending changes log,
-- depending on the protection action.
--
-- ${TALKPAGE} - a link to the talk page. If a section is specified, links
-- straight to that talk page section.
--
-- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to
-- create a blurb like "This template is semi-protected", or "This article is
-- move-protected until DD Month YYYY".
--
-- ${VANDAL} - links for the specified username (or the root page name)
-- using Module:Vandal-m.
--
-- Functions
--
-- For advanced users, it is possible to use Lua functions instead of strings
-- in the banner config tables. Using functions gives flexibility that is not
-- possible just by using parameters. Functions take two arguments, the
-- protection object and the template arguments, and they must output a string.
--
-- For example:
--
-- text = function (protectionObj, args)
-- if protectionObj.level == 'autoconfirmed' then
-- return 'foo'
-- else
-- return 'bar'
-- end
-- end
--
-- Some protection object properties and methods that may be useful:
-- protectionObj.action - the protection action
-- protectionObj.level - the protection level
-- protectionObj.reason - the protection reason
-- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set
-- to indefinite, and the protection time in unix time if temporary.
-- protectionObj.protectionDate - the protection date in unix time, or nil if
-- unspecified.
-- protectionObj.bannerConfig - the banner config found by the module. Beware
-- of editing the config field used by the function, as it could create an
-- infinite loop.
-- protectionObj:isProtected - returns a boolean showing whether the page is
-- protected.
-- protectionObj:isTemporary - returns a boolean showing whether the expiry is
-- temporary.
-- protectionObj:isIncorrect - returns a boolean showing whether the protection
-- template is incorrect.
--]]
-- The master banner data, used if no values have been found in banners or
-- defaultBanners.
masterBanner = {
text = '${INTROBLURB}',
explanation = '${EXPLANATIONBLURB}',
tooltip = '${TOOLTIPBLURB}',
link = '${IMAGELINK}',
alt = 'Page ${PROTECTIONLEVEL}'
},
-- The default banner data. This holds banner data for different protection
-- levels.
-- *required* - this table needs edit, move, autoreview and upload subtables.
defaultBanners = {
edit = {},
move = {},
autoreview = {
default = {
alt = 'Page protected with pending changes',
tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users',
image = 'Pending-protection-shackle.svg'
}
},
upload = {}
},
-- The banner data. This holds banner data for different protection reasons.
-- In fact, the reasons specified in this table control which reasons are
-- valid inputs to the first positional parameter.
--
-- There is also a non-standard "description" field that can be used for items
-- in this table. This is a description of the protection reason for use in the
-- module documentation.
--
-- *required* - this table needs edit, move, autoreview and upload subtables.
banners = {
edit = {
blp = {
description = 'For pages protected to promote compliance with the'
.. ' [[Wikipedia:Biographies of living persons'
.. '|biographies of living persons]] policy',
text = '${INTROFRAGMENT} to promote compliance with'
.. ' [[Wikipedia:Biographies of living persons'
.. "|Wikipedia's policy on the biographies"
.. ' of living people]].',
tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on'
.. ' biographies of living persons',
},
deceased = {
description = 'For user pages of Wikipedia users who are deceased',
text = '${INTROFRAGMENT} to prevent vandalism of a deceased'
.. ' Wikipedian\'s user page.'
.. ' A family member who wishes to edit this user page can use this'
.. ' user\'s ${TALKPAGE} or submit a request to [[Wikipedia:VRT|the'
.. ' Volunteer Response Team]].',
tooltip = '${TOOLTIPFRAGMENT} because this Wikipedian is deceased'
},
dmca = {
description = 'For pages protected by the Wikimedia Foundation'
.. ' due to [[Digital Millennium Copyright Act]] takedown requests',
explanation = function (protectionObj, args)
local ret = 'Pursuant to a rights owner notice under the Digital'
.. ' Millennium Copyright Act (DMCA) regarding some content'
.. ' in this article, the Wikimedia Foundation acted under'
.. ' applicable law and took down and restricted the content'
.. ' in question.'
if args.notice then
ret = ret .. ' A copy of the received notice can be found here: '
.. args.notice .. '.'
end
ret = ret .. ' For more information, including websites discussing'
.. ' how to file a counter-notice, please see'
.. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}."
.. "'''Do not remove this template from the article until the"
.. " restrictions are withdrawn'''."
return ret
end,
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
dispute = {
description = 'For pages protected due to editing disputes',
text = function (protectionObj, args)
-- Find the value of "disputes".
local display = 'disputes'
local disputes
if args.section then
disputes = string.format(
'[[%s:%s#%s|%s]]',
mw.site.namespaces[protectionObj.title.namespace].talk.name,
protectionObj.title.text,
args.section,
display
)
else
disputes = display
end
-- Make the blurb, depending on the expiry.
local msg
if type(protectionObj.expiry) == 'number' then
msg = '${INTROFRAGMENT} or until editing %s have been resolved.'
else
msg = '${INTROFRAGMENT} until editing %s have been resolved.'
end
return string.format(msg, disputes)
end,
explanation = "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}',
tooltip = '${TOOLTIPFRAGMENT} due to editing disputes',
},
ecp = {
description = 'For articles in topic areas authorized by'
.. ' [[Wikipedia:Arbitration Committee|ArbCom]] or'
.. ' meets the criteria for community use',
alt = 'Extended-protected ${PAGETYPE}',
},
mainpage = {
description = 'For pages protected for being displayed on the [[Main Page]]',
text = 'This file is currently'
.. ' [[Wikipedia:This page is protected|protected]] from'
.. ' editing because it is currently or will soon be displayed'
.. ' on the [[Main Page]].',
explanation = 'Images on the Main Page are protected due to their high'
.. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.'
.. '<br /><span style="font-size:90%;">'
.. "'''Administrators:''' Once this image is definitely off the Main Page,"
.. ' please unprotect this file, or reduce to semi-protection,'
.. ' as appropriate.</span>',
},
office = {
description = 'For pages protected by the Wikimedia Foundation',
text = function (protectionObj, args)
local ret = 'This ${PAGETYPE} is currently under the'
.. ' scrutiny of the'
.. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]'
.. ' and is protected.'
if protectionObj.protectionDate then
ret = ret .. ' It has been protected since ${PROTECTIONDATE}.'
end
return ret
end,
explanation = "If you can edit this page, please discuss all changes and"
.. " additions on the ${TALKPAGE} first. '''Do not remove protection from this"
.. " page unless you are authorized by the Wikimedia Foundation to do"
.. " so.'''",
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
reset = {
description = 'For pages protected by the Wikimedia Foundation and'
.. ' "reset" to a bare-bones version',
text = 'This ${PAGETYPE} is currently under the'
.. ' scrutiny of the'
.. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]'
.. ' and is protected.',
explanation = function (protectionObj, args)
local ret = ''
if protectionObj.protectionDate then
ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was'
else
ret = ret .. 'This ${PAGETYPE} has been'
end
ret = ret .. ' reduced to a'
.. ' simplified, "bare bones" version so that it may be completely'
.. ' rewritten to ensure it meets the policies of'
.. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].'
.. ' Standard Wikipedia policies will apply to its rewriting—which'
.. ' will eventually be open to all editors—and will be strictly'
.. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while'
.. ' it is being rebuilt.\n\n'
.. 'Any insertion of material directly from'
.. ' pre-protection revisions of the ${PAGETYPE} will be removed, as'
.. ' will any material added to the ${PAGETYPE} that is not properly'
.. ' sourced. The associated talk page(s) were also cleared on the'
.. " same date.\n\n"
.. "If you can edit this page, please discuss all changes and"
.. " additions on the ${TALKPAGE} first. '''Do not override"
.. " this action, and do not remove protection from this page,"
.. " unless you are authorized by the Wikimedia Foundation"
.. " to do so. No editor may remove this notice.'''"
return ret
end,
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
sock = {
description = 'For pages protected due to'
.. ' [[Wikipedia:Sock puppetry|sock puppetry]]',
text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of'
.. ' [[Wikipedia:Blocking policy|blocked]] or'
.. ' [[Wikipedia:Banning policy|banned users]]'
.. ' from editing it.',
tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from'
.. ' editing it',
},
template = {
description = 'For [[Wikipedia:High-risk templates|high-risk]]'
.. ' templates and Lua modules',
text = 'This is a permanently [[Wikipedia:Protection policy|protected]] ${PAGETYPE},'
.. ' as it is [[Wikipedia:High-risk templates|high-risk]].',
explanation = 'Please discuss any changes on the ${TALKPAGE}; you may'
.. ' ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] or'
.. ' [[Wikipedia:Template editor|template editor]] to make an edit if'
.. ' it is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by'
.. ' [[Wikipedia:Consensus|consensus]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.',
tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}'
.. ' to prevent vandalism',
alt = 'Permanently protected ${PAGETYPE}',
},
usertalk = {
description = 'For pages protected against disruptive edits by a'
.. ' particular user',
text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,'
.. ' such as abusing the'
.. ' {{[[Template:unblock|unblock]]}} template.',
explanation = 'If you cannot edit this user talk page and you need to'
.. ' make a change or leave a message, you can'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for edits to a protected page'
.. '|request an edit]],'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]],'
.. ' [[Special:Userlogin|log in]],'
.. ' or [[Special:UserLogin/signup|create an account]].',
},
vandalism = {
description = 'For pages protected against'
.. ' [[Wikipedia:Vandalism|vandalism]]',
text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].',
explanation = function (protectionObj, args)
local ret = ''
if protectionObj.level == 'sysop' then
ret = ret .. "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. '
end
return ret .. '${EXPLANATIONBLURB}'
end,
tooltip = '${TOOLTIPFRAGMENT} due to vandalism',
}
},
move = {
dispute = {
description = 'For pages protected against page moves due to'
.. ' disputes over the page title',
explanation = "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}',
image = 'Move-protection-shackle.svg'
},
vandalism = {
description = 'For pages protected against'
.. ' [[Wikipedia:Vandalism#Page-move vandalism'
.. ' |page-move vandalism]]'
}
},
autoreview = {},
upload = {}
},
--------------------------------------------------------------------------------
--
-- GENERAL DATA TABLES
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Protection blurbs
--------------------------------------------------------------------------------
-- This table produces the protection blurbs available with the
-- ${PROTECTIONBLURB} parameter. It is sorted by protection action and
-- protection level, and is checked by the module in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
protectionBlurbs = {
edit = {
default = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#full|'
.. 'protected]] from editing',
templateeditor = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#template'
.. '|protected]] from editing',
autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access'
.. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered'
.. ' users|unregistered]] users is currently [[Wikipedia:Protection'
.. ' policy#semi|disabled]]',
extendedconfirmed = 'This ${PAGETYPE} is currently under [[Wikipedia:Protection'
.. ' policy#extended|extended confirmed protection]]',
},
move = {
default = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#Move'
.. ' protection|protected]] from [[Help:Moving a page|page moves]]'
},
autoreview = {
default = 'All edits made to this ${PAGETYPE} by'
.. ' [[Wikipedia:User access levels#New users|new]] or'
.. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]'
.. ' users are currently'
.. ' [[Wikipedia:Pending changes|subject to review]]'
},
upload = {
default = 'Uploading new versions of this ${PAGETYPE} is currently disabled'
}
},
--------------------------------------------------------------------------------
-- Explanation blurbs
--------------------------------------------------------------------------------
-- This table produces the explanation blurbs available with the
-- ${EXPLANATIONBLURB} parameter. It is sorted by protection action,
-- protection level, and whether the page is a talk page or not. If the page is
-- a talk page it will have a talk key of "talk"; otherwise it will have a talk
-- key of "subject". The table is checked in the following order:
-- 1. page's protection action, page's protection level, page's talk key
-- 2. page's protection action, page's protection level, default talk key
-- 3. page's protection action, default protection level, page's talk key
-- 4. page's protection action, default protection level, default talk key
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
explanationBlurbs = {
edit = {
autoconfirmed = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details. If you'
.. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can'
.. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details. If you'
.. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].',
},
extendedconfirmed = {
default = 'Extended confirmed protection prevents edits from all unregistered editors'
.. ' and registered users with fewer than 30 days tenure and 500 edits.'
.. ' The [[Wikipedia:Protection policy#extended|policy on community use]]'
.. ' specifies that extended confirmed protection can be applied to combat'
.. ' disruption, if semi-protection has proven to be ineffective.'
.. ' Extended confirmed protection may also be applied to enforce'
.. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].'
.. ' Please discuss any changes on the ${TALKPAGE}; you may'
.. ' ${EDITREQUEST} to ask for uncontroversial changes supported by'
.. ' [[Wikipedia:Consensus|consensus]].'
},
default = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Please discuss any changes on the ${TALKPAGE}; you'
.. ' may ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] to make an edit if it'
.. ' is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by [[Wikipedia:Consensus'
.. '|consensus]]. You may also [[Wikipedia:Requests for'
.. ' page protection#Current requests for reduction in protection level'
.. '|request]] that this page be unprotected.',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' You may [[Wikipedia:Requests for page'
.. ' protection#Current requests for edits to a protected page|request an'
.. ' edit]] to this page, or [[Wikipedia:Requests for'
.. ' page protection#Current requests for reduction in protection level'
.. '|ask]] for it to be unprotected.'
}
},
move = {
default = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but cannot be moved'
.. ' until unprotected. Please discuss any suggested moves on the'
.. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but cannot be moved'
.. ' until unprotected. Please discuss any suggested moves at'
.. ' [[Wikipedia:Requested moves]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.'
}
},
autoreview = {
default = {
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Edits to this ${PAGETYPE} by new and unregistered users'
.. ' will not be visible to readers until they are accepted by'
.. ' a reviewer. To avoid the need for your edits to be'
.. ' reviewed, you may'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].'
},
},
upload = {
default = {
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but new versions of the file'
.. ' cannot be uploaded until it is unprotected. You can'
.. ' request that a new version be uploaded by using a'
.. ' [[Wikipedia:Edit requests|protected edit request]], or you'
.. ' can [[Wikipedia:Requests for page protection|request]]'
.. ' that the file be unprotected.'
}
}
},
--------------------------------------------------------------------------------
-- Protection levels
--------------------------------------------------------------------------------
-- This table provides the data for the ${PROTECTIONLEVEL} parameter, which
-- produces a short label for different protection levels. It is sorted by
-- protection action and protection level, and is checked in the following
-- order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
protectionLevels = {
edit = {
default = 'protected',
templateeditor = 'template-protected',
extendedconfirmed = 'extended-confirmed-protected',
autoconfirmed = 'semi-protected',
},
move = {
default = 'move-protected'
},
autoreview = {
},
upload = {
default = 'upload-protected'
}
},
--------------------------------------------------------------------------------
-- Images
--------------------------------------------------------------------------------
-- This table lists different padlock images for each protection action and
-- protection level. It is used if an image is not specified in any of the
-- banner data tables, and if the page does not satisfy the conditions for using
-- the ['image-filename-indef'] image. It is checked in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
images = {
edit = {
default = 'Full-protection-shackle.svg',
templateeditor = 'Template-protection-shackle.svg',
extendedconfirmed = 'Extended-protection-shackle.svg',
autoconfirmed = 'Semi-protection-shackle.svg'
},
move = {
default = 'Move-protection-shackle.svg',
},
autoreview = {
default = 'Pending-protection-shackle.svg'
},
upload = {
default = 'Upload-protection-shackle.svg'
}
},
-- Pages with a reason specified in this table will show the special "indef"
-- padlock, defined in the 'image-filename-indef' message, if no expiry is set.
indefImageReasons = {
template = true
},
--------------------------------------------------------------------------------
-- Image links
--------------------------------------------------------------------------------
-- This table provides the data for the ${IMAGELINK} parameter, which gets
-- the image link for small padlock icons based on the page's protection action
-- and protection level. It is checked in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
imageLinks = {
edit = {
default = 'Wikipedia:Protection policy#full',
templateeditor = 'Wikipedia:Protection policy#template',
extendedconfirmed = 'Wikipedia:Protection policy#extended',
autoconfirmed = 'Wikipedia:Protection policy#semi'
},
move = {
default = 'Wikipedia:Protection policy#move'
},
autoreview = {
default = 'Wikipedia:Protection policy#pending'
},
upload = {
default = 'Wikipedia:Protection policy#upload'
}
},
--------------------------------------------------------------------------------
-- Padlock indicator names
--------------------------------------------------------------------------------
-- This table provides the "name" attribute for the <indicator> extension tag
-- with which small padlock icons are generated. All indicator tags on a page
-- are displayed in alphabetical order based on this attribute, and with
-- indicator tags with duplicate names, the last tag on the page wins.
-- The attribute is chosen based on the protection action; table keys must be a
-- protection action name or the string "default".
padlockIndicatorNames = {
autoreview = 'pp-autoreview',
default = 'pp-default'
},
--------------------------------------------------------------------------------
-- Protection categories
--------------------------------------------------------------------------------
--[[
-- The protection categories are stored in the protectionCategories table.
-- Keys to this table are made up of the following strings:
--
-- 1. the expiry date
-- 2. the namespace
-- 3. the protection reason (e.g. "dispute" or "vandalism")
-- 4. the protection level (e.g. "sysop" or "autoconfirmed")
-- 5. the action (e.g. "edit" or "move")
--
-- When the module looks up a category in the table, first it will will check to
-- see a key exists that corresponds to all five parameters. For example, a
-- user page semi-protected from vandalism for two weeks would have the key
-- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module
-- changes the first part of the key to "all" and checks the table again. It
-- keeps checking increasingly generic key combinations until it finds the
-- field, or until it reaches the key "all-all-all-all-all".
--
-- The module uses a binary matrix to determine the order in which to search.
-- This is best demonstrated by a table. In this table, the "0" values
-- represent "all", and the "1" values represent the original data (e.g.
-- "indef" or "file" or "vandalism").
--
-- expiry namespace reason level action
-- order
-- 1 1 1 1 1 1
-- 2 0 1 1 1 1
-- 3 1 0 1 1 1
-- 4 0 0 1 1 1
-- 5 1 1 0 1 1
-- 6 0 1 0 1 1
-- 7 1 0 0 1 1
-- 8 0 0 0 1 1
-- 9 1 1 1 0 1
-- 10 0 1 1 0 1
-- 11 1 0 1 0 1
-- 12 0 0 1 0 1
-- 13 1 1 0 0 1
-- 14 0 1 0 0 1
-- 15 1 0 0 0 1
-- 16 0 0 0 0 1
-- 17 1 1 1 1 0
-- 18 0 1 1 1 0
-- 19 1 0 1 1 0
-- 20 0 0 1 1 0
-- 21 1 1 0 1 0
-- 22 0 1 0 1 0
-- 23 1 0 0 1 0
-- 24 0 0 0 1 0
-- 25 1 1 1 0 0
-- 26 0 1 1 0 0
-- 27 1 0 1 0 0
-- 28 0 0 1 0 0
-- 29 1 1 0 0 0
-- 30 0 1 0 0 0
-- 31 1 0 0 0 0
-- 32 0 0 0 0 0
--
-- In this scheme the action has the highest priority, as it is the last
-- to change, and the expiry has the least priority, as it changes the most.
-- The priorities of the expiry, the protection level and the action are
-- fixed, but the priorities of the reason and the namespace can be swapped
-- through the use of the cfg.bannerDataNamespaceHasPriority table.
--]]
-- If the reason specified to the template is listed in this table,
-- namespace data will take priority over reason data in the protectionCategories
-- table.
reasonsWithNamespacePriority = {
vandalism = true,
},
-- The string to use as a namespace key for the protectionCategories table for each
-- namespace number.
categoryNamespaceKeys = {
[ 2] = 'user',
[ 3] = 'user',
[ 4] = 'project',
[ 6] = 'file',
[ 8] = 'mediawiki',
[ 10] = 'template',
[ 12] = 'project',
[ 14] = 'category',
[100] = 'portal',
[828] = 'module',
},
protectionCategories = {
['all|all|all|all|all'] = 'Wikipedia fully protected pages',
['all|all|office|all|all'] = 'Wikipedia Office-protected pages',
['all|all|reset|all|all'] = 'Wikipedia Office-protected pages',
['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages',
['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files',
['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages',
['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages',
['all|template|all|all|edit'] = 'Wikipedia fully protected templates',
['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages',
['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages',
['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people',
['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people',
['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute',
['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users',
['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism',
['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories',
['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files',
['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals',
['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages',
['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages',
['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates',
['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages',
['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules',
['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules',
['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates',
['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates
['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people',
['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people',
['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute',
['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users',
['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism',
['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories',
['all|file|all|sysop|edit'] = 'Wikipedia fully protected files',
['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages',
['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages',
['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates',
['all|template|all|extendedconfirmed|move'] = 'Wikipedia extended-confirmed-protected templates',
['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates',
['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages',
['all|module|all|all|edit'] = 'Wikipedia fully protected modules',
['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules',
['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules',
['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules',
['all|all|all|sysop|move'] = 'Wikipedia move-protected pages',
['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages',
['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute',
['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism',
['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals',
['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages',
['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages',
['all|template|all|sysop|move'] = 'Wikipedia move-protected templates',
['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages',
['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages',
['all|file|all|all|upload'] = 'Wikipedia upload-protected files',
},
--------------------------------------------------------------------------------
-- Expiry category config
--------------------------------------------------------------------------------
-- This table configures the expiry category behaviour for each protection
-- action.
-- * If set to true, setting that action will always categorise the page if
-- an expiry parameter is not set.
-- * If set to false, setting that action will never categorise the page.
-- * If set to nil, the module will categorise the page if:
-- 1) an expiry parameter is not set, and
-- 2) a reason is provided, and
-- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck
-- table.
expiryCheckActions = {
edit = nil,
move = false,
autoreview = true,
upload = false
},
reasonsWithoutExpiryCheck = {
blp = true,
template = true,
},
--------------------------------------------------------------------------------
-- Pagetypes
--------------------------------------------------------------------------------
-- This table produces the page types available with the ${PAGETYPE} parameter.
-- Keys are namespace numbers, or the string "default" for the default value.
pagetypes = {
[0] = 'article',
[6] = 'file',
[10] = 'template',
[14] = 'category',
[828] = 'module',
default = 'page'
},
--------------------------------------------------------------------------------
-- Strings marking indefinite protection
--------------------------------------------------------------------------------
-- This table contains values passed to the expiry parameter that mean the page
-- is protected indefinitely.
indefStrings = {
['indef'] = true,
['indefinite'] = true,
['indefinitely'] = true,
['infinite'] = true,
},
--------------------------------------------------------------------------------
-- Group hierarchy
--------------------------------------------------------------------------------
-- This table maps each group to all groups that have a superset of the original
-- group's page editing permissions.
hierarchy = {
sysop = {},
reviewer = {'sysop'},
filemover = {'sysop'},
templateeditor = {'sysop'},
extendedconfirmed = {'sysop'},
autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'},
user = {'autoconfirmed'},
['*'] = {'user'}
},
--------------------------------------------------------------------------------
-- Wrapper templates and their default arguments
--------------------------------------------------------------------------------
-- This table contains wrapper templates used with the module, and their
-- default arguments. Templates specified in this table should contain the
-- following invocation, and no other template content:
--
-- {{#invoke:Protection banner|main}}
--
-- If other content is desired, it can be added between
-- <noinclude>...</noinclude> tags.
--
-- When a user calls one of these wrapper templates, they will use the
-- default arguments automatically. However, users can override any of the
-- arguments.
wrappers = {
['Template:Protected page'] = {},
['Template:Extended confirmed–protected'] = {'ecp'},
['Template:Protected biography of a living person'] = {'blp'},
['Template:Protected due to a dispute'] = {'dispute'},
['Template:Move-protected'] = {action = 'move', catonly = 'yes'},
['Template:Move-protected due to a dispute'] = {'dispute', action = 'move', catonly = 'yes'},
['Template:Move-protected due to vandalism'] = {'vandalism', action = 'move', catonly = 'yes'},
['Template:Office-protected'] = {'office'},
['Template:Pending changes–protected'] = {action = 'autoreview', small = true},
['Template:Semi-protected indefinitely'] = {small = true},
['Template:Protected due to sockpuppetry'] = {'sock'},
['Template:Protected template'] = {'template', small = true},
['Template:Upload-protected'] = {action = 'upload'},
['Template:Protected talk page of a blocked user'] = {'usertalk'},
['Template:Protected due to vandalism'] = {'vandalism'},
},
--------------------------------------------------------------------------------
--
-- MESSAGES
--
--------------------------------------------------------------------------------
msg = {
--------------------------------------------------------------------------------
-- Intro blurb and intro fragment
--------------------------------------------------------------------------------
-- These messages specify what is produced by the ${INTROBLURB} and
-- ${INTROFRAGMENT} parameters. If the protection is temporary they use the
-- intro-blurb-expiry or intro-fragment-expiry, and if not they use
-- intro-blurb-noexpiry or intro-fragment-noexpiry.
-- It is possible to use banner parameters in these messages.
['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.',
['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.',
['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},',
['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}',
--------------------------------------------------------------------------------
-- Tooltip blurb
--------------------------------------------------------------------------------
-- These messages specify what is produced by the ${TOOLTIPBLURB} parameter.
-- If the protection is temporary the tooltip-blurb-expiry message is used, and
-- if not the tooltip-blurb-noexpiry message is used.
-- It is possible to use banner parameters in these messages.
['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.',
['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.',
['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},',
['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}',
--------------------------------------------------------------------------------
-- Special explanation blurb
--------------------------------------------------------------------------------
-- An explanation blurb for pages that cannot be unprotected, e.g. for pages
-- in the MediaWiki namespace.
-- It is possible to use banner parameters in this message.
['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Please discuss any changes on the ${TALKPAGE}; you'
.. ' may ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] to make an edit if it'
.. ' is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by [[Wikipedia:Consensus'
.. '|consensus]].',
--------------------------------------------------------------------------------
-- Protection log display values
--------------------------------------------------------------------------------
-- These messages determine the display values for the protection log link
-- or the pending changes log link produced by the ${PROTECTIONLOG} parameter.
-- It is possible to use banner parameters in these messages.
['protection-log-display'] = 'protection log',
['pc-log-display'] = 'pending changes log',
--------------------------------------------------------------------------------
-- Current version display values
--------------------------------------------------------------------------------
-- These messages determine the display values for the page history link
-- or the move log link produced by the ${CURRENTVERSION} parameter.
-- It is possible to use banner parameters in these messages.
['current-version-move-display'] = 'current title',
['current-version-edit-display'] = 'current version',
--------------------------------------------------------------------------------
-- Talk page
--------------------------------------------------------------------------------
-- This message determines the display value of the talk page link produced
-- with the ${TALKPAGE} parameter.
-- It is possible to use banner parameters in this message.
['talk-page-link-display'] = 'talk page',
--------------------------------------------------------------------------------
-- Edit requests
--------------------------------------------------------------------------------
-- This message determines the display value of the edit request link produced
-- with the ${EDITREQUEST} parameter.
-- It is possible to use banner parameters in this message.
['edit-request-display'] = 'submit an edit request',
--------------------------------------------------------------------------------
-- Expiry date format
--------------------------------------------------------------------------------
-- This is the format for the blurb expiry date. It should be valid input for
-- the first parameter of the #time parser function.
['expiry-date-format'] = 'F j, Y "at" H:i e',
--------------------------------------------------------------------------------
-- Tracking categories
--------------------------------------------------------------------------------
-- These messages determine which tracking categories the module outputs.
['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates',
['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules',
--------------------------------------------------------------------------------
-- Images
--------------------------------------------------------------------------------
-- These are images that are not defined by their protection action and protection level.
['image-filename-indef'] = 'Full-protection-shackle.svg',
['image-filename-default'] = 'Transparent.gif',
--------------------------------------------------------------------------------
-- End messages
--------------------------------------------------------------------------------
}
--------------------------------------------------------------------------------
-- End configuration
--------------------------------------------------------------------------------
}
k108n3hntzssp9cyjanrmu01ygggcb9
124222
124221
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Protected_page/config]]
124221
Scribunto
text/plain
-- This module provides configuration data for [[Module:Protection banner]].
return {
--------------------------------------------------------------------------------
--
-- BANNER DATA
--
--------------------------------------------------------------------------------
--[[
-- Banner data consists of six fields:
-- * text - the main protection text that appears at the top of protection
-- banners.
-- * explanation - the text that appears below the main protection text, used
-- to explain the details of the protection.
-- * tooltip - the tooltip text you see when you move the mouse over a small
-- padlock icon.
-- * link - the page that the small padlock icon links to.
-- * alt - the alt text for the small padlock icon. This is also used as tooltip
-- text for the large protection banners.
-- * image - the padlock image used in both protection banners and small padlock
-- icons.
--
-- The module checks in three separate tables to find a value for each field.
-- First it checks the banners table, which has values specific to the reason
-- for the page being protected. Then the module checks the defaultBanners
-- table, which has values specific to each protection level. Finally, the
-- module checks the masterBanner table, which holds data for protection
-- templates to use if no data has been found in the previous two tables.
--
-- The values in the banner data can take parameters. These are specified
-- using ${TEXTLIKETHIS} (a dollar sign preceding a parameter name
-- enclosed in curly braces).
--
-- Available parameters:
--
-- ${CURRENTVERSION} - a link to the page history or the move log, with the
-- display message "current-version-edit-display" or
-- "current-version-move-display".
--
-- ${EDITREQUEST} - a link to create an edit request for the current page.
--
-- ${EXPLANATIONBLURB} - an explanation blurb, e.g. "Please discuss any changes
-- on the talk page; you may submit a request to ask an administrator to make
-- an edit if it is minor or supported by consensus."
--
-- ${IMAGELINK} - a link to set the image to, depending on the protection
-- action and protection level.
--
-- ${INTROBLURB} - the PROTECTIONBLURB parameter, plus the expiry if an expiry
-- is set. E.g. "Editing of this page by new or unregistered users is currently
-- disabled until dd Month YYYY."
--
-- ${INTROFRAGMENT} - the same as ${INTROBLURB}, but without final punctuation
-- so that it can be used in run-on sentences.
--
-- ${PAGETYPE} - the type of the page, e.g. "article" or "template".
-- Defined in the cfg.pagetypes table.
--
-- ${PROTECTIONBLURB} - a blurb explaining the protection level of the page, e.g.
-- "Editing of this page by new or unregistered users is currently disabled"
--
-- ${PROTECTIONDATE} - the protection date, if it has been supplied to the
-- template.
--
-- ${PROTECTIONLEVEL} - the protection level, e.g. "fully protected" or
-- "semi-protected".
--
-- ${PROTECTIONLOG} - a link to the protection log or the pending changes log,
-- depending on the protection action.
--
-- ${TALKPAGE} - a link to the talk page. If a section is specified, links
-- straight to that talk page section.
--
-- ${TOOLTIPBLURB} - uses the PAGETYPE, PROTECTIONTYPE and EXPIRY parameters to
-- create a blurb like "This template is semi-protected", or "This article is
-- move-protected until DD Month YYYY".
--
-- ${VANDAL} - links for the specified username (or the root page name)
-- using Module:Vandal-m.
--
-- Functions
--
-- For advanced users, it is possible to use Lua functions instead of strings
-- in the banner config tables. Using functions gives flexibility that is not
-- possible just by using parameters. Functions take two arguments, the
-- protection object and the template arguments, and they must output a string.
--
-- For example:
--
-- text = function (protectionObj, args)
-- if protectionObj.level == 'autoconfirmed' then
-- return 'foo'
-- else
-- return 'bar'
-- end
-- end
--
-- Some protection object properties and methods that may be useful:
-- protectionObj.action - the protection action
-- protectionObj.level - the protection level
-- protectionObj.reason - the protection reason
-- protectionObj.expiry - the expiry. Nil if unset, the string "indef" if set
-- to indefinite, and the protection time in unix time if temporary.
-- protectionObj.protectionDate - the protection date in unix time, or nil if
-- unspecified.
-- protectionObj.bannerConfig - the banner config found by the module. Beware
-- of editing the config field used by the function, as it could create an
-- infinite loop.
-- protectionObj:isProtected - returns a boolean showing whether the page is
-- protected.
-- protectionObj:isTemporary - returns a boolean showing whether the expiry is
-- temporary.
-- protectionObj:isIncorrect - returns a boolean showing whether the protection
-- template is incorrect.
--]]
-- The master banner data, used if no values have been found in banners or
-- defaultBanners.
masterBanner = {
text = '${INTROBLURB}',
explanation = '${EXPLANATIONBLURB}',
tooltip = '${TOOLTIPBLURB}',
link = '${IMAGELINK}',
alt = 'Page ${PROTECTIONLEVEL}'
},
-- The default banner data. This holds banner data for different protection
-- levels.
-- *required* - this table needs edit, move, autoreview and upload subtables.
defaultBanners = {
edit = {},
move = {},
autoreview = {
default = {
alt = 'Page protected with pending changes',
tooltip = 'All edits by unregistered and new users are subject to review prior to becoming visible to unregistered users',
image = 'Pending-protection-shackle.svg'
}
},
upload = {}
},
-- The banner data. This holds banner data for different protection reasons.
-- In fact, the reasons specified in this table control which reasons are
-- valid inputs to the first positional parameter.
--
-- There is also a non-standard "description" field that can be used for items
-- in this table. This is a description of the protection reason for use in the
-- module documentation.
--
-- *required* - this table needs edit, move, autoreview and upload subtables.
banners = {
edit = {
blp = {
description = 'For pages protected to promote compliance with the'
.. ' [[Wikipedia:Biographies of living persons'
.. '|biographies of living persons]] policy',
text = '${INTROFRAGMENT} to promote compliance with'
.. ' [[Wikipedia:Biographies of living persons'
.. "|Wikipedia's policy on the biographies"
.. ' of living people]].',
tooltip = '${TOOLTIPFRAGMENT} to promote compliance with the policy on'
.. ' biographies of living persons',
},
deceased = {
description = 'For user pages of Wikipedia users who are deceased',
text = '${INTROFRAGMENT} to prevent vandalism of a deceased'
.. ' Wikipedian\'s user page.'
.. ' A family member who wishes to edit this user page can use this'
.. ' user\'s ${TALKPAGE} or submit a request to [[Wikipedia:VRT|the'
.. ' Volunteer Response Team]].',
tooltip = '${TOOLTIPFRAGMENT} because this Wikipedian is deceased'
},
dmca = {
description = 'For pages protected by the Wikimedia Foundation'
.. ' due to [[Digital Millennium Copyright Act]] takedown requests',
explanation = function (protectionObj, args)
local ret = 'Pursuant to a rights owner notice under the Digital'
.. ' Millennium Copyright Act (DMCA) regarding some content'
.. ' in this article, the Wikimedia Foundation acted under'
.. ' applicable law and took down and restricted the content'
.. ' in question.'
if args.notice then
ret = ret .. ' A copy of the received notice can be found here: '
.. args.notice .. '.'
end
ret = ret .. ' For more information, including websites discussing'
.. ' how to file a counter-notice, please see'
.. " [[Wikipedia:Office actions]] and the article's ${TALKPAGE}."
.. "'''Do not remove this template from the article until the"
.. " restrictions are withdrawn'''."
return ret
end,
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
dispute = {
description = 'For pages protected due to editing disputes',
text = function (protectionObj, args)
-- Find the value of "disputes".
local display = 'disputes'
local disputes
if args.section then
disputes = string.format(
'[[%s:%s#%s|%s]]',
mw.site.namespaces[protectionObj.title.namespace].talk.name,
protectionObj.title.text,
args.section,
display
)
else
disputes = display
end
-- Make the blurb, depending on the expiry.
local msg
if type(protectionObj.expiry) == 'number' then
msg = '${INTROFRAGMENT} or until editing %s have been resolved.'
else
msg = '${INTROFRAGMENT} until editing %s have been resolved.'
end
return string.format(msg, disputes)
end,
explanation = "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}',
tooltip = '${TOOLTIPFRAGMENT} due to editing disputes',
},
ecp = {
description = 'For articles in topic areas authorized by'
.. ' [[Wikipedia:Arbitration Committee|ArbCom]] or'
.. ' meets the criteria for community use',
alt = 'Extended-protected ${PAGETYPE}',
},
mainpage = {
description = 'For pages protected for being displayed on the [[Main Page]]',
text = 'This file is currently'
.. ' [[Wikipedia:This page is protected|protected]] from'
.. ' editing because it is currently or will soon be displayed'
.. ' on the [[Main Page]].',
explanation = 'Images on the Main Page are protected due to their high'
.. ' visibility. Please discuss any necessary changes on the ${TALKPAGE}.'
.. '<br /><span style="font-size:90%;">'
.. "'''Administrators:''' Once this image is definitely off the Main Page,"
.. ' please unprotect this file, or reduce to semi-protection,'
.. ' as appropriate.</span>',
},
office = {
description = 'For pages protected by the Wikimedia Foundation',
text = function (protectionObj, args)
local ret = 'This ${PAGETYPE} is currently under the'
.. ' scrutiny of the'
.. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]'
.. ' and is protected.'
if protectionObj.protectionDate then
ret = ret .. ' It has been protected since ${PROTECTIONDATE}.'
end
return ret
end,
explanation = "If you can edit this page, please discuss all changes and"
.. " additions on the ${TALKPAGE} first. '''Do not remove protection from this"
.. " page unless you are authorized by the Wikimedia Foundation to do"
.. " so.'''",
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
reset = {
description = 'For pages protected by the Wikimedia Foundation and'
.. ' "reset" to a bare-bones version',
text = 'This ${PAGETYPE} is currently under the'
.. ' scrutiny of the'
.. ' [[Wikipedia:Office actions|Wikimedia Foundation Office]]'
.. ' and is protected.',
explanation = function (protectionObj, args)
local ret = ''
if protectionObj.protectionDate then
ret = ret .. 'On ${PROTECTIONDATE} this ${PAGETYPE} was'
else
ret = ret .. 'This ${PAGETYPE} has been'
end
ret = ret .. ' reduced to a'
.. ' simplified, "bare bones" version so that it may be completely'
.. ' rewritten to ensure it meets the policies of'
.. ' [[WP:NPOV|Neutral Point of View]] and [[WP:V|Verifiability]].'
.. ' Standard Wikipedia policies will apply to its rewriting—which'
.. ' will eventually be open to all editors—and will be strictly'
.. ' enforced. The ${PAGETYPE} has been ${PROTECTIONLEVEL} while'
.. ' it is being rebuilt.\n\n'
.. 'Any insertion of material directly from'
.. ' pre-protection revisions of the ${PAGETYPE} will be removed, as'
.. ' will any material added to the ${PAGETYPE} that is not properly'
.. ' sourced. The associated talk page(s) were also cleared on the'
.. " same date.\n\n"
.. "If you can edit this page, please discuss all changes and"
.. " additions on the ${TALKPAGE} first. '''Do not override"
.. " this action, and do not remove protection from this page,"
.. " unless you are authorized by the Wikimedia Foundation"
.. " to do so. No editor may remove this notice.'''"
return ret
end,
image = 'Office-protection-shackle.svg',
link = 'Wikipedia:Protection policy#office',
},
sock = {
description = 'For pages protected due to'
.. ' [[Wikipedia:Sock puppetry|sock puppetry]]',
text = '${INTROFRAGMENT} to prevent [[Wikipedia:Sock puppetry|sock puppets]] of'
.. ' [[Wikipedia:Blocking policy|blocked]] or'
.. ' [[Wikipedia:Banning policy|banned users]]'
.. ' from editing it.',
tooltip = '${TOOLTIPFRAGMENT} to prevent sock puppets of blocked or banned users from'
.. ' editing it',
},
template = {
description = 'For [[Wikipedia:High-risk templates|high-risk]]'
.. ' templates and Lua modules',
text = 'This is a permanently [[Wikipedia:Protection policy|protected]] ${PAGETYPE},'
.. ' as it is [[Wikipedia:High-risk templates|high-risk]].',
explanation = 'Please discuss any changes on the ${TALKPAGE}; you may'
.. ' ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] or'
.. ' [[Wikipedia:Template editor|template editor]] to make an edit if'
.. ' it is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by'
.. ' [[Wikipedia:Consensus|consensus]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.',
tooltip = 'This high-risk ${PAGETYPE} is permanently ${PROTECTIONLEVEL}'
.. ' to prevent vandalism',
alt = 'Permanently protected ${PAGETYPE}',
},
usertalk = {
description = 'For pages protected against disruptive edits by a'
.. ' particular user',
text = '${INTROFRAGMENT} to prevent ${VANDAL} from using it to make disruptive edits,'
.. ' such as abusing the'
.. ' {{[[Template:unblock|unblock]]}} template.',
explanation = 'If you cannot edit this user talk page and you need to'
.. ' make a change or leave a message, you can'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for edits to a protected page'
.. '|request an edit]],'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]],'
.. ' [[Special:Userlogin|log in]],'
.. ' or [[Special:UserLogin/signup|create an account]].',
},
vandalism = {
description = 'For pages protected against'
.. ' [[Wikipedia:Vandalism|vandalism]]',
text = '${INTROFRAGMENT} due to [[Wikipedia:Vandalism|vandalism]].',
explanation = function (protectionObj, args)
local ret = ''
if protectionObj.level == 'sysop' then
ret = ret .. "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. '
end
return ret .. '${EXPLANATIONBLURB}'
end,
tooltip = '${TOOLTIPFRAGMENT} due to vandalism',
}
},
move = {
dispute = {
description = 'For pages protected against page moves due to'
.. ' disputes over the page title',
explanation = "This protection is '''not''' an endorsement of the"
.. ' ${CURRENTVERSION}. ${EXPLANATIONBLURB}',
image = 'Move-protection-shackle.svg'
},
vandalism = {
description = 'For pages protected against'
.. ' [[Wikipedia:Vandalism#Page-move vandalism'
.. ' |page-move vandalism]]'
}
},
autoreview = {},
upload = {}
},
--------------------------------------------------------------------------------
--
-- GENERAL DATA TABLES
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Protection blurbs
--------------------------------------------------------------------------------
-- This table produces the protection blurbs available with the
-- ${PROTECTIONBLURB} parameter. It is sorted by protection action and
-- protection level, and is checked by the module in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
protectionBlurbs = {
edit = {
default = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#full|'
.. 'protected]] from editing',
templateeditor = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#template'
.. '|protected]] from editing',
autoconfirmed = 'Editing of this ${PAGETYPE} by [[Wikipedia:User access'
.. ' levels#New users|new]] or [[Wikipedia:User access levels#Unregistered'
.. ' users|unregistered]] users is currently [[Wikipedia:Protection'
.. ' policy#semi|disabled]]',
extendedconfirmed = 'This ${PAGETYPE} is currently under [[Wikipedia:Protection'
.. ' policy#extended|extended confirmed protection]]',
},
move = {
default = 'This ${PAGETYPE} is currently [[Wikipedia:Protection policy#Move'
.. ' protection|protected]] from [[Help:Moving a page|page moves]]'
},
autoreview = {
default = 'All edits made to this ${PAGETYPE} by'
.. ' [[Wikipedia:User access levels#New users|new]] or'
.. ' [[Wikipedia:User access levels#Unregistered users|unregistered]]'
.. ' users are currently'
.. ' [[Wikipedia:Pending changes|subject to review]]'
},
upload = {
default = 'Uploading new versions of this ${PAGETYPE} is currently disabled'
}
},
--------------------------------------------------------------------------------
-- Explanation blurbs
--------------------------------------------------------------------------------
-- This table produces the explanation blurbs available with the
-- ${EXPLANATIONBLURB} parameter. It is sorted by protection action,
-- protection level, and whether the page is a talk page or not. If the page is
-- a talk page it will have a talk key of "talk"; otherwise it will have a talk
-- key of "subject". The table is checked in the following order:
-- 1. page's protection action, page's protection level, page's talk key
-- 2. page's protection action, page's protection level, default talk key
-- 3. page's protection action, default protection level, page's talk key
-- 4. page's protection action, default protection level, default talk key
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
explanationBlurbs = {
edit = {
autoconfirmed = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details. If you'
.. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can'
.. ' ${EDITREQUEST}, discuss changes on the ${TALKPAGE},'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details. If you'
.. ' cannot edit this ${PAGETYPE} and you wish to make a change, you can'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].',
},
extendedconfirmed = {
default = 'Extended confirmed protection prevents edits from all unregistered editors'
.. ' and registered users with fewer than 30 days tenure and 500 edits.'
.. ' The [[Wikipedia:Protection policy#extended|policy on community use]]'
.. ' specifies that extended confirmed protection can be applied to combat'
.. ' disruption, if semi-protection has proven to be ineffective.'
.. ' Extended confirmed protection may also be applied to enforce'
.. ' [[Wikipedia:Arbitration Committee|arbitration sanctions]].'
.. ' Please discuss any changes on the ${TALKPAGE}; you may'
.. ' ${EDITREQUEST} to ask for uncontroversial changes supported by'
.. ' [[Wikipedia:Consensus|consensus]].'
},
default = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Please discuss any changes on the ${TALKPAGE}; you'
.. ' may ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] to make an edit if it'
.. ' is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by [[Wikipedia:Consensus'
.. '|consensus]]. You may also [[Wikipedia:Requests for'
.. ' page protection#Current requests for reduction in protection level'
.. '|request]] that this page be unprotected.',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' You may [[Wikipedia:Requests for page'
.. ' protection#Current requests for edits to a protected page|request an'
.. ' edit]] to this page, or [[Wikipedia:Requests for'
.. ' page protection#Current requests for reduction in protection level'
.. '|ask]] for it to be unprotected.'
}
},
move = {
default = {
subject = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but cannot be moved'
.. ' until unprotected. Please discuss any suggested moves on the'
.. ' ${TALKPAGE} or at [[Wikipedia:Requested moves]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.',
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but cannot be moved'
.. ' until unprotected. Please discuss any suggested moves at'
.. ' [[Wikipedia:Requested moves]]. You can also'
.. ' [[Wikipedia:Requests for page protection|request]] that the page be'
.. ' unprotected.'
}
},
autoreview = {
default = {
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Edits to this ${PAGETYPE} by new and unregistered users'
.. ' will not be visible to readers until they are accepted by'
.. ' a reviewer. To avoid the need for your edits to be'
.. ' reviewed, you may'
.. ' [[Wikipedia:Requests for page protection'
.. '#Current requests for reduction in protection level'
.. '|request unprotection]], [[Special:Userlogin|log in]], or'
.. ' [[Special:UserLogin/signup|create an account]].'
},
},
upload = {
default = {
default = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' The page may still be edited but new versions of the file'
.. ' cannot be uploaded until it is unprotected. You can'
.. ' request that a new version be uploaded by using a'
.. ' [[Wikipedia:Edit requests|protected edit request]], or you'
.. ' can [[Wikipedia:Requests for page protection|request]]'
.. ' that the file be unprotected.'
}
}
},
--------------------------------------------------------------------------------
-- Protection levels
--------------------------------------------------------------------------------
-- This table provides the data for the ${PROTECTIONLEVEL} parameter, which
-- produces a short label for different protection levels. It is sorted by
-- protection action and protection level, and is checked in the following
-- order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
protectionLevels = {
edit = {
default = 'protected',
templateeditor = 'template-protected',
extendedconfirmed = 'extended-confirmed-protected',
autoconfirmed = 'semi-protected',
},
move = {
default = 'move-protected'
},
autoreview = {
},
upload = {
default = 'upload-protected'
}
},
--------------------------------------------------------------------------------
-- Images
--------------------------------------------------------------------------------
-- This table lists different padlock images for each protection action and
-- protection level. It is used if an image is not specified in any of the
-- banner data tables, and if the page does not satisfy the conditions for using
-- the ['image-filename-indef'] image. It is checked in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
images = {
edit = {
default = 'Full-protection-shackle.svg',
templateeditor = 'Template-protection-shackle.svg',
extendedconfirmed = 'Extended-protection-shackle.svg',
autoconfirmed = 'Semi-protection-shackle.svg'
},
move = {
default = 'Move-protection-shackle.svg',
},
autoreview = {
default = 'Pending-protection-shackle.svg'
},
upload = {
default = 'Upload-protection-shackle.svg'
}
},
-- Pages with a reason specified in this table will show the special "indef"
-- padlock, defined in the 'image-filename-indef' message, if no expiry is set.
indefImageReasons = {
template = true
},
--------------------------------------------------------------------------------
-- Image links
--------------------------------------------------------------------------------
-- This table provides the data for the ${IMAGELINK} parameter, which gets
-- the image link for small padlock icons based on the page's protection action
-- and protection level. It is checked in the following order:
-- 1. page's protection action, page's protection level
-- 2. page's protection action, default protection level
-- 3. "edit" protection action, default protection level
--
-- It is possible to use banner parameters inside this table.
-- *required* - this table needs edit, move, autoreview and upload subtables.
imageLinks = {
edit = {
default = 'Wikipedia:Protection policy#full',
templateeditor = 'Wikipedia:Protection policy#template',
extendedconfirmed = 'Wikipedia:Protection policy#extended',
autoconfirmed = 'Wikipedia:Protection policy#semi'
},
move = {
default = 'Wikipedia:Protection policy#move'
},
autoreview = {
default = 'Wikipedia:Protection policy#pending'
},
upload = {
default = 'Wikipedia:Protection policy#upload'
}
},
--------------------------------------------------------------------------------
-- Padlock indicator names
--------------------------------------------------------------------------------
-- This table provides the "name" attribute for the <indicator> extension tag
-- with which small padlock icons are generated. All indicator tags on a page
-- are displayed in alphabetical order based on this attribute, and with
-- indicator tags with duplicate names, the last tag on the page wins.
-- The attribute is chosen based on the protection action; table keys must be a
-- protection action name or the string "default".
padlockIndicatorNames = {
autoreview = 'pp-autoreview',
default = 'pp-default'
},
--------------------------------------------------------------------------------
-- Protection categories
--------------------------------------------------------------------------------
--[[
-- The protection categories are stored in the protectionCategories table.
-- Keys to this table are made up of the following strings:
--
-- 1. the expiry date
-- 2. the namespace
-- 3. the protection reason (e.g. "dispute" or "vandalism")
-- 4. the protection level (e.g. "sysop" or "autoconfirmed")
-- 5. the action (e.g. "edit" or "move")
--
-- When the module looks up a category in the table, first it will will check to
-- see a key exists that corresponds to all five parameters. For example, a
-- user page semi-protected from vandalism for two weeks would have the key
-- "temp-user-vandalism-autoconfirmed-edit". If no match is found, the module
-- changes the first part of the key to "all" and checks the table again. It
-- keeps checking increasingly generic key combinations until it finds the
-- field, or until it reaches the key "all-all-all-all-all".
--
-- The module uses a binary matrix to determine the order in which to search.
-- This is best demonstrated by a table. In this table, the "0" values
-- represent "all", and the "1" values represent the original data (e.g.
-- "indef" or "file" or "vandalism").
--
-- expiry namespace reason level action
-- order
-- 1 1 1 1 1 1
-- 2 0 1 1 1 1
-- 3 1 0 1 1 1
-- 4 0 0 1 1 1
-- 5 1 1 0 1 1
-- 6 0 1 0 1 1
-- 7 1 0 0 1 1
-- 8 0 0 0 1 1
-- 9 1 1 1 0 1
-- 10 0 1 1 0 1
-- 11 1 0 1 0 1
-- 12 0 0 1 0 1
-- 13 1 1 0 0 1
-- 14 0 1 0 0 1
-- 15 1 0 0 0 1
-- 16 0 0 0 0 1
-- 17 1 1 1 1 0
-- 18 0 1 1 1 0
-- 19 1 0 1 1 0
-- 20 0 0 1 1 0
-- 21 1 1 0 1 0
-- 22 0 1 0 1 0
-- 23 1 0 0 1 0
-- 24 0 0 0 1 0
-- 25 1 1 1 0 0
-- 26 0 1 1 0 0
-- 27 1 0 1 0 0
-- 28 0 0 1 0 0
-- 29 1 1 0 0 0
-- 30 0 1 0 0 0
-- 31 1 0 0 0 0
-- 32 0 0 0 0 0
--
-- In this scheme the action has the highest priority, as it is the last
-- to change, and the expiry has the least priority, as it changes the most.
-- The priorities of the expiry, the protection level and the action are
-- fixed, but the priorities of the reason and the namespace can be swapped
-- through the use of the cfg.bannerDataNamespaceHasPriority table.
--]]
-- If the reason specified to the template is listed in this table,
-- namespace data will take priority over reason data in the protectionCategories
-- table.
reasonsWithNamespacePriority = {
vandalism = true,
},
-- The string to use as a namespace key for the protectionCategories table for each
-- namespace number.
categoryNamespaceKeys = {
[ 2] = 'user',
[ 3] = 'user',
[ 4] = 'project',
[ 6] = 'file',
[ 8] = 'mediawiki',
[ 10] = 'template',
[ 12] = 'project',
[ 14] = 'category',
[100] = 'portal',
[828] = 'module',
},
protectionCategories = {
['all|all|all|all|all'] = 'Wikipedia fully protected pages',
['all|all|office|all|all'] = 'Wikipedia Office-protected pages',
['all|all|reset|all|all'] = 'Wikipedia Office-protected pages',
['all|all|dmca|all|all'] = 'Wikipedia Office-protected pages',
['all|all|mainpage|all|all'] = 'Wikipedia fully protected main page files',
['all|all|all|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages',
['all|all|ecp|extendedconfirmed|all'] = 'Wikipedia extended-confirmed-protected pages',
['all|template|all|all|edit'] = 'Wikipedia fully protected templates',
['all|all|all|autoconfirmed|edit'] = 'Wikipedia semi-protected pages',
['indef|all|all|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected pages',
['all|all|blp|autoconfirmed|edit'] = 'Wikipedia indefinitely semi-protected biographies of living people',
['temp|all|blp|autoconfirmed|edit'] = 'Wikipedia temporarily semi-protected biographies of living people',
['all|all|dispute|autoconfirmed|edit'] = 'Wikipedia pages semi-protected due to dispute',
['all|all|sock|autoconfirmed|edit'] = 'Wikipedia pages semi-protected from banned users',
['all|all|vandalism|autoconfirmed|edit'] = 'Wikipedia pages semi-protected against vandalism',
['all|category|all|autoconfirmed|edit'] = 'Wikipedia semi-protected categories',
['all|file|all|autoconfirmed|edit'] = 'Wikipedia semi-protected files',
['all|portal|all|autoconfirmed|edit'] = 'Wikipedia semi-protected portals',
['all|project|all|autoconfirmed|edit'] = 'Wikipedia semi-protected project pages',
['all|talk|all|autoconfirmed|edit'] = 'Wikipedia semi-protected talk pages',
['all|template|all|autoconfirmed|edit'] = 'Wikipedia semi-protected templates',
['all|user|all|autoconfirmed|edit'] = 'Wikipedia semi-protected user and user talk pages',
['all|all|all|templateeditor|move'] = 'Wikipedia template-protected pages other than templates and modules',
['all|all|all|templateeditor|edit'] = 'Wikipedia template-protected pages other than templates and modules',
['all|template|all|templateeditor|edit'] = 'Wikipedia template-protected templates',
['all|template|all|templateeditor|move'] = 'Wikipedia template-protected templates', -- move-protected templates
['all|all|blp|sysop|edit'] = 'Wikipedia indefinitely protected biographies of living people',
['temp|all|blp|sysop|edit'] = 'Wikipedia temporarily protected biographies of living people',
['all|all|dispute|sysop|edit'] = 'Wikipedia pages protected due to dispute',
['all|all|sock|sysop|edit'] = 'Wikipedia pages protected from banned users',
['all|all|vandalism|sysop|edit'] = 'Wikipedia pages protected against vandalism',
['all|category|all|sysop|edit'] = 'Wikipedia fully protected categories',
['all|file|all|sysop|edit'] = 'Wikipedia fully protected files',
['all|project|all|sysop|edit'] = 'Wikipedia fully protected project pages',
['all|talk|all|sysop|edit'] = 'Wikipedia fully protected talk pages',
['all|template|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected templates',
['all|template|all|extendedconfirmed|move'] = 'Wikipedia extended-confirmed-protected templates',
['all|template|all|sysop|edit'] = 'Wikipedia fully protected templates',
['all|user|all|sysop|edit'] = 'Wikipedia fully protected user and user talk pages',
['all|module|all|all|edit'] = 'Wikipedia fully protected modules',
['all|module|all|templateeditor|edit'] = 'Wikipedia template-protected modules',
['all|module|all|extendedconfirmed|edit'] = 'Wikipedia extended-confirmed-protected modules',
['all|module|all|autoconfirmed|edit'] = 'Wikipedia semi-protected modules',
['all|all|all|sysop|move'] = 'Wikipedia move-protected pages',
['indef|all|all|sysop|move'] = 'Wikipedia indefinitely move-protected pages',
['all|all|dispute|sysop|move'] = 'Wikipedia pages move-protected due to dispute',
['all|all|vandalism|sysop|move'] = 'Wikipedia pages move-protected due to vandalism',
['all|portal|all|sysop|move'] = 'Wikipedia move-protected portals',
['all|project|all|sysop|move'] = 'Wikipedia move-protected project pages',
['all|talk|all|sysop|move'] = 'Wikipedia move-protected talk pages',
['all|template|all|sysop|move'] = 'Wikipedia move-protected templates',
['all|user|all|sysop|move'] = 'Wikipedia move-protected user and user talk pages',
['all|all|all|autoconfirmed|autoreview'] = 'Wikipedia pending changes protected pages',
['all|file|all|all|upload'] = 'Wikipedia upload-protected files',
},
--------------------------------------------------------------------------------
-- Expiry category config
--------------------------------------------------------------------------------
-- This table configures the expiry category behaviour for each protection
-- action.
-- * If set to true, setting that action will always categorise the page if
-- an expiry parameter is not set.
-- * If set to false, setting that action will never categorise the page.
-- * If set to nil, the module will categorise the page if:
-- 1) an expiry parameter is not set, and
-- 2) a reason is provided, and
-- 3) the specified reason is not blacklisted in the reasonsWithoutExpiryCheck
-- table.
expiryCheckActions = {
edit = nil,
move = false,
autoreview = true,
upload = false
},
reasonsWithoutExpiryCheck = {
blp = true,
template = true,
},
--------------------------------------------------------------------------------
-- Pagetypes
--------------------------------------------------------------------------------
-- This table produces the page types available with the ${PAGETYPE} parameter.
-- Keys are namespace numbers, or the string "default" for the default value.
pagetypes = {
[0] = 'article',
[6] = 'file',
[10] = 'template',
[14] = 'category',
[828] = 'module',
default = 'page'
},
--------------------------------------------------------------------------------
-- Strings marking indefinite protection
--------------------------------------------------------------------------------
-- This table contains values passed to the expiry parameter that mean the page
-- is protected indefinitely.
indefStrings = {
['indef'] = true,
['indefinite'] = true,
['indefinitely'] = true,
['infinite'] = true,
},
--------------------------------------------------------------------------------
-- Group hierarchy
--------------------------------------------------------------------------------
-- This table maps each group to all groups that have a superset of the original
-- group's page editing permissions.
hierarchy = {
sysop = {},
reviewer = {'sysop'},
filemover = {'sysop'},
templateeditor = {'sysop'},
extendedconfirmed = {'sysop'},
autoconfirmed = {'reviewer', 'filemover', 'templateeditor', 'extendedconfirmed'},
user = {'autoconfirmed'},
['*'] = {'user'}
},
--------------------------------------------------------------------------------
-- Wrapper templates and their default arguments
--------------------------------------------------------------------------------
-- This table contains wrapper templates used with the module, and their
-- default arguments. Templates specified in this table should contain the
-- following invocation, and no other template content:
--
-- {{#invoke:Protection banner|main}}
--
-- If other content is desired, it can be added between
-- <noinclude>...</noinclude> tags.
--
-- When a user calls one of these wrapper templates, they will use the
-- default arguments automatically. However, users can override any of the
-- arguments.
wrappers = {
['Template:Protected page'] = {},
['Template:Extended confirmed–protected'] = {'ecp'},
['Template:Protected biography of a living person'] = {'blp'},
['Template:Protected due to a dispute'] = {'dispute'},
['Template:Move-protected'] = {action = 'move', catonly = 'yes'},
['Template:Move-protected due to a dispute'] = {'dispute', action = 'move', catonly = 'yes'},
['Template:Move-protected due to vandalism'] = {'vandalism', action = 'move', catonly = 'yes'},
['Template:Office-protected'] = {'office'},
['Template:Pending changes–protected'] = {action = 'autoreview', small = true},
['Template:Semi-protected indefinitely'] = {small = true},
['Template:Protected due to sockpuppetry'] = {'sock'},
['Template:Protected template'] = {'template', small = true},
['Template:Upload-protected'] = {action = 'upload'},
['Template:Protected talk page of a blocked user'] = {'usertalk'},
['Template:Protected due to vandalism'] = {'vandalism'},
},
--------------------------------------------------------------------------------
--
-- MESSAGES
--
--------------------------------------------------------------------------------
msg = {
--------------------------------------------------------------------------------
-- Intro blurb and intro fragment
--------------------------------------------------------------------------------
-- These messages specify what is produced by the ${INTROBLURB} and
-- ${INTROFRAGMENT} parameters. If the protection is temporary they use the
-- intro-blurb-expiry or intro-fragment-expiry, and if not they use
-- intro-blurb-noexpiry or intro-fragment-noexpiry.
-- It is possible to use banner parameters in these messages.
['intro-blurb-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY}.',
['intro-blurb-noexpiry'] = '${PROTECTIONBLURB}.',
['intro-fragment-expiry'] = '${PROTECTIONBLURB} until ${EXPIRY},',
['intro-fragment-noexpiry'] = '${PROTECTIONBLURB}',
--------------------------------------------------------------------------------
-- Tooltip blurb
--------------------------------------------------------------------------------
-- These messages specify what is produced by the ${TOOLTIPBLURB} parameter.
-- If the protection is temporary the tooltip-blurb-expiry message is used, and
-- if not the tooltip-blurb-noexpiry message is used.
-- It is possible to use banner parameters in these messages.
['tooltip-blurb-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY}.',
['tooltip-blurb-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}.',
['tooltip-fragment-expiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL} until ${EXPIRY},',
['tooltip-fragment-noexpiry'] = 'This ${PAGETYPE} is ${PROTECTIONLEVEL}',
--------------------------------------------------------------------------------
-- Special explanation blurb
--------------------------------------------------------------------------------
-- An explanation blurb for pages that cannot be unprotected, e.g. for pages
-- in the MediaWiki namespace.
-- It is possible to use banner parameters in this message.
['explanation-blurb-nounprotect'] = 'See the [[Wikipedia:Protection policy|'
.. 'protection policy]] and ${PROTECTIONLOG} for more details.'
.. ' Please discuss any changes on the ${TALKPAGE}; you'
.. ' may ${EDITREQUEST} to ask an'
.. ' [[Wikipedia:Administrators|administrator]] to make an edit if it'
.. ' is [[Help:Minor edit#When to mark an edit as a minor edit'
.. '|uncontroversial]] or supported by [[Wikipedia:Consensus'
.. '|consensus]].',
--------------------------------------------------------------------------------
-- Protection log display values
--------------------------------------------------------------------------------
-- These messages determine the display values for the protection log link
-- or the pending changes log link produced by the ${PROTECTIONLOG} parameter.
-- It is possible to use banner parameters in these messages.
['protection-log-display'] = 'protection log',
['pc-log-display'] = 'pending changes log',
--------------------------------------------------------------------------------
-- Current version display values
--------------------------------------------------------------------------------
-- These messages determine the display values for the page history link
-- or the move log link produced by the ${CURRENTVERSION} parameter.
-- It is possible to use banner parameters in these messages.
['current-version-move-display'] = 'current title',
['current-version-edit-display'] = 'current version',
--------------------------------------------------------------------------------
-- Talk page
--------------------------------------------------------------------------------
-- This message determines the display value of the talk page link produced
-- with the ${TALKPAGE} parameter.
-- It is possible to use banner parameters in this message.
['talk-page-link-display'] = 'talk page',
--------------------------------------------------------------------------------
-- Edit requests
--------------------------------------------------------------------------------
-- This message determines the display value of the edit request link produced
-- with the ${EDITREQUEST} parameter.
-- It is possible to use banner parameters in this message.
['edit-request-display'] = 'submit an edit request',
--------------------------------------------------------------------------------
-- Expiry date format
--------------------------------------------------------------------------------
-- This is the format for the blurb expiry date. It should be valid input for
-- the first parameter of the #time parser function.
['expiry-date-format'] = 'F j, Y "at" H:i e',
--------------------------------------------------------------------------------
-- Tracking categories
--------------------------------------------------------------------------------
-- These messages determine which tracking categories the module outputs.
['tracking-category-incorrect'] = 'Wikipedia pages with incorrect protection templates',
['tracking-category-template'] = 'Wikipedia template-protected pages other than templates and modules',
--------------------------------------------------------------------------------
-- Images
--------------------------------------------------------------------------------
-- These are images that are not defined by their protection action and protection level.
['image-filename-indef'] = 'Full-protection-shackle.svg',
['image-filename-default'] = 'Transparent.gif',
--------------------------------------------------------------------------------
-- End messages
--------------------------------------------------------------------------------
}
--------------------------------------------------------------------------------
-- End configuration
--------------------------------------------------------------------------------
}
k108n3hntzssp9cyjanrmu01ygggcb9
Chipopoma cha Niagara
0
50227
124079
2026-11-09T19:23:42Z
Tumbuka Arch
6863
Created page with "{{Short description|Chipopoma chikuru icho chili pa mphaka ya Kanada na United States}} {{Infobox | above = Chipopoma cha Niagara | label1 = Malo | data1 = Pa mphaka ya [[Kanada]] na [[Charu cha Amelika]] | label2 = Mlonga | data2 = [[Mlonga wa Niagara]] | label3 = Nyanja izo zikusazgana | data3 = [[Nyanja ya Erie]] na [[Nyanja ya Ontario]] | label4 = Mtundu | data4 = Mathunthu ghatatu | label5 = Utali wakukhira | data5 = Mamita pafupifupi 51 (Horseshoe Falls) | label6 =..."
124079
wikitext
text/x-wiki
{{Short description|Chipopoma chikuru icho chili pa mphaka ya Kanada na United States}}
{{Infobox
| above = Chipopoma cha Niagara
| label1 = Malo
| data1 = Pa mphaka ya [[Kanada]] na [[Charu cha Amelika]]
| label2 = Mlonga
| data2 = [[Mlonga wa Niagara]]
| label3 = Nyanja izo zikusazgana
| data3 = [[Nyanja ya Erie]] na [[Nyanja ya Ontario]]
| label4 = Mtundu
| data4 = Mathunthu ghatatu
| label5 = Utali wakukhira
| data5 = Mamita pafupifupi 51 (Horseshoe Falls)
| label6 = Malo ghakumanyikwa
| data6 = North America
| label7 = Kuyamba kupangika
| data7 = Pafupifupi vyaka 12,000 ivyo vyajumpha
| label8 = Makonzedwe gha malo
| data8 = {{Coord|43|04|48|N|79|04|16|W|display=inline}}
}}
'''Chipopoma cha Niagara''' ni chipopoma chikuru icho chili pa mphaka ya [[Kanada]] na [[Charu cha Amelika]], pakati pa chigaŵa cha Ontario mu Kanada na chigaŵa cha New York mu Amelika. Chipopoma ichi chili pa [[Mlonga wa Niagara]], uwo ukutola maji kufuma mu [[Nyanja ya Erie]] na kuluta mu [[Nyanja ya Ontario]].<ref name="NASA">{{Cite web|url=https://science.nasa.gov/earth/earth-observatory/niagara-falls-5325/|title=Niagara Falls|website=NASA Earth Observatory|access-date=9 November 2026}}</ref>
Chipopoma cha Niagara ntchimoza mwa malo ghakumanyikwa chomene pa charu chapasi chifukwa cha maji ghanandi agho ghakukhira pa malibwe na chiwoneskelo chake chakukondweska.
== Kakhalilo ka malo ==
Chipopoma cha Niagara chili kumpoto kwa Amelika, pa mphaka ya vyaru viŵiri, Canada na United States. Chigaŵa ichi chili pafupi na [[Nyanja Zikuru za ku Amelika Kumpoto]], izo ni nyanja zikuru izo zili pakati pa Canada na United States.
Mlonga wa Niagara ni mlonga uwo ukulongozga maji kufuma mu Nyanja ya Erie kuluta mu Nyanja ya Ontario. Mlonga uwu ukugazara mu vigaŵa vinyake ndipo ukugawikana kuzingilizga [[Chirwa cha Goat Island]] pambere maji ghandakhire mu mathunthu.
== Mathunthu gha Niagara ==
Chipopoma cha Niagara chili na mathunthu ghatatu ghakuru:
* '''Chipopoma cha Horseshoe (Horseshoe Falls)''' – ichi chili ku chigaŵa cha Canada ndipo ndicho chili na maji ghanandi chomene. Chikupanga mtundu wa mphendelo uwo ukuwoneka nga ni chikomboli.
* '''Chipopoma cha Amelika (American Falls)''' – ichi chili ku chigaŵa cha United States.
* '''Chipopoma cha Bridal Veil (Bridal Veil Falls)''' – ichi ntchipopoma chichoko icho chili pafupi na American Falls.
Mathunthu agha ghakupanga chipopoma chose cha Niagara ndipo maji ghake ghakukhira mu chigwa cha mlonga uwo uli kusi kwa mathunthu agha.<ref name="NASA"/>
Chipopoma cha Horseshoe chili na utali wakukhira wa pafupifupi mamita 51. Malinga na NASA, maji ghakujumpha malita 2 miliyoni pa sekondi ghakukhira pa chigaŵa ichi, ntheura chipopoma ichi chili pakati pa vyipopo vikuru chomene pa charu chapasi.<ref name="NASA"/>
== Kupangika kwa chipopoma ==
Chipopoma cha Niagara chikapangika pamanyuma pa nyengo yikuru ya chisanu iyo yikakhwaska chigaŵa ichi cha Amelika Kumpoto. Mu nyengo iyi, matalala ghakuzizima ghakabisa vigaŵa vikuru vya charu.
Apo chisanu chikayamba kusungunuka na madzi ghake kuluta mu nyanja, maji ghakapanga nthowa yiphya yakujumpha pa malo ghakukwera gha malibwe agho ghakumanyikwa kuti Niagara Escarpment. Ivi vikachitika pafupifupi vyaka 12,000 ivyo vyajumpha.<ref name="NYSM">{{Cite web|url=https://nysm.nysed.gov/research-collections/geology/resources/niagara-falls|title=Niagara Falls|website=The New York State Museum|access-date=9 November 2026}}</ref>
Nyengo yikati yajumphapo, maji ghakalutilira kulyererera malibwe agho ghali pasi pa chipopoma. Chifukwa cha kuŵa kosiyana kwa kukhozga kwa malibwe, vigaŵa vinyake vikulyeka luŵiro kuluska vinyake. Ivi vyapangiska kuti chipopoma chisoloreke pachokopachoko kuluta ku chigaŵa cha kunthazi.
Mwakuyana na New York State Museum, chipopoma ichi chasendelera pafupifupi makilomita 11 kuluta ku chigaŵa cha kunthazi kufuma apo chikayambira kupangika.<ref name="NYSM"/>
== Umoyo wa vyamoyo na chilengedwe ==
Mlonga wa Niagara na malo ghake ghakuzingilizga ghali na vyamoyo vyakupambanapambana. Maji agha ghakukhala vyamoyo vya mu maji, kusazgapo somba na vyamoyo vinyake ivyo vikukhala mu nyanja.
Chigaŵa cha Niagara nacho chili na vyakumera na malo gha nkhorongo. Vinyama na vyamoyo ivi vikovwira kuti chilengedwe cha mlonga na nyanja izo zikusazgana chilangike makora.
== Kagwiliskilo ntchito na kukhumbikwa kwake ==
Chipopoma cha Niagara ntchakuzirwa pa nkhani ya ulendo wa ŵanthu, masambiro gha vya chilengedwe na masambiro gha vya charu. Ŵanthu ŵakufuma mu vyaru vinandi ŵakuluta kukawonelera mathunthu agha.
Maji agha ngakuzirwa so pa nkhani ya kupanga nkhongono ya magesi kwizira mu maji. Mlonga wa Niagara uli na malo ghakupangira magesi agho ghakovwira kupeleka magesi ku vigaŵa vya Canada na United States.
== Wonaniso ==
* [[Mlonga wa Niagara]]
* [[Nyanja ya Erie]]
* [[Nyanja ya Ontario]]
* [[Nyanja Zikuru za ku Amelika Kumpoto]]
* [[Chipopoma cha Victoria]]
* [[Chipopoma cha Iguazu]]
* [[Kukwera kwa malo gha Niagara]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Viwira vya maji]]
[[Category:Vinthu vya ku Kanada]]
[[Category:Vinthu vya ku Amelika]]
5g0z6fq1uooh4ak965n5v5erlniuzxw
Category:Kakhalilo ka malo
14
50228
124080
2026-11-09T19:24:28Z
Tumbuka Arch
6863
Created blank page
124080
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vyachilengedwe
14
50229
124081
2026-11-09T19:24:32Z
Tumbuka Arch
6863
Created blank page
124081
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Viwira vya maji
14
50230
124082
2026-11-09T19:24:35Z
Tumbuka Arch
6863
Created blank page
124082
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya ku Kanada
14
50231
124083
2026-11-09T19:24:39Z
Tumbuka Arch
6863
Created blank page
124083
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya ku Amelika
14
50232
124084
2026-11-09T19:24:42Z
Tumbuka Arch
6863
Created blank page
124084
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Mlonga wa Amazon
0
50233
124085
2026-11-09T19:27:05Z
Tumbuka Arch
6863
Created page with "{{Short description|Mlonga ukuru chomene pa charu chapasi pa nkhani ya unandi wa maji}} {{Infobox | above = Mlonga wa Amazon | label1 = Malo | data1 = [[Amelika ya Kumwera]] | label2 = Kwambira | data2 = [[Mapiri gha Andes]], [[Charu cha Peru]] | label3 = Kumalizgira | data3 = [[Nyanja ya Atlantic]] | label4 = Utali | data4 = Pafupifupi makilomita 6,400 | label5 = Kukura kwa chigaŵa cha maji | data5 = Pafupifupi makilomita 7 miliyoni za pa sikweya | label6 = Unandi wa t..."
124085
wikitext
text/x-wiki
{{Short description|Mlonga ukuru chomene pa charu chapasi pa nkhani ya unandi wa maji}}
{{Infobox
| above = Mlonga wa Amazon
| label1 = Malo
| data1 = [[Amelika ya Kumwera]]
| label2 = Kwambira
| data2 = [[Mapiri gha Andes]], [[Charu cha Peru]]
| label3 = Kumalizgira
| data3 = [[Nyanja ya Atlantic]]
| label4 = Utali
| data4 = Pafupifupi makilomita 6,400
| label5 = Kukura kwa chigaŵa cha maji
| data5 = Pafupifupi makilomita 7 miliyoni za pa sikweya
| label6 = Unandi wa tumilonga twake
| data6 = Vyakujumpha 1,000
| label7 = Vyaru ivyo vili mu chigaŵa cha maji
| data7 = Peru, Brazil, Bolivia, Colombia, Ecuador, Guyana, Suriname na Venezuela, kusazgapo Guiana la ku France
}}
'''Mlonga wa Amazon''' ni mlonga ukuru chomene pa charu chapasi pa nkhani ya unandi wa maji agho ukutola. Uli mu [[Amelika ya Kumwera]], ndipo ukuyambira mu [[Mapiri gha Andes]] mu [[Charu cha Peru]] na kuluta ku [[Nyanja ya Atlantic]] ku chigaŵa cha kumpoto kwa [[Charu cha Brazil]].
Mlonga uwu uli na maji ghanandi chomene kuluska milonga yinyake yiliyose pa charu chapasi. Chigaŵa chake cha maji, icho chikupokelera maji kufuma ku milonga yinandi, ndicho chikuru chomene pa charu chose.<ref name="SPAmazon">{{Cite web|url=https://www.sp-amazon.org/about-the-amazon|title=About the Amazon|website=Science Panel for the Amazon|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Mlonga wa Amazon ukulongozga maji kufuma ku Mapiri gha Andes kuluta ku nyanja ya Atlantic. Mlonga uwu ukuluta mu vigaŵa vikuru vya nkhorongo ya Amazon, chomenechomene mu Peru na Brazil.
Chigaŵa chose icho chikupokelera maji gha mlonga uwu chikujumpha mu vyaru vinandi vya Amelika ya Kumwera. Vyaru ivi ni:
* [[Charu cha Peru]]
* [[Charu cha Brazil]]
* [[Charu cha Bolivia]]
* [[Charu cha Colombia]]
* [[Charu cha Ecuador]]
* [[Charu cha Guyana]]
* [[Charu cha Suriname]]
* [[Charu cha Venezuela]]
* [[Guiana la ku France]]
Chigaŵa chose ichi chikumanyikwa kuti chigaŵa cha maji gha Amazon, ndipo chili na malo pafupifupi makilomita 7 miliyoni pa sikweya.<ref name="SPAmazon"/>
== Utali na unandi wa maji ==
Mlonga wa Amazon uli na utali wa makilomita pafupifupi 6,400. Ndipouli, utali wake ungapambana kuyana na malo agho munthu wakuwona kuti ndiko mlonga uwu ukwambira.
Ŵasayansi ŵanandi ŵakupulikana yayi pa nkhani ya malo ghakwenelera kuti ghaŵe magwero ghake. Vigaŵa vinyake vya mlonga wa Mantaro, Apurímac na Ucayali vili kusambazgika na ŵasayansi kuti vioneske uko maji gha Amazon ghakufumira. Ntheura, utali wakwenelera wa mlonga uwu ungasintha kuyana na umo magwero ghake ghakupimikira.<ref name="NatGeoSource">{{Cite web|url=https://education.nationalgeographic.org/resource/where-does-amazon-river-begin/|title=Where Does the Amazon River Begin?|website=National Geographic Education|access-date=9 November 2026}}</ref>
Mlonga uwu uli na tumilonga tunandi chomene uto tukumwengezgera maji. Ŵanyake mwa tumilonga utu ni:
* [[Mlonga wa Madeira]]
* [[Mlonga wa Negro]]
* [[Mlonga wa Tapajós]]
* [[Mlonga wa Xingu]]
* [[Mlonga wa Purus]]
* [[Mlonga wa Juruá]]
* [[Mlonga wa Ucayali]]
* [[Mlonga wa Marañón]]
Mwakuyana na National Geographic, Mlonga wa Amazon ukupokelera maji kufuma ku tumilonga twakujumpha 1,000. Ivi vikovwira kuti uŵe na maji ghanandi chomene pa charu chapasi.<ref name="NatGeoRivers">{{Cite web|url=https://education.nationalgeographic.org/resource/understanding-rivers/|title=Understanding Rivers|website=National Geographic Education|access-date=9 November 2026}}</ref>
== Nkhorongo ya Amazon ==
Mlonga wa Amazon uli pakati pa chigaŵa cha [[Nkhorongo ya Amazon]], iyo ni nkhorongo yikuru chomene ya mu vyaru vyakufunda pa charu chapasi.
Nkhorongo iyi yili na vyakumera na vyamoyo vinandi chomene. Mu malo agha muli:
* [[Jaguwa]]
* [[Mbalame]]
* [[Somba]]
* [[Njovu ya maji ya Amazon]]
* [[Dolphin ya mlonga]]
* [[Mbelele za mu nkhorongo]]
* [[Njoka]]
* [[Vyakumera vya mu nkhorongo]]
Chigaŵa cha Amazon chili na mitundu ya vyamoyo yakujumpha 10 peresenti ya vyamoyo vyose ivyo vikumanyikwa pa charu chapasi. Ivi vikupangiska kuti chigaŵa ichi chiŵe chakuzirwa chomene pa nkhani ya kusungilira vyamoyo.<ref name="SPAmazon"/><ref name="WWF">{{Cite web|url=https://www.worldwildlife.org/news/stories/protecting-the-amazons-critical-wildlife-corridors/|title=Protecting the Amazon's Critical Wildlife Corridors|website=World Wildlife Fund|date=12 August 2025|access-date=9 November 2026}}</ref>
== Kukhumbikwa kwa mlonga ==
Mlonga wa Amazon ngwakuzirwa chomene pa umoyo wa ŵanthu ŵanandi awo ŵakukhala mu Amelika ya Kumwera. Ŵanthu ŵakugwiliskira ntchito maji ghake pa:
* Kwenda mu maboti na kusendelera ku malo ghanyake.
* Kusomba somba kuti ŵasange chakurya.
* Kulima mu vigaŵa ivyo vili pafupi na mlonga.
* Kusanga maji ghakukhumbikwa pa umoyo.
* Kufufuza vya vyamoyo na chilengedwe.
Mlonga uwu na nkhorongo yake vili na ntchito yikuru pa kusintha kwa mphepo na nyengo pa charu chose. Nkhorongo ya Amazon yikusunga kaboni ndipo yikovwira pakupanga vula na kulongozga umo nyengo yikukhalira mu vigaŵa vinandi vya charu chapasi.<ref name="SPAmazon"/>
== Kusungilira nkhorongo na mlonga ==
Nkhorongo ya Amazon na milonga yake vikukhumbikwira kusungilirika chifukwa cha vyamoyo vinandi ivyo vikukhala mwenemumo. Kusangika kwa malo ghakutemeka nkhorongo, kusintha kwa nyengo na kusangika kwa vyakuchitika ivyo vikupweteka malo gha vyamoyo vikupangiska kuti kusungilira chigaŵa ichi kuŵe kwakuzirwa chomene.
Ŵasayansi na mabungwe gha vya chilengedwe ŵakukolerana pa ntchito ya kusungilira nkhorongo na malo agho vyamoyo vikukhala, kuti vyamoyo ivi vileke kumara.<ref name="WWF"/>
== Wonaniso ==
* [[Nkhorongo ya Amazon]]
* [[Mapiri gha Andes]]
* [[Mlonga wa Nile]]
* [[Mlonga wa Congo]]
* [[Nyanja ya Atlantic]]
* [[Charu cha Brazil]]
* [[Charu cha Peru]]
* [[Chilengedwe]]
* [[Kusintha kwa nyengo]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Milonga]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Amelika ya Kumwera]]
skvzdsktz69wcfvw1b3nhhig3zw9r1g
124086
124085
2026-11-09T19:29:07Z
Tumbuka Arch
6863
124086
wikitext
text/x-wiki
{{Short description|Mlonga ukuru chomene pa charu chapasi pa nkhani ya unandi wa maji}}
{{Infobox
| above = Mlonga wa Amazon
| label1 = Malo
| data1 = [[Amelika ya Kumwera]]
| label2 = Kwambira
| data2 = [[Mapiri gha Andes]], [[Charu cha Peru]]
| label3 = Kumalizgira
| data3 = [[Nyanja ya Atlantic]]
| label4 = Utali
| data4 = Pafupifupi makilomita 6,400
| label5 = Kukura kwa chigaŵa cha maji
| data5 = Pafupifupi makilomita 7 miliyoni za pa sikweya
| label6 = Unandi wa tumilonga twake
| data6 = Vyakujumpha 1,000
| label7 = Vyaru ivyo vili mu chigaŵa cha maji
| data7 = Peru, Brazil, Bolivia, Colombia, Ecuador, Guyana, Suriname na Venezuela, kusazgapo Guiana la ku France
}}
'''Mlonga wa Amazon''' ni mlonga ukuru chomene pa charu chapasi pa nkhani ya unandi wa maji agho ukutola. Uli mu [[Amelika ya Kumwera]], ndipo ukuyambira mu [[Mapiri gha Andes]] mu [[Charu cha Peru]] na kuluta ku [[Nyanja ya Atlantic]] ku chigaŵa cha kumpoto kwa [[Charu cha Brazil]].
Mlonga uwu uli na maji ghanandi chomene kuluska milonga yinyake yiliyose pa charu chapasi. Chigaŵa chake cha maji, icho chikupokelera maji kufuma ku milonga yinandi, ndicho chikuru chomene pa charu chose.<ref name="SPAmazon">{{Cite web|url=https://www.sp-amazon.org/about-the-amazon|title=About the Amazon|website=Science Panel for the Amazon|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Mlonga wa Amazon ukulongozga maji kufuma ku Mapiri gha Andes kuluta ku nyanja ya Atlantic. Mlonga uwu ukuluta mu vigaŵa vikuru vya nkhorongo ya Amazon, chomenechomene mu Peru na Brazil.
Chigaŵa chose icho chikupokelera maji gha mlonga uwu chikujumpha mu vyaru vinandi vya Amelika ya Kumwera. Vyaru ivi ni:
* [[Peru|Charu cha Peru]]
* [[Brazil|Charu cha Brazil]]
* [[Bolivia|Charu cha Bolivia]]
* [[Colombia|Charu cha Colombia]]
* [[Ecuador|Charu cha Ecuador]]
* [[Guyana|Charu cha Guyana]]
* [[Suriname|Charu cha Suriname]]
* [[Venezuela|Charu cha Venezuela]]
* [[France|Guiana la ku France]]
Chigaŵa chose ichi chikumanyikwa kuti chigaŵa cha maji gha Amazon, ndipo chili na malo pafupifupi makilomita 7 miliyoni pa sikweya.<ref name="SPAmazon"/>
== Utali na unandi wa maji ==
Mlonga wa Amazon uli na utali wa makilomita pafupifupi 6,400. Ndipouli, utali wake ungapambana kuyana na malo agho munthu wakuwona kuti ndiko mlonga uwu ukwambira.
Ŵasayansi ŵanandi ŵakupulikana yayi pa nkhani ya malo ghakwenelera kuti ghaŵe magwero ghake. Vigaŵa vinyake vya mlonga wa Mantaro, Apurímac na Ucayali vili kusambazgika na ŵasayansi kuti vioneske uko maji gha Amazon ghakufumira. Ntheura, utali wakwenelera wa mlonga uwu ungasintha kuyana na umo magwero ghake ghakupimikira.<ref name="NatGeoSource">{{Cite web|url=https://education.nationalgeographic.org/resource/where-does-amazon-river-begin/|title=Where Does the Amazon River Begin?|website=National Geographic Education|access-date=9 November 2026}}</ref>
Mlonga uwu uli na tumilonga tunandi chomene uto tukumwengezgera maji. Ŵanyake mwa tumilonga utu ni:
* [[Mlonga wa Madeira]]
* [[Mlonga wa Negro]]
* [[Mlonga wa Tapajós]]
* [[Mlonga wa Xingu]]
* [[Mlonga wa Purus]]
* [[Mlonga wa Juruá]]
* [[Mlonga wa Ucayali]]
* [[Mlonga wa Marañón]]
Mwakuyana na National Geographic, Mlonga wa Amazon ukupokelera maji kufuma ku tumilonga twakujumpha 1,000. Ivi vikovwira kuti uŵe na maji ghanandi chomene pa charu chapasi.<ref name="NatGeoRivers">{{Cite web|url=https://education.nationalgeographic.org/resource/understanding-rivers/|title=Understanding Rivers|website=National Geographic Education|access-date=9 November 2026}}</ref>
== Nkhorongo ya Amazon ==
Mlonga wa Amazon uli pakati pa chigaŵa cha [[Nkhorongo ya Amazon]], iyo ni nkhorongo yikuru chomene ya mu vyaru vyakufunda pa charu chapasi.
Nkhorongo iyi yili na vyakumera na vyamoyo vinandi chomene. Mu malo agha muli:
* [[Jaguwa]]
* [[Mbalame]]
* [[Somba]]
* [[Njovu ya maji ya Amazon]]
* [[Dolphin ya mlonga]]
* [[Mbelele za mu nkhorongo]]
* [[Njoka]]
* [[Vyakumera vya mu nkhorongo]]
Chigaŵa cha Amazon chili na mitundu ya vyamoyo yakujumpha 10 peresenti ya vyamoyo vyose ivyo vikumanyikwa pa charu chapasi. Ivi vikupangiska kuti chigaŵa ichi chiŵe chakuzirwa chomene pa nkhani ya kusungilira vyamoyo.<ref name="SPAmazon"/><ref name="WWF">{{Cite web|url=https://www.worldwildlife.org/news/stories/protecting-the-amazons-critical-wildlife-corridors/|title=Protecting the Amazon's Critical Wildlife Corridors|website=World Wildlife Fund|date=12 August 2025|access-date=9 November 2026}}</ref>
== Kukhumbikwa kwa mlonga ==
Mlonga wa Amazon ngwakuzirwa chomene pa umoyo wa ŵanthu ŵanandi awo ŵakukhala mu Amelika ya Kumwera. Ŵanthu ŵakugwiliskira ntchito maji ghake pa:
* Kwenda mu maboti na kusendelera ku malo ghanyake.
* Kusomba somba kuti ŵasange chakurya.
* Kulima mu vigaŵa ivyo vili pafupi na mlonga.
* Kusanga maji ghakukhumbikwa pa umoyo.
* Kufufuza vya vyamoyo na chilengedwe.
Mlonga uwu na nkhorongo yake vili na ntchito yikuru pa kusintha kwa mphepo na nyengo pa charu chose. Nkhorongo ya Amazon yikusunga kaboni ndipo yikovwira pakupanga vula na kulongozga umo nyengo yikukhalira mu vigaŵa vinandi vya charu chapasi.<ref name="SPAmazon"/>
== Kusungilira nkhorongo na mlonga ==
Nkhorongo ya Amazon na milonga yake vikukhumbikwira kusungilirika chifukwa cha vyamoyo vinandi ivyo vikukhala mwenemumo. Kusangika kwa malo ghakutemeka nkhorongo, kusintha kwa nyengo na kusangika kwa vyakuchitika ivyo vikupweteka malo gha vyamoyo vikupangiska kuti kusungilira chigaŵa ichi kuŵe kwakuzirwa chomene.
Ŵasayansi na mabungwe gha vya chilengedwe ŵakukolerana pa ntchito ya kusungilira nkhorongo na malo agho vyamoyo vikukhala, kuti vyamoyo ivi vileke kumara.<ref name="WWF"/>
== Wonaniso ==
* [[Nkhorongo ya Amazon]]
* [[Mapiri gha Andes]]
* [[Mlonga wa Nile]]
* [[Mlonga wa Congo]]
* [[Nyanja ya Atlantic]]
* [[Charu cha Brazil]]
* [[Charu cha Peru]]
* [[Chilengedwe]]
* [[Kusintha kwa nyengo]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Milonga]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Amelika ya Kumwera]]
4gzqpl58ofii43r8375ddcrsc400n58
Category:Milonga
14
50234
124087
2026-11-09T19:29:56Z
Tumbuka Arch
6863
Created blank page
124087
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya ku Amelika ya Kumwera
14
50235
124088
2026-11-09T19:29:59Z
Tumbuka Arch
6863
Created blank page
124088
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Niagara Falls
0
50236
124089
2026-11-09T19:31:55Z
Tumbuka Arch
6863
Redirected page to [[Chipopoma cha Niagara]]
124089
wikitext
text/x-wiki
#REDIRECT [[Chipopoma cha Niagara]]
nwfxg8c9az04q8r8s2t7rlja6905vse
Nyanja ya Baikal
0
50237
124090
2026-11-09T19:32:25Z
Tumbuka Arch
6863
Created page with "{{Short description|Nyanja yakuzirwa chomene iyo njakale na yitali chomene pa charu chapasi}} {{Infobox | above = Nyanja ya Baikal | label1 = Malo | data1 = [[Siberia]], [[Charu cha Russia]] | label2 = Mtundu wa malo | data2 = Nyanja ya mu chigaŵa cha kuzingilizgika na mapiri | label3 = Kuzama chomene | data3 = Mamita pafupifupi 1,700 | label4 = Vyaka vya nyanja | data4 = Pafupifupi 25 miliyoni | label5 = Madzi ghake | data5 = Pafupifupi 20% ya maji ghawemi ghambura kuz..."
124090
wikitext
text/x-wiki
{{Short description|Nyanja yakuzirwa chomene iyo njakale na yitali chomene pa charu chapasi}}
{{Infobox
| above = Nyanja ya Baikal
| label1 = Malo
| data1 = [[Siberia]], [[Charu cha Russia]]
| label2 = Mtundu wa malo
| data2 = Nyanja ya mu chigaŵa cha kuzingilizgika na mapiri
| label3 = Kuzama chomene
| data3 = Mamita pafupifupi 1,700
| label4 = Vyaka vya nyanja
| data4 = Pafupifupi 25 miliyoni
| label5 = Madzi ghake
| data5 = Pafupifupi 20% ya maji ghawemi ghambura kuzizimika pa charu chapasi
| label6 = Mlonga uwo ukufuma mu nyanja
| data6 = [[Mlonga wa Angara]]
| label7 = Malo ghakumanyikwa
| data7 = {{Coord|53|30|N|108|00|E|display=inline}}
| label8 = Kusazgikira pa malo gha chiharo cha pa charu chose
| data8 = 1996
}}
'''Nyanja ya Baikal''' ni nyanja yikuru iyo yikusangika kumwera kwa [[Siberia]] mu [[Charu cha Russia]]. Nyanja iyi njakale chomene ndipo ndiyo yili na kuzama kukuru chomene pa nyanja zose za pa charu chapasi. Yikumanyikwa pa charu chose chifukwa cha maji ghake ghanandi na vyamoyo vyakupambanapambana ivyo vikukhala mwenemumo.
Mwakuyana na bungwe la [[UNESCO]], Nyanja ya Baikal yili na vyaka pafupifupi 25 miliyoni ndipo njimoza mwa nyanja zakale chomene izo zikumanyikwa na ŵanthu. Kuzama kwake kukujumpha mamita 1,600, ndipo UNESCO yikulongosora kuzama kwake kuti kuli pafupifupi mamita 1,700.<ref name="UNESCO">{{Cite web|url=https://whc.unesco.org/en/list/754/|title=Lake Baikal|website=UNESCO World Heritage Centre|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Nyanja ya Baikal yili kumwera kwa Siberia, pakati pa chigaŵa cha Irkutsk na charu cha ŴaBuryat mu Russia. Yili mu chigaŵa icho chili na mapiri, nkhorongo na milonga yinandi.
Nyanja iyi njakutalika ndipo yili na mawonekedwe ghakupambanapambana. Maji ghake ghakupokelera maji kufuma mu milonga na tumilonga twakupambanapambana. Mlonga wa Angara ni mlonga uwo ukufumiska maji mu nyanja iyi.
== Kukura na maji gha nyanja ==
Nyanja ya Baikal njimoza mwa nyanja zikuru chomene pa charu chapasi. Chinthu icho chikupambana nayo na nyanja zinyake ni kuzama kwake na unandi wa maji agho yikusunga.
Mwakuyana na UNESCO, nyanja iyi yikusunga pafupifupi 20 peresenti ya maji ghawemi ghambura kuzizimika agho ghasangika pa charu chose. Ichi chikupangiska kuti Baikal yiŵe yakuzirwa chomene pa nkhani ya maji ghawemi agho ghakukhumbikwa pa umoyo wa vyamoyo na ŵanthu.<ref name="UNESCO"/>
Maji gha Baikal ngakuwoneka makora chomene mu vigaŵa vinandi, ndipo nyanja iyi yikuzizima mu nyengo ya chisanu. Mu nyengo iyi, chigaŵa chikuru cha maji ghake chingazizima na kupanga ayezi uwo ungakhalapo kwa myezi yinandi.
== Vyamoyo vya mu nyanja ==
Nyanja ya Baikal yili na vyamoyo vinandi ivyo vikusangika mu malo agha pera. Vinyama na vyakumera ivi vikulongora umo vyamoyo vikapangira kusintha kwa nyengo kwa vyaka mamiliyoni.
Mu vyamoyo ivyo vikukhala mu nyanja iyi muli:
* [[Somba]] za mitundu yakupambanapambana.
* [[Vyani vya mu maji]] na vyamoyo vichoko ivyo vikukhala mu maji ghawemi.
* [[Vinyama vya mu maji]] ivyo vikukhala mu nyanja na m'mphepete mwake.
* Vyakumera vyakupambanapambana ivyo vikovwira pa umoyo wa vyamoyo vinyake.
Nyanja iyi yili na vyamoyo ivyo vikuwoneka yayi mu nyanja zinyake. Ivi vyapangiska kuti Baikal yiŵe yakuzirwa chomene pa masambiro gha vya chilengedwe na umo vyamoyo vikusintha mu nyengo yitali.<ref name="UNESCO"/>
== Kukhumbikwa kwa nyanja ==
Nyanja ya Baikal njakuzirwa pa nkhani ya maji ghawemi, vya ulimi, vya vyamoyo na kafukufuku wa sayansi. Ŵasayansi ŵakufuma mu vyaru vinandi ŵakufufuza umo nyanja iyi yikapangikira na umo vyamoyo vyake vikukhalira.
Chifukwa cha vyaka vyake vinandi, nyanja iyi yikovwira ŵasayansi kupulikiska umo vyamoyo vya mu maji ghawemi vikusinthira mu nyengo yitali.
Mu 1996, Nyanja ya Baikal yikasazgikira pa mndandanda wa malo gha chiharo cha charu chose wa UNESCO chifukwa cha kukhumbikwa kwake pa nkhani ya chilengedwe na vyamoyo.<ref name="UNESCO"/>
== Kusungilira chilengedwe ==
Nyanja ya Baikal yikukumana na masuzgo ghakupambanapambana, kusazgapo ukazuzi wa maji na kusintha kwa chilengedwe. Ukazuzi ungafumira ku vyakuchitika vya ŵanthu na ntchito za mafakitale mu vigaŵa vyakuzingilizga nyanja.
UNESCO yalongosorapo kuti nyanja iyi yikwenera kusungilirika chifukwa cha kuzirwa kwake pa charu chose. Kusungilira maji na nkhorongo za m'mphepete mwa nyanja nkhwakuzirwa kuti vyamoyo ivyo vikukhala mwenemumo vilutilire kuŵapo.<ref name="UNESCO"/>
== Wonaniso ==
* [[Siberia]]
* [[Charu cha Russia]]
* [[Nyanja ya Victoria]]
* [[Nyanja ya Tanganyika]]
* [[Mlonga wa Angara]]
* [[Maji ghawemi]]
* [[Chilengedwe]]
* [[UNESCO]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Nyanja]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Russia]]
[[Category:Vinthu vya ku Asia]]
6hkqpdjbbariotevnzryu1xyjihutc2
Category:Nyanja
14
50238
124091
2026-11-09T19:32:54Z
Tumbuka Arch
6863
Created blank page
124091
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya ku Russia
14
50239
124092
2026-11-09T19:32:57Z
Tumbuka Arch
6863
Created blank page
124092
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya ku Asia
14
50240
124093
2026-11-09T19:33:01Z
Tumbuka Arch
6863
Created blank page
124093
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Antarctica
0
50241
124094
2026-11-09T19:33:58Z
Tumbuka Arch
6863
Created page with "{{Short description|Charu chikuru chakuzizima chomene ku chigaŵa chakumwera kwa charu chapasi}} {{Infobox | above = Nyanja ya Antarctica | label1 = Malo | data1 = Chigaŵa chakumwera chomene cha charu chapasi | label2 = Mtundu wa malo | data2 = Charu chikuru chakuzingilizgika na nyanja | label3 = Kukura kwa charu | data3 = Makilomita pafupifupi 13,661,000 pa sikweya | label4 = Kuzama kwa ayezi | data4 = Mpaka makilomita 4.8 | label5 = Nyengo | data5 = Yakuzizima chomene..."
124094
wikitext
text/x-wiki
{{Short description|Charu chikuru chakuzizima chomene ku chigaŵa chakumwera kwa charu chapasi}}
{{Infobox
| above = Nyanja ya Antarctica
| label1 = Malo
| data1 = Chigaŵa chakumwera chomene cha charu chapasi
| label2 = Mtundu wa malo
| data2 = Charu chikuru chakuzingilizgika na nyanja
| label3 = Kukura kwa charu
| data3 = Makilomita pafupifupi 13,661,000 pa sikweya
| label4 = Kuzama kwa ayezi
| data4 = Mpaka makilomita 4.8
| label5 = Nyengo
| data5 = Yakuzizima chomene
| label6 = Ŵanthu awo ŵakukhala nyengo zinyake
| data6 = Ŵasayansi na ŵakovwira pa malo ghakufufuzira
| label7 = Pangano lakulongozga chigaŵa ichi
| data7 = [[Pangano la Antarctica]]
}}
'''Nyanja ya Antarctica''' ni charu chikuru icho chili ku chigaŵa chakumwera chomene kwa [[charu chapasi]]. Antarctica ni charu chachisanu chikuru chomene pa charu chose, ndipo chikuzingilizgika na [[Nyanja ya Kumwera]].
Chigaŵa ichi chikuzizima chomene kuluska makontinenti ghanyake. Chili na chisanu na ayezi vinandi chomene, ndipo ntchimoza mwa malo ghakuzirwa chomene pa kafukufuku wa sayansi ya nyengo na chilengedwe.<ref name="BAS">{{Cite web|url=https://www.bas.ac.uk/about/education-and-schools/antarctic-factsheet/|title=Antarctic Factsheet and Geographical Statistics|website=British Antarctic Survey|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Antarctica yili ku chigaŵa cha kumwera chomene kwa charu chapasi. Yikuzingilizgika na Nyanja ya Kumwera, ndipo yili na malo gha ayezi, mapiri, mabwe na malo ghakuzama.
Charu ichi chili na malo pafupifupi makilomita 13,661,000 pa sikweya. Kukura kwake kukusintha mu nyengo ya chisanu chifukwa chakuti ayezi wakuzingilizga m'mphepete mwa charu ichi wakusazgikira chomene.
Malo ghanandi gha Antarctica ghakubisika na ayezi. Chikhokho cha ayezi chingafika pa kuzama kwa makilomita pafupifupi 4.8. Chifukwa cha kulemera kwa ayezi uyu, malo ghanyake gha charu ichi ghali pasi chomene pa msinkhu wa maji gha nyanja.<ref name="AAG">{{Cite web|url=https://www.antarctica.gov.au/about-antarctica/geography-and-geology/|title=Antarctic geography and geology|website=Australian Antarctic Program|access-date=9 November 2026}}</ref><ref name="BAS"/>
== Nyengo ya Antarctica ==
Antarctica ntcharu chakuzizima chomene, chakuwombeka na mphepo zinandi ndipo chili na vula yichoko chomene.
Nyengo iyi yikupangiska kuti vigaŵa vinandi viŵe vyakuzizima kweniso vyambura vyakumera. Mu chigaŵa ichi muli mphepo zakukhora chomene izo zikukhala zikuchitika chifukwa cha kulemera kwa mphepo yakuzizima iyo yikufuma ku malo ghapachanya kuluta ku m'mphepete mwa charu.
Mu 1983, pa malo ghakufufuzira gha Vostok, ŵanthu ŵakapima nyengo yakuzizima ya madigiri 89.2 pasi pa ziro. Iyi ndiyo yikulondezgana na nyengo yakuzizima chomene iyo yikapimika pa charu chapasi.<ref name="AAG"/>
Antarctica yikupokelera vula yichoko chomene, ndipo vigaŵa vyake vyakukati vili nga ni mapopa ghakuzizima. Ndipouli, chili na ayezi munandi chomene chifukwa chakuti chisanu chikawunjikika kwa vyaka vinandi.<ref name="BAS"/>
== Ayezi na maji ==
Antarctica yili na chikhokho chikuru chomene cha ayezi pa charu chapasi. Chikhokho ichi chikusunga maji ghawemi ghanandi chomene agho ghali mu mawonekedwe gha ayezi.
Mwakuyana na Australian Antarctic Program, ayezi wa Antarctica ukusunga pafupifupi 90 peresenti ya maji ghawemi ghose gha pa charu chapasi.<ref name="AAG"/>
Apo nyengo yikupindikana, chigaŵa cha ayezi icho chazungulira charu ichi mu nyanja chikukura na kuchepa. Mu nyengo ya chisanu, ayezi wa mu nyanja ukuŵa munandi, ndipo mu nyengo yakufunda ukuyamba kusungunuka.
Kusintha kwa unandi wa ayezi wa Antarctica nkhwakuzirwa pa nkhani ya [[kusintha kwa nyengo]] na kukwera kwa msinkhu wa maji gha nyanja pa charu chose.
== Vyamoyo vya ku Antarctica ==
Nangauli nyengo yake njakuzizima chomene, Antarctica yili na vyamoyo ivyo vyasanga nthowa zakukhalira mu malo agha.
Vyamoyo ivyo vikusangika mu chigaŵa ichi na mu nyanja zakuchizungilizga ni:
* [[Mbalame za pengwini]]
* [[Vinyama vya mu nyanja]]
* [[Mbalame za albatrosi]]
* [[Masomba gha mu nyanja]]
* [[Vyakumera vya mu maji]]
* [[Moss]]
* [[Lichen]]
Mu malo ghanandi gha Antarctica muli vyakumera vichoko chomene, ndipo moss na lichen ndivyo vikuwoneka chomene pa malo agho ayezi walipo yayi.<ref name="BAS"/><ref name="AAG"/>
== Ŵanthu na kafukufuku wa sayansi ==
Antarctica yilije ŵanthu awo ŵakukhala mwenemumo nyengo zose nga umo viliri pa makontinenti ghanyake. Ŵanthu awo ŵakuluta ku charu ichi ŵakukhalako pa nyengo yichoko kuti ŵachite kafukufuku wa sayansi.
Vyaru vinandi vili na malo ghakufufuzira mu Antarctica. Ŵasayansi awo ŵakugwira ntchito mwenemumo ŵakufufuza vya:
* [[Nyengo ya charu chapasi]].
* Kusintha kwa ayezi.
* [[Chilengedwe]] na vyamoyo.
* [[Mphepo]] na umo yikwendeskera nyengo.
* Mbiri ya nyengo ya charu chapasi.
Kafukufuku uwu ngwakuzirwa chifukwa Antarctica yikovwira ŵasayansi kupulikiska umo charu chapasi chikaŵira mu nyengo zakale na umo chikusinthira sono.<ref name="BAS"/>
== Pangano la Antarctica ==
Antarctica yikulongozgeka na ndondomeko ya [[Pangano la Antarctica]], ilo likasainika pa 1 Disembala 1959 na vyaru 12. Pangano ili likamba kugwira ntchito pa 23 Juni 1961.
Chilato chikuru cha pangano ili nkhuwoneseska kuti Antarctica yikugwiliskirika ntchito pa vyakuchitika vya mtende na kafukufuku wa sayansi. Likukhozga vyaru kukolerana pakusungilira chilengedwe na kuchita kafukufuku kwambura kususkana.<ref name="Treaty">{{Cite web|url=https://www.ats.aq/|title=The Antarctic Treaty|website=Antarctic Treaty Secretariat|access-date=9 November 2026}}</ref>
== Kukhumbikwa kwa Antarctica pa charu chose ==
Antarctica njakuzirwa chomene pa umo nyengo ya charu chapasi yikwendeskekera. Ayezi wake, nyanja zakuchizungilizga na mphepo zake vikovwira kusintha kwa nyengo mu vigaŵa vinyake vya charu chose.
Kusungilira Antarctica kukovwira pa:
* Kusungilira maji ghawemi gha pa charu chapasi.
* Kuchepeska kuparanyika kwa malo gha vyamoyo.
* Kuthandazga masambiro gha vya nyengo.
* Kumanya makora kusintha kwa charu chapasi.
* Kusungilira vyamoyo vya mu nyanja.
== Wonaniso ==
* [[Makontinenti gha charu chapasi]]
* [[Nyanja ya Kumwera]]
* [[Chigaŵa cha ku Arctic]]
* [[Chigaŵa cha South Pole]]
* [[Kusintha kwa nyengo]]
* [[Matalala gha mu charu]]
* [[Pangano la Antarctica]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Makontinenti]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Antarctica]]
0e05gnd7p4e9f4ukcn8vqwziwa9dwck
124097
124094
2026-11-09T19:35:42Z
Tumbuka Arch
6863
Tumbuka Arch moved page [[Nyanja ya Antarctica]] to [[Antarctica]]
124094
wikitext
text/x-wiki
{{Short description|Charu chikuru chakuzizima chomene ku chigaŵa chakumwera kwa charu chapasi}}
{{Infobox
| above = Nyanja ya Antarctica
| label1 = Malo
| data1 = Chigaŵa chakumwera chomene cha charu chapasi
| label2 = Mtundu wa malo
| data2 = Charu chikuru chakuzingilizgika na nyanja
| label3 = Kukura kwa charu
| data3 = Makilomita pafupifupi 13,661,000 pa sikweya
| label4 = Kuzama kwa ayezi
| data4 = Mpaka makilomita 4.8
| label5 = Nyengo
| data5 = Yakuzizima chomene
| label6 = Ŵanthu awo ŵakukhala nyengo zinyake
| data6 = Ŵasayansi na ŵakovwira pa malo ghakufufuzira
| label7 = Pangano lakulongozga chigaŵa ichi
| data7 = [[Pangano la Antarctica]]
}}
'''Nyanja ya Antarctica''' ni charu chikuru icho chili ku chigaŵa chakumwera chomene kwa [[charu chapasi]]. Antarctica ni charu chachisanu chikuru chomene pa charu chose, ndipo chikuzingilizgika na [[Nyanja ya Kumwera]].
Chigaŵa ichi chikuzizima chomene kuluska makontinenti ghanyake. Chili na chisanu na ayezi vinandi chomene, ndipo ntchimoza mwa malo ghakuzirwa chomene pa kafukufuku wa sayansi ya nyengo na chilengedwe.<ref name="BAS">{{Cite web|url=https://www.bas.ac.uk/about/education-and-schools/antarctic-factsheet/|title=Antarctic Factsheet and Geographical Statistics|website=British Antarctic Survey|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Antarctica yili ku chigaŵa cha kumwera chomene kwa charu chapasi. Yikuzingilizgika na Nyanja ya Kumwera, ndipo yili na malo gha ayezi, mapiri, mabwe na malo ghakuzama.
Charu ichi chili na malo pafupifupi makilomita 13,661,000 pa sikweya. Kukura kwake kukusintha mu nyengo ya chisanu chifukwa chakuti ayezi wakuzingilizga m'mphepete mwa charu ichi wakusazgikira chomene.
Malo ghanandi gha Antarctica ghakubisika na ayezi. Chikhokho cha ayezi chingafika pa kuzama kwa makilomita pafupifupi 4.8. Chifukwa cha kulemera kwa ayezi uyu, malo ghanyake gha charu ichi ghali pasi chomene pa msinkhu wa maji gha nyanja.<ref name="AAG">{{Cite web|url=https://www.antarctica.gov.au/about-antarctica/geography-and-geology/|title=Antarctic geography and geology|website=Australian Antarctic Program|access-date=9 November 2026}}</ref><ref name="BAS"/>
== Nyengo ya Antarctica ==
Antarctica ntcharu chakuzizima chomene, chakuwombeka na mphepo zinandi ndipo chili na vula yichoko chomene.
Nyengo iyi yikupangiska kuti vigaŵa vinandi viŵe vyakuzizima kweniso vyambura vyakumera. Mu chigaŵa ichi muli mphepo zakukhora chomene izo zikukhala zikuchitika chifukwa cha kulemera kwa mphepo yakuzizima iyo yikufuma ku malo ghapachanya kuluta ku m'mphepete mwa charu.
Mu 1983, pa malo ghakufufuzira gha Vostok, ŵanthu ŵakapima nyengo yakuzizima ya madigiri 89.2 pasi pa ziro. Iyi ndiyo yikulondezgana na nyengo yakuzizima chomene iyo yikapimika pa charu chapasi.<ref name="AAG"/>
Antarctica yikupokelera vula yichoko chomene, ndipo vigaŵa vyake vyakukati vili nga ni mapopa ghakuzizima. Ndipouli, chili na ayezi munandi chomene chifukwa chakuti chisanu chikawunjikika kwa vyaka vinandi.<ref name="BAS"/>
== Ayezi na maji ==
Antarctica yili na chikhokho chikuru chomene cha ayezi pa charu chapasi. Chikhokho ichi chikusunga maji ghawemi ghanandi chomene agho ghali mu mawonekedwe gha ayezi.
Mwakuyana na Australian Antarctic Program, ayezi wa Antarctica ukusunga pafupifupi 90 peresenti ya maji ghawemi ghose gha pa charu chapasi.<ref name="AAG"/>
Apo nyengo yikupindikana, chigaŵa cha ayezi icho chazungulira charu ichi mu nyanja chikukura na kuchepa. Mu nyengo ya chisanu, ayezi wa mu nyanja ukuŵa munandi, ndipo mu nyengo yakufunda ukuyamba kusungunuka.
Kusintha kwa unandi wa ayezi wa Antarctica nkhwakuzirwa pa nkhani ya [[kusintha kwa nyengo]] na kukwera kwa msinkhu wa maji gha nyanja pa charu chose.
== Vyamoyo vya ku Antarctica ==
Nangauli nyengo yake njakuzizima chomene, Antarctica yili na vyamoyo ivyo vyasanga nthowa zakukhalira mu malo agha.
Vyamoyo ivyo vikusangika mu chigaŵa ichi na mu nyanja zakuchizungilizga ni:
* [[Mbalame za pengwini]]
* [[Vinyama vya mu nyanja]]
* [[Mbalame za albatrosi]]
* [[Masomba gha mu nyanja]]
* [[Vyakumera vya mu maji]]
* [[Moss]]
* [[Lichen]]
Mu malo ghanandi gha Antarctica muli vyakumera vichoko chomene, ndipo moss na lichen ndivyo vikuwoneka chomene pa malo agho ayezi walipo yayi.<ref name="BAS"/><ref name="AAG"/>
== Ŵanthu na kafukufuku wa sayansi ==
Antarctica yilije ŵanthu awo ŵakukhala mwenemumo nyengo zose nga umo viliri pa makontinenti ghanyake. Ŵanthu awo ŵakuluta ku charu ichi ŵakukhalako pa nyengo yichoko kuti ŵachite kafukufuku wa sayansi.
Vyaru vinandi vili na malo ghakufufuzira mu Antarctica. Ŵasayansi awo ŵakugwira ntchito mwenemumo ŵakufufuza vya:
* [[Nyengo ya charu chapasi]].
* Kusintha kwa ayezi.
* [[Chilengedwe]] na vyamoyo.
* [[Mphepo]] na umo yikwendeskera nyengo.
* Mbiri ya nyengo ya charu chapasi.
Kafukufuku uwu ngwakuzirwa chifukwa Antarctica yikovwira ŵasayansi kupulikiska umo charu chapasi chikaŵira mu nyengo zakale na umo chikusinthira sono.<ref name="BAS"/>
== Pangano la Antarctica ==
Antarctica yikulongozgeka na ndondomeko ya [[Pangano la Antarctica]], ilo likasainika pa 1 Disembala 1959 na vyaru 12. Pangano ili likamba kugwira ntchito pa 23 Juni 1961.
Chilato chikuru cha pangano ili nkhuwoneseska kuti Antarctica yikugwiliskirika ntchito pa vyakuchitika vya mtende na kafukufuku wa sayansi. Likukhozga vyaru kukolerana pakusungilira chilengedwe na kuchita kafukufuku kwambura kususkana.<ref name="Treaty">{{Cite web|url=https://www.ats.aq/|title=The Antarctic Treaty|website=Antarctic Treaty Secretariat|access-date=9 November 2026}}</ref>
== Kukhumbikwa kwa Antarctica pa charu chose ==
Antarctica njakuzirwa chomene pa umo nyengo ya charu chapasi yikwendeskekera. Ayezi wake, nyanja zakuchizungilizga na mphepo zake vikovwira kusintha kwa nyengo mu vigaŵa vinyake vya charu chose.
Kusungilira Antarctica kukovwira pa:
* Kusungilira maji ghawemi gha pa charu chapasi.
* Kuchepeska kuparanyika kwa malo gha vyamoyo.
* Kuthandazga masambiro gha vya nyengo.
* Kumanya makora kusintha kwa charu chapasi.
* Kusungilira vyamoyo vya mu nyanja.
== Wonaniso ==
* [[Makontinenti gha charu chapasi]]
* [[Nyanja ya Kumwera]]
* [[Chigaŵa cha ku Arctic]]
* [[Chigaŵa cha South Pole]]
* [[Kusintha kwa nyengo]]
* [[Matalala gha mu charu]]
* [[Pangano la Antarctica]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Makontinenti]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Antarctica]]
0e05gnd7p4e9f4ukcn8vqwziwa9dwck
124099
124097
2026-11-09T19:35:57Z
Tumbuka Arch
6863
124099
wikitext
text/x-wiki
{{Short description|Charu chikuru chakuzizima chomene ku chigaŵa chakumwera kwa charu chapasi}}
{{Infobox
| above = Nyanja ya Antarctica
| label1 = Malo
| data1 = Chigaŵa chakumwera chomene cha charu chapasi
| label2 = Mtundu wa malo
| data2 = Charu chikuru chakuzingilizgika na nyanja
| label3 = Kukura kwa charu
| data3 = Makilomita pafupifupi 13,661,000 pa sikweya
| label4 = Kuzama kwa ayezi
| data4 = Mpaka makilomita 4.8
| label5 = Nyengo
| data5 = Yakuzizima chomene
| label6 = Ŵanthu awo ŵakukhala nyengo zinyake
| data6 = Ŵasayansi na ŵakovwira pa malo ghakufufuzira
| label7 = Pangano lakulongozga chigaŵa ichi
| data7 = [[Pangano la Antarctica]]
}}
'''Antarctica''' ni charu chikuru icho chili ku chigaŵa chakumwera chomene kwa [[charu chapasi]]. Antarctica ni charu chachisanu chikuru chomene pa charu chose, ndipo chikuzingilizgika na [[Nyanja ya Kumwera]].
Chigaŵa ichi chikuzizima chomene kuluska makontinenti ghanyake. Chili na chisanu na ayezi vinandi chomene, ndipo ntchimoza mwa malo ghakuzirwa chomene pa kafukufuku wa sayansi ya nyengo na chilengedwe.<ref name="BAS">{{Cite web|url=https://www.bas.ac.uk/about/education-and-schools/antarctic-factsheet/|title=Antarctic Factsheet and Geographical Statistics|website=British Antarctic Survey|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Antarctica yili ku chigaŵa cha kumwera chomene kwa charu chapasi. Yikuzingilizgika na Nyanja ya Kumwera, ndipo yili na malo gha ayezi, mapiri, mabwe na malo ghakuzama.
Charu ichi chili na malo pafupifupi makilomita 13,661,000 pa sikweya. Kukura kwake kukusintha mu nyengo ya chisanu chifukwa chakuti ayezi wakuzingilizga m'mphepete mwa charu ichi wakusazgikira chomene.
Malo ghanandi gha Antarctica ghakubisika na ayezi. Chikhokho cha ayezi chingafika pa kuzama kwa makilomita pafupifupi 4.8. Chifukwa cha kulemera kwa ayezi uyu, malo ghanyake gha charu ichi ghali pasi chomene pa msinkhu wa maji gha nyanja.<ref name="AAG">{{Cite web|url=https://www.antarctica.gov.au/about-antarctica/geography-and-geology/|title=Antarctic geography and geology|website=Australian Antarctic Program|access-date=9 November 2026}}</ref><ref name="BAS"/>
== Nyengo ya Antarctica ==
Antarctica ntcharu chakuzizima chomene, chakuwombeka na mphepo zinandi ndipo chili na vula yichoko chomene.
Nyengo iyi yikupangiska kuti vigaŵa vinandi viŵe vyakuzizima kweniso vyambura vyakumera. Mu chigaŵa ichi muli mphepo zakukhora chomene izo zikukhala zikuchitika chifukwa cha kulemera kwa mphepo yakuzizima iyo yikufuma ku malo ghapachanya kuluta ku m'mphepete mwa charu.
Mu 1983, pa malo ghakufufuzira gha Vostok, ŵanthu ŵakapima nyengo yakuzizima ya madigiri 89.2 pasi pa ziro. Iyi ndiyo yikulondezgana na nyengo yakuzizima chomene iyo yikapimika pa charu chapasi.<ref name="AAG"/>
Antarctica yikupokelera vula yichoko chomene, ndipo vigaŵa vyake vyakukati vili nga ni mapopa ghakuzizima. Ndipouli, chili na ayezi munandi chomene chifukwa chakuti chisanu chikawunjikika kwa vyaka vinandi.<ref name="BAS"/>
== Ayezi na maji ==
Antarctica yili na chikhokho chikuru chomene cha ayezi pa charu chapasi. Chikhokho ichi chikusunga maji ghawemi ghanandi chomene agho ghali mu mawonekedwe gha ayezi.
Mwakuyana na Australian Antarctic Program, ayezi wa Antarctica ukusunga pafupifupi 90 peresenti ya maji ghawemi ghose gha pa charu chapasi.<ref name="AAG"/>
Apo nyengo yikupindikana, chigaŵa cha ayezi icho chazungulira charu ichi mu nyanja chikukura na kuchepa. Mu nyengo ya chisanu, ayezi wa mu nyanja ukuŵa munandi, ndipo mu nyengo yakufunda ukuyamba kusungunuka.
Kusintha kwa unandi wa ayezi wa Antarctica nkhwakuzirwa pa nkhani ya [[kusintha kwa nyengo]] na kukwera kwa msinkhu wa maji gha nyanja pa charu chose.
== Vyamoyo vya ku Antarctica ==
Nangauli nyengo yake njakuzizima chomene, Antarctica yili na vyamoyo ivyo vyasanga nthowa zakukhalira mu malo agha.
Vyamoyo ivyo vikusangika mu chigaŵa ichi na mu nyanja zakuchizungilizga ni:
* [[Mbalame za pengwini]]
* [[Vinyama vya mu nyanja]]
* [[Mbalame za albatrosi]]
* [[Masomba gha mu nyanja]]
* [[Vyakumera vya mu maji]]
* [[Moss]]
* [[Lichen]]
Mu malo ghanandi gha Antarctica muli vyakumera vichoko chomene, ndipo moss na lichen ndivyo vikuwoneka chomene pa malo agho ayezi walipo yayi.<ref name="BAS"/><ref name="AAG"/>
== Ŵanthu na kafukufuku wa sayansi ==
Antarctica yilije ŵanthu awo ŵakukhala mwenemumo nyengo zose nga umo viliri pa makontinenti ghanyake. Ŵanthu awo ŵakuluta ku charu ichi ŵakukhalako pa nyengo yichoko kuti ŵachite kafukufuku wa sayansi.
Vyaru vinandi vili na malo ghakufufuzira mu Antarctica. Ŵasayansi awo ŵakugwira ntchito mwenemumo ŵakufufuza vya:
* [[Nyengo ya charu chapasi]].
* Kusintha kwa ayezi.
* [[Chilengedwe]] na vyamoyo.
* [[Mphepo]] na umo yikwendeskera nyengo.
* Mbiri ya nyengo ya charu chapasi.
Kafukufuku uwu ngwakuzirwa chifukwa Antarctica yikovwira ŵasayansi kupulikiska umo charu chapasi chikaŵira mu nyengo zakale na umo chikusinthira sono.<ref name="BAS"/>
== Pangano la Antarctica ==
Antarctica yikulongozgeka na ndondomeko ya [[Pangano la Antarctica]], ilo likasainika pa 1 Disembala 1959 na vyaru 12. Pangano ili likamba kugwira ntchito pa 23 Juni 1961.
Chilato chikuru cha pangano ili nkhuwoneseska kuti Antarctica yikugwiliskirika ntchito pa vyakuchitika vya mtende na kafukufuku wa sayansi. Likukhozga vyaru kukolerana pakusungilira chilengedwe na kuchita kafukufuku kwambura kususkana.<ref name="Treaty">{{Cite web|url=https://www.ats.aq/|title=The Antarctic Treaty|website=Antarctic Treaty Secretariat|access-date=9 November 2026}}</ref>
== Kukhumbikwa kwa Antarctica pa charu chose ==
Antarctica njakuzirwa chomene pa umo nyengo ya charu chapasi yikwendeskekera. Ayezi wake, nyanja zakuchizungilizga na mphepo zake vikovwira kusintha kwa nyengo mu vigaŵa vinyake vya charu chose.
Kusungilira Antarctica kukovwira pa:
* Kusungilira maji ghawemi gha pa charu chapasi.
* Kuchepeska kuparanyika kwa malo gha vyamoyo.
* Kuthandazga masambiro gha vya nyengo.
* Kumanya makora kusintha kwa charu chapasi.
* Kusungilira vyamoyo vya mu nyanja.
== Wonaniso ==
* [[Makontinenti gha charu chapasi]]
* [[Nyanja ya Kumwera]]
* [[Chigaŵa cha ku Arctic]]
* [[Chigaŵa cha South Pole]]
* [[Kusintha kwa nyengo]]
* [[Matalala gha mu charu]]
* [[Pangano la Antarctica]]
== Ukaboni ==
<references/>
[[Category:Kakhalilo ka malo]]
[[Category:Makontinenti]]
[[Category:Vinthu vyachilengedwe]]
[[Category:Vinthu vya ku Antarctica]]
s41gkboqubxir2zf6rrbau1x37hunwy
Category:Vinthu vya ku Antarctica
14
50242
124095
2026-11-09T19:34:34Z
Tumbuka Arch
6863
Created blank page
124095
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Makontinenti
14
50243
124096
2026-11-09T19:34:37Z
Tumbuka Arch
6863
Created blank page
124096
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Nyanja ya Antarctica
0
50244
124098
2026-11-09T19:35:43Z
Tumbuka Arch
6863
Tumbuka Arch moved page [[Nyanja ya Antarctica]] to [[Antarctica]]
124098
wikitext
text/x-wiki
#REDIRECT [[Antarctica]]
a4ysfgyg34m0dnnnsm7ugc9eqbufjr0
Palawan people
0
50245
124100
2026-11-09T19:36:46Z
Tumbuka Arch
6863
Created page with "# REDIRECT [[ŴaPalaw'an]]"
124100
wikitext
text/x-wiki
# REDIRECT [[ŴaPalaw'an]]
c601520b9x3jtkqxzjpdpis7oo70ywv
124101
124100
2026-11-09T19:36:58Z
Tumbuka Arch
6863
Redirected page to [[ŴaPalaw'an]]
124101
wikitext
text/x-wiki
#REDIRECT [[ŴaPalaw'an]]
iimrtzmpkc171oyyxfh65g0fx41yjp9
ŴaPalaw'an
0
50246
124102
2026-11-09T19:37:16Z
Tumbuka Arch
6863
Created page with "{{Short description|Mtundu wa ŵanthu ŵakwambilira ŵa ku chirwa cha Palawan mu Philippines}} {{Infobox ethnic group | group = ŴaPalaw'an | native_name = Pala’wan | native_name_lang = Chiyowoyero cha Pala’wan | regions = [[Chirwa cha Palawan]], kumwera kwa [[Charu cha Philippines]] | languages = [[Chiyowoyero cha Pala'wan]] | related_groups = [[ŴaTau't Bato]] }} '''ŴaPalaw'an''' ni mtundu wa ŵanthu ŵakwambilira awo ŵakukhala mu [[Chirwa cha Palawan]] ku chiga..."
124102
wikitext
text/x-wiki
{{Short description|Mtundu wa ŵanthu ŵakwambilira ŵa ku chirwa cha Palawan mu Philippines}}
{{Infobox ethnic group
| group = ŴaPalaw'an
| native_name = Pala’wan
| native_name_lang = Chiyowoyero cha Pala’wan
| regions = [[Chirwa cha Palawan]], kumwera kwa [[Charu cha Philippines]]
| languages = [[Chiyowoyero cha Pala'wan]]
| related_groups = [[ŴaTau't Bato]]
}}
'''ŴaPalaw'an''' ni mtundu wa ŵanthu ŵakwambilira awo ŵakukhala mu [[Chirwa cha Palawan]] ku chigaŵa cha kumwera kwa [[Charu cha Philippines]]. Ŵanthu a mtundu uwu ŵakukhala chomene mu chigaŵa chakumwera cha chirwa cha Palawan.
Mu mabuku ghanyake, mtundu uwu ukulembeka kuti '''Pala’wan''' panji '''Palawano'''. ŴaPalaw'an ŵali na chiyowoyero, maluso na umoyo wakukolerana na malo agho ŵakukhala.<ref name="NCCA">{{Cite web|url=https://ncca.gov.ph/about-culture-and-arts/culture-profile/glimpses-peoples-of-the-philippines/palawan/|title=Peoples of the Philippines: Pala'wan|website=National Commission for Culture and the Arts|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
ŴaPalaw'an ŵakusangika mu chigaŵa chakumwera cha [[Chirwa cha Palawan]], icho chili mu [[Charu cha Philippines]]. Malo ghawo ghakusangika chomene mu vigaŵa vya:
* [[Brooke's Point]]
* [[Quezon]]
* [[Rizal]]
* [[Singnapan Valley]]
Nkhani ya National Commission for Culture and the Arts yikulongosora kuti ŴaPalaw'an ŵakukhala mu chigaŵa chikuru chakumwera kwa chirwa ichi. Yikuzunuraso kuti ŴaTau't Bato ŵali pakati pa magulu agho ghakukolerana na ŵa mtundu uwu.<ref name="NCCA"/>
ŴaPalaw'an ni mtundu wakupambanako na ŵanthu wose awo ŵakukhala mu chirwa cha Palawan. Ntheura, zina ili likung'anamura mtundu uwu, kuti yayi ŵanthu wose ŵa mu chigaŵa ichi.
== Chiyowoyero ==
ŴaPalaw'an ŵali na chiyowoyero chawo icho chikumanyikwa kuti Pala’wan panji Palawano. Chiyowoyero ichi ntchimoza mwa viyowoyero ivyo vikuyowoyeka kumwera kwa Philippines.
Mwakuyana na National Commission for Culture and the Arts, chiyowoyero cha mtundu uwu chikukolerana na gulu la viyowoyero vya Manobo vya ku chigaŵa chakumwera kwa Philippines.<ref name="NCCA"/>
Chiyowoyero ichi ntchakuzirwa chomene pa kusungilira mbiri, maluso, sumu, ntharika na vinjeru vya ŵanthu a mtundu uwu.
== Umoyo na ulimi ==
ŴaPalaw'an ŵakhalapo nyengo yitali ŵakugwiliskira ntchito ulimi, kusomba somba na kusanga vyakurya kufuma mu nkhorongo.
Mwakuyana na National Commission for Culture and the Arts, ŵanthu a mtundu uwu ŵakuchita chomene ulimi wakusintha minda. Vyakurya ivyo ŵakulima ni:
* [[Mpunga]]
* [[Chimanga]]
* [[Mbatata]]
* [[Vyakumera vya mu minda]]
* [[Mihogo]]
Mpunga ngwakuzirwa chomene pa vyakurya vyawo. Mihogo nayo njimoza mwa vyakurya ivyo vikugwiliskirika ntchito chomene.
Mu vigaŵa vinyake, umo ŵanthu ŵakukhala na malo agho ŵakugwiliskira ntchito vikusintha kuyana na nyengo. Nkhani ya NCCA yikulongosora za kusintha kwa malo ghakukhala kufuma mu mapanga kuluta ku malo ghakujulika mu vigaŵa vinyake pa nyengo ya chaka.<ref name="NCCA"/>
== Nyumba na maluso ==
ŴaPalaw'an ŵali na maluso ghakupambanapambana pa kuzenga nyumba na kugwiliskira ntchito vinthu vyakufuma mu chilengedwe.
Nyumba zawo zakale zikulongosoreka kuti zili na vigaŵa vyakupambanapambana ivyo vikusazgana kuyana na ntchito yake. Ŵanthu a mtundu uwu ŵakagwiliskiranga ntchito vinthu nga ni:
* [[Bamboo]]
* Mitengo yichoko.
* Makuni ghakuzenga.
* Vyakumera vya mu nkhorongo.
Kugwiliskira ntchito vinthu ivi kukulongora umo ŵanthu a mtundu uwu ŵasungililira maluso ghawo gha kuzenga na umo ŵakukoleranira na malo agho ŵakukhala.<ref name="NCCA"/>
Mu vigaŵa vinyake vya Palawan, maluso gha kupanga mabasiketi gha mtundu wa tingkep ghakulutilira kusungilirika na ŵanthu ŵakwimira chikaya cha Pala'wan. Maluso agha ghakovwira kusungilira vinjeru vya kale na kugwiliskira ntchito vinthu vyakufuma mu chilengedwe.<ref>{{Cite web|url=https://palawan-news.com/an-indigenous-basket-weaving-tradition-keeps-a-philippine-forest-alive/|title=An Indigenous Basket-Weaving Tradition Keeps a Philippine Forest Alive|website=Palawan News|access-date=9 November 2026}}</ref>
== ŴaTau't Bato ==
[[ŴaTau't Bato]] ni gulu linyake la ŵanthu awo ŵakukhala mu chigaŵa cha Singnapan Valley ku Ransang, kumwera kwa Palawan.
Ŵanthu a mtundu uwu ŵakumanyikwa chifukwa cha umo umoyo wawo ukukolerana na malo agho ŵakukhala. Maluso ghawo, umoyo na umo ŵakugwiliskira ntchito chilengedwe ni vigaŵa vyakuzirwa pa mbiri ya ŵanthu ŵakwambilira ŵa Palawan.<ref name="NCCA"/>
== Chikaya na kusungilira maluso ==
Chikaya cha ŴaPalaw'an chili na vinjeru vya kale ivyo vikujumpha kufuma ku one generation kuluta ku linyake. Ivi vikusazgapo chiyowoyero, maluso gha ulimi, kupanga vinthu vya mu nyumba, sumu na umo ŵakugwiliskira ntchito vyakumera vya mu chilengedwe.
Kusungilira viyowoyero vya ŵanthu ŵakwambilira, maluso ghawo na malo agho ŵakukhala nkhwakuzirwa kuti mbiri ya mtundu uwu yileke kumara.
== Wonaniso ==
* [[Chirwa cha Palawan]]
* [[Charu cha Philippines]]
* [[ŴaTau't Bato]]
* [[Ŵanthu ŵakwambilira]]
* [[Ŵanthu ŵa mtundu wa Manobo]]
* [[Viyowoyero vya mu Philippines]]
* [[Nkhorongo ya ku Palawan]]
* [[Chikaya]]
== Ukaboni ==
<references/>
[[Category:Mitundu ya ŵanthu]]
[[Category:Ŵanthu ŵa ku Philippines]]
[[Category:Ŵanthu ŵakwambilira]]
[[Category:Kakhalilo ka malo]]
8d3g87zg3wslha61hpnxb7clq5zsgzd
Ming dynasty
0
50247
124103
2026-11-09T19:45:12Z
Tumbuka Arch
6863
Redirected page to [[Mbumba ya Ming]]
124103
wikitext
text/x-wiki
#REDIRECT [[Mbumba ya Ming]]
0577eyb3r0omc369lvj6lqkcu4sc5wr
Mbumba ya Ming
0
50248
124104
2026-11-09T19:45:43Z
Tumbuka Arch
6863
Created page with "{{Short description|Mbumba iyo yikalamulira Charu cha China pakati pa 1368 na 1644}} {{Infobox | above = Mbumba ya Ming | label1 = Zina | data1 = Ming (明朝) | label2 = Nyengo iyo yikalamulira | data2 = 1368–1644 | label3 = Muthomi | data3 = Zhu Yuanzhang (Hongwu) | label4 = Mfumukazi yaumaliro | data4 = Chongzhen | label5 = Misumba mikuru | data5 = Nanjing na Beijing | label6 = Mtundu wa boma | data6 = Ufumu wakulongozgeka na mbumba | label7 = Mbumba iyo yikayilonde..."
124104
wikitext
text/x-wiki
{{Short description|Mbumba iyo yikalamulira Charu cha China pakati pa 1368 na 1644}}
{{Infobox
| above = Mbumba ya Ming
| label1 = Zina
| data1 = Ming (明朝)
| label2 = Nyengo iyo yikalamulira
| data2 = 1368–1644
| label3 = Muthomi
| data3 = Zhu Yuanzhang (Hongwu)
| label4 = Mfumukazi yaumaliro
| data4 = Chongzhen
| label5 = Misumba mikuru
| data5 = Nanjing na Beijing
| label6 = Mtundu wa boma
| data6 = Ufumu wakulongozgeka na mbumba
| label7 = Mbumba iyo yikayilondezga
| data7 = Mbumba ya Qing
| label8 = Chigaŵa
| data8 = [[Charu cha China]]
| label9 = Chiŵelengero cha ŵalongozgi
| data9 = Mafumu 17
}}
[[File:Map of the Ming dynasty (1500).png|thumb|right|Malo agho Mbumba ya Ming yikalamuliranga mu 1500.]]
[[File:Forbidden City BM 1881,1210,0.87.CH.jpg|thumb|right|Nyumba ya ufumu wa China ku Beijing iyo yikazengeka mu nyengo ya Ming.]]
[[File:20241018 Blue and White Porcelain Plate with Lotuses Design, Xuande Reign of Ming Dynasty 01.jpg|thumb|right|Chinthu chakupangika na dongo lakuzgoka nga ni gilasi mu nyengo ya Ming.]]
'''Mbumba ya Ming''' yikaŵa mbumba ya mafumu iyo yikalamulira [[Charu cha China]] kufuma mu 1368 m'paka mu 1644. Mbumba iyi yikiza pamanyuma pa kumara kwa [[Mbumba ya Yuan]], ndipo yikakhala njimoza mwa mbumba izo zikaŵa na mazaza ghakuru chomene mu mdauko wa China.
Mbumba iyi yikambika na Zhu Yuanzhang, uyo wakamanyikwaso na zina lakuti Fumu Hongwu. Mu nyengo ya Ming, China yikasambira chomene pa vya ulimi, malonda, kuzenga, sayansi, vyaluso na vyakusanguluska. Nyengo iyi yikumanyikwaso chifukwa cha vinthu vyakupangika na dongo la porcelain na ntchito zakuzenga izo zikalutilira kumanyikwa kwa vyaka vinandi.<ref name="Smithsonian">{{Cite web|url=https://asia.si.edu/education/educator-resources/teaching-china-with-the-smithsonian/explore-by-dynasty/ming-dynasty/|title=Ming dynasty (1368–1644)|website=Smithsonian National Museum of Asian Art|access-date=9 November 2026}}</ref>
== Kwamba kwa Mbumba ya Ming ==
Mbumba ya Ming yikambika mu 1368 apo Zhu Yuanzhang wakathereska boma la Mongoliya la Yuan. Zhu wakafuma mu mbumba yakavu ndipo wakakwera na kuŵa mulongozgi wa ŵasilikari awo ŵakawuska boma la Yuan.
Wakati wathereska ŵalongozgi ŵake, wakakhazikiska mbumba yiphya iyo wakayithya Ming. Wakatora zina la ufumu lakuti Hongwu ndipo wakakhazikiska boma lake mu [[Mzinda wa Nanjing]].<ref name="Princeton">{{Cite web|url=https://static.artmuseum.princeton.edu/asian-art/china/timeline|title=China Timeline|website=Princeton University Art Museum|access-date=9 November 2026}}</ref>
Mu nyengo ya ufumu wake, Zhu Yuanzhang wakakhazikiska ndondomeko za boma, malango na nthowa zakulongozgera charu. Wakakhazikiska so dongosolo la ŵalaraŵalara ŵa boma na kulimbiska mazaza gha fumu.
== Kusamukira kwa likuru la boma ku Beijing ==
Mu nyengo ya Fumu Yongle, uyo wakaŵa mulongozgi wachitatu wa mbumba iyi, likuru la boma likasamukira kufuma ku Nanjing kuya ku [[Mzinda wa Beijing]].
Kusintha uku kukachitika mu vyaka vya kukwambilira vya m'ma 1400, ndipo mu 1421 Beijing yikazgoka likuru la ufumu. Fumu Yongle yikazenga nyumba zikuru za boma na nyumba za mafumu izo zikapangiska kuti Beijing yiŵe pakati pa mazaza gha China.<ref name="Princeton"/>
[[Mzinda wa Beijing]] ukalutilira kuŵa likuru la boma la China kufuma pa nyengo iyi.
== Ulendo wa ŵasilikari ŵa panyanja ==
Mbumba ya Ming yikumanyikwaso chifukwa cha maulendo ghakuru gha panyanja agho ghakalongozgekanga na Zheng He. Maulendo agha ghakachitika pakati pa 1405 na 1433.
Zheng He wakaŵa mulongozgi wa zombo za ufumu ndipo wakalongozga maulendo ghakujumpha nyanja za ku Asia na kuluta ku vigaŵa vya kumafumiro gha dazi kwa [[Africa]].
Maulendo agha ghakawovwira kukhazikiska ubwezi wa malonda na vyaru vinyake. Ŵanthu ŵa ku China ŵakasinthananga katundu, vinjeru na maluso na ŵanthu ŵa mu vyaru vinyake.<ref name="MetYongle">{{Cite web|url=https://www.metmuseum.org/exhibitions/listings/2005/yongle-imperial-art|title=Defining Yongle|website=The Metropolitan Museum of Art|access-date=9 November 2026}}</ref>
== Malonda na chuma ==
Mu nyengo ya Ming, China yikaŵa na malonda ghakukura chomene. Ŵamalonda ŵakaguliskanga katundu mu misumba ya mu charu ichi kweniso ku vyaru vinyake vya ku Asia.
Vinthu ivyo vikaguliskikanga chomene vikaŵa:
* [[Silika]].
* [[Porcelain]].
* [[Tiyi]].
* Vyakuvwara.
* Vyakupangika na visulo.
* Vyakumera vyakugwiliskika ntchito pa vyakurya na vyamankhwala.
Kukura kwa malonda kukawovwira kuti misumba yinandi yikure. Ŵanthu ŵanandi ŵakagwiliskiranga ntchito ndalama pa malonda ndipo chuma cha mu mbumba iyi chikakura chomene.<ref name="Smithsonian"/>
== Vyaluso na vinjeru ==
Mbumba ya Ming yikaŵa yakuzirwa pa vya maluso gha ku China. Vyakupangika na dongo la porcelain vikazgoka vinthu vyakumanyikwa pa charu chose.
Vinthu vyakupangika mu nyengo iyi vikaŵa na mawonekedwe ghakupambanapambana, kusazgapo viŵiya, mbale, makapu na vyakudyo. Vinyake vikapendekeka na malibwe gha mtundu wa buluu pa fundo yituŵa.
Ŵapendi ŵakazenga vikozgo, ŵakapenda vithuzithuzi na kupenda vinthu vya chilengedwe. Maluso agha ghakawovwira kusambazga chikhalidwe cha ku China.<ref name="Smithsonian"/><ref name="Met">{{Cite web|url=https://www.metmuseum.org/es/toah/ht/08/eac.html|title=China, 1400–1600 A.D.|website=The Metropolitan Museum of Art|access-date=9 November 2026}}</ref>
== Chisola cha Great Wall ==
Mu nyengo ya Ming, vigaŵa vinandi vya [[Chimakoma Chikuru cha China]] vikazengeka panji kunozgekaso kuti viwovwire pakuvikilira mphaka za ufumu.
Ntchito izi zikapangiska kuti Chimakoma Chikuru chiŵe na mawonekedwe agho tikuwona mu vigaŵa vinandi mazuŵa ghano. Chikaŵa na minara yakulaŵilira, vipata na nthowa za ŵasilikari.<ref name="UNESCO">{{Cite web|url=https://whc.unesco.org/en/list/438/|title=The Great Wall|website=UNESCO World Heritage Centre|access-date=9 November 2026}}</ref>
== Kumara kwa Mbumba ya Ming ==
Mu nyengo yake yaumaliro, mbumba iyi yikakumana na masuzgo ghanandi. Masuzgo agha ghakasazgapo kusuzgika kwa chuma cha boma, njara, mphindano za ŵanthu, masuzgo gha vya ulimi na kuwusa mwambura kukhazikika.
Mu 1644, ŵasilikari ŵakakora Beijing ndipo ufumu wa Ming ukamara. Pamanyuma pake, Mbumba ya Qing yikamba kulamulira China.<ref name="Smithsonian"/>
== Wonaniso ==
* [[Charu cha China]]
* [[Mbumba ya Yuan]]
* [[Mbumba ya Qing]]
* [[Zheng He]]
* [[Mzinda wa Beijing]]
* [[Mzinda wa Nanjing]]
* [[Chimakoma Chikuru cha China]]
* [[Mbiri ya China]]
* [[Porcelain]]
* [[Ufumu wa Mongoliya]]
== Ukaboni ==
<references/>
[[Category:Mbiri ya China]]
[[Category:Mbumba za China]]
[[Category:Mbumba za mafumu]]
[[Category:Mbiri ya ku Asia]]
0xeejd69c8ubx6veolgyz4v2q5phs7h
Category:Mbiri ya China
14
50249
124105
2026-11-09T19:46:20Z
Tumbuka Arch
6863
Created blank page
124105
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbumba za China
14
50250
124106
2026-11-09T19:46:23Z
Tumbuka Arch
6863
Created blank page
124106
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbumba za mafumu
14
50251
124107
2026-11-09T19:46:27Z
Tumbuka Arch
6863
Created blank page
124107
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya ku Asia
14
50252
124108
2026-11-09T19:46:30Z
Tumbuka Arch
6863
Created blank page
124108
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Triantha occidentalis
0
50253
124109
2026-11-09T19:47:14Z
Tumbuka Arch
6863
Created page with "{{Short description|Chomera chakurya tunyama twachoko kwizira mu tumiseru twake twakunata}} {{Infobox | above = Triantha occidentalis | label1 = Zina la sayansi | data1 = Triantha occidentalis | label2 = Ufumu | data2 = Plantae | label3 = Gulu la vyakumera | data3 = Angiosperms | label4 = Banja | data4 = Tofieldiaceae | label5 = Malo agho chikukulira | data5 = Kumanjiliro gha dazi kwa North America | label6 = Malo agho chikukhala | data6 = Malo ghakunyota, madambo na map..."
124109
wikitext
text/x-wiki
{{Short description|Chomera chakurya tunyama twachoko kwizira mu tumiseru twake twakunata}}
{{Infobox
| above = Triantha occidentalis
| label1 = Zina la sayansi
| data1 = Triantha occidentalis
| label2 = Ufumu
| data2 = Plantae
| label3 = Gulu la vyakumera
| data3 = Angiosperms
| label4 = Banja
| data4 = Tofieldiaceae
| label5 = Malo agho chikukulira
| data5 = Kumanjiliro gha dazi kwa North America
| label6 = Malo agho chikukhala
| data6 = Malo ghakunyota, madambo na mapopa ghanyontho
| label7 = Mtundu wa chakurya
| data7 = Chakurya cha vyakumera na tunyama twachoko
}}
[[File:Triantha occidentalis.jpg|thumb|right|Triantha occidentalis mu malo agho yikukulira.]]
[[File:JEPS109491 Triantha occidentalis ssp. occidentalis (7586062482).jpg|thumb|right|Maluŵa gha Triantha occidentalis na tusere twake twakunata.]]
[[File:Triantha occidentalis.jpg|thumb|right|Triantha occidentalis ni chomera icho chingakora tunyama twachoko kuti chisange vyakukhumbikwa pakukura.]]
'''Triantha occidentalis''' ni mtundu wa chomera icho chikukulira ku kumanjiliro gha dazi kwa [[North America]]. Chomera ichi ntchakupambanapambana chifukwa chikukora tunyama twachoko na kugwiliskira ntchito vyakukhumbikwa kufuma mu tunyama utu.
Chomera ichi chikuwoneka nga ni vyakumera vinyake ivyo vili na maluŵa ghatuŵa. Kweni kafukufuku wa sayansi uliboneska kuti Triantha occidentalis chili na nthowa yapadera yakukolera na kugaya tunyama twachoko. <ref name="PNAS">{{Cite journal|url=https://pmc.ncbi.nlm.nih.gov/articles/PMC8379919/|title=A new carnivorous plant lineage (Triantha) with a unique sticky-inflorescence trap|journal=Proceedings of the National Academy of Sciences|date=17 August 2021|access-date=9 November 2026}}</ref>
== Kakhalilo ka chomera ==
Triantha occidentalis ntchimoza mwa vyakumera vya mu banja la Tofieldiaceae. Chikukura kufuma ku vigaŵa vyake vya pasi pa dongo ivyo vikusunga vyakukhumbikwa kuti chikure.
Chomera ichi chili na masamba agho ghakupangika kufupi na pasi. Mu nyengo yakuti chikulenge maluŵa, chikupanga nthumbo yitali iyo yikupwelelera maluŵa ghatuŵa panji ghakulotera ku mtundu wa green.
Chomera ichi chikukulira mu vigaŵa ivyo vili na maji ghanandi, nga ni:
* [[Dambo]].
* Malo ghanyontho.
* Malo ghakukhala maji.
* Malo ghakuzingilizgika na mphonje za milonga.
* Malo gha peat bogs.
Mu [[Canada]], chikukulira chomene mu vigaŵa vya British Columbia na Alberta. Chikusangikasongaso mu vigaŵa vinyake vya kumanjiliro gha dazi kwa United States.<ref name="ANPC">{{Cite web|url=https://anpc.ab.ca/?page_id=6801|title=Western False Asphodel|website=Alberta Native Plant Council|access-date=9 November 2026}}</ref>
== Umo chikukolera tunyama ==
Chinthu chakuzirwa chomene icho chikupambana Triantha occidentalis na vyakumera vinandi ntchakuti chili na tumiseru twakunata pa ndodo izo zikusangikapo maluŵa.
Tumisere utu tukupanga chinthu chakunata icho chikukora tunyama twachoko nga ni:
* [[Ntchentche]] zichoko.
* Tizilombo twakuwuluka.
* Tunyama twachoko twakukhala pa vyakumera.
Tunyama utu tikakora pa tumiseru utu, ndipo chomera chikugwiliskira ntchito vimvuchi vya kugaya vyakurya kuti chisange vyakukhumbikwa pa kukura kwake.
Tumisere utu tikupanga enzyme yakumanyikwa kuti phosphatase, iyo yikovwira pa kugaya vyamoyo ivyo vyakorwa.<ref name="PNAS"/><ref name="ANPC"/>
== Sayansi yakusimikizga kuti chikurya tunyama ==
Mu 2021, kafukufuku uyo ukafumiskika mu magazini ya sayansi ya *Proceedings of the National Academy of Sciences* ukasimikizga kuti Triantha occidentalis ntchimoza mwa vyakumera ivyo vikurya vyamoyo vinyake.
Ŵasayansi ŵakagwiliskira ntchito vipimo vya sayansi kuti ŵamanye umo nitrogen yakufuma mu tunyama yikulutira mu chomera ichi. Kafukufuku uyu wakasanga kuti pafupifupi 64 peresenti ya nitrogen iyo yikaŵa mu masamba ghake yikafumanga ku tunyama uto chomera chikakora mu vyaka vyakumasinda.<ref name="PNAS"/>
Ichi chikaŵa chakuzirwa pa sayansi chifukwa chakuti chikulongora kuti vyakumera vinyake ivyo vikawonekanga nga ni vyakumera vyambura kurya tunyama navyo vili na nthowa yakugwiliskira ntchito vyamoyo vinyake kuti visange chakurya.
== Umo chikukoleranira na tizilombo twakukobela maluŵa ==
Triantha occidentalis chili na maluŵa agho ghakukobela tizilombo kuti tivwovwire pakupangiska mbeu.
Ndipouli, tumiseru twakunata tukuwoneka chomene pa ndodo ya maluŵa ndipo tukukora chomene tizilombo tuchoko. Tizilombo tikuru nga ni njuchi na vipepeŵa vikuru tikufika pa maluŵa na kovwira pa kusendelera kwa mbeu kwambura kukorwa luŵiro na tumiseru utu.<ref name="PNAS"/>
Ichi chikulongora umo chomera ichi chasangira nthowa yakuti chikorenge vyakurya kwizira mu tizilombo twachoko kweni chichali kupokelera thandizo la tizilombo twakukobela maluŵa.
== Kukhumbikwa kwa chomera ==
Triantha occidentalis njakuzirwa pa kafukufuku wa vyakumera na umo vyamoyo vikupangikira kusintha kuti viŵe na umoyo mu malo ghakupambanapambana.
Chomera ichi chikovwira ŵasayansi kumanya umo vyakumera vikusangira nitrogen na vyakukhumbikwa vinyake mu malo agho dongo lilije vyakukhumbikwa vinandi.
Kafukufuku wake wakulongoraso kuti pakaŵa vyakumera vinandi ivyo vikukhala na vinthu vyakupambanapambana ivyo vindafufuzike makora na ŵasayansi.<ref name="PNAS"/>
== Wonaniso ==
* [[Vyakumera]]
* [[Vyakumera vyakurya tunyama]]
* [[Tizilombo]]
* [[Maluŵa]]
* [[Dambo]]
* [[Chilengedwe]]
* [[Sayansi ya vyamoyo]]
* [[North America]]
== Ukaboni ==
<references/>
[[Category:Vyakumera]]
[[Category:Vyakumera vyakurya tunyama]]
[[Category:Vyamoyo vya ku North America]]
[[Category:Sayansi ya vyamoyo]]
01vow5psfkvufa0bsjrzpi23oktmrvb
Category:Vyakumera
14
50254
124110
2026-11-09T19:47:48Z
Tumbuka Arch
6863
Created blank page
124110
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vyakumera vyakurya tunyama
14
50255
124111
2026-11-09T19:47:51Z
Tumbuka Arch
6863
Created blank page
124111
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vyamoyo vya ku North America
14
50256
124112
2026-11-09T19:47:54Z
Tumbuka Arch
6863
Created blank page
124112
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Sayansi ya vyamoyo
14
50257
124113
2026-11-09T19:47:57Z
Tumbuka Arch
6863
Created blank page
124113
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Chiyuni cha Bill cha mlomo wa skapato
0
50258
124114
2026-11-09T19:49:26Z
Tumbuka Arch
6863
Created page with "{{Short description|Chiyuni chikuru cha mu madambo gha pakati na kumafumiro gha dazi kwa Africa}} {{Infobox | above = Chiyuni cha mlomo wa skapato | label1 = Zina la sayansi | data1 = Balaeniceps rex | label2 = Ufumu | data2 = Animalia | label3 = Gulu | data3 = Aves | label4 = Banja | data4 = Balaenicipitidae | label5 = Malo agho chikukhala | data5 = Central Africa na East Africa | label6 = Kutalika | data6 = Masentimita 110–140 | label7 = Kutambalala kwa mapapindo | d..."
124114
wikitext
text/x-wiki
{{Short description|Chiyuni chikuru cha mu madambo gha pakati na kumafumiro gha dazi kwa Africa}}
{{Infobox
| above = Chiyuni cha mlomo wa skapato
| label1 = Zina la sayansi
| data1 = Balaeniceps rex
| label2 = Ufumu
| data2 = Animalia
| label3 = Gulu
| data3 = Aves
| label4 = Banja
| data4 = Balaenicipitidae
| label5 = Malo agho chikukhala
| data5 = Central Africa na East Africa
| label6 = Kutalika
| data6 = Masentimita 110–140
| label7 = Kutambalala kwa mapapindo
| data7 = Mamita pafupifupi 2.4
| label8 = Mtundu wa vyakurya
| data8 = Somba na vyamoyo vinyake vya mu maji
| label9 = Mkhalidwe wa kusungilira
| data9 = Vulnerable (chakupwetekeka)
}}
[[File:Shoebill - Balaeniceps rex.jpg|thumb|right|Chiyuni cha mlomo wa skapato.]]
[[File:Shoebill (Balaeniceps rex).jpg|thumb|right|Chiyuni ichi chikukhala mu malo ghanyontho gha mu Africa.]]
[[File:Balaeniceps rex.jpg|thumb|right|Balaeniceps rex iyo yikuwoneska mlomo wake ukuru.]]
[[File:Shoebill.jpg|thumb|right|Chiyuni cha mlomo wa skapato chili na mawonekedwe ghapadera chomene.]]
'''Chiyuni cha mlomo wa skapato''' (''Balaeniceps rex'') ni chiyuni chikuru icho chikukhala mu madambo gha pakati na kumafumiro gha dazi kwa [[Africa]]. Chikumanyikwa chifukwa cha mlomo wake ukuru uwo ukuyanako na skapato.
Chiyuni ichi chili na mawonekedwe ghapadera, ndipo ntchimoza mwa viyuni ivyo vikumanyikwa chomene pa charu chifukwa cha mlomo wake ukuru na maso ghake agho ghakuwoneka ghakuthwa.
Chikukhala chomene mu madambo agho ghali na maji ghambura kwenda luŵiro, chomenechomene mu malo agho muli vyakumera vya papyrus na mabango.<ref name="SDZ">{{Cite web|url=https://animals.sandiegozoo.org/animals/shoebill|title=Shoebill|website=San Diego Zoo Wildlife Alliance|access-date=9 November 2026}}</ref>
== Mawonekedwe gha thupi ==
Chiyuni cha mlomo wa skapato chili na thupi likuru ilo likufika pa kutalika kwa masentimita 110 mpaka 140.
Mapapindo ghake ngakuru, ndipo ghakupangiska kuti chiwuluke mwakukhora. Kutambalala kwa mapapindo ghake kungafika pafupifupi mamita 2.4.
Vinthu vinyake ivyo vikulongora mawonekedwe ghake ni:
* Mlomo ukuru wakuyanako na skapato.
* Maso ghakuwoneka gha chikasu panji ghakuyerako.
* Mapapindo ghakuru.
* Malundi ghatali.
* Minwe yitali iyo yikovwira pakwendamo mu madambo.
* Nthenga zakuyerako na zakufipa.
Mlomo wake ungafika pafupifupi masentimita 19 ndipo ngwakukhora chomene. Mlomo uwu ngwakuzirwa pakukora somba na vyakurya vinyake vya mu maji.<ref name="SDZ"/>
== Malo agho chikukhala ==
Chiyuni ichi chikukhala chomene mu chigaŵa cha pakati na kumafumiro gha dazi kwa [[Africa]].
Vyaru ivyo chikusangikamo ni:
* [[Sudan]]
* [[South Sudan]]
* [[Uganda]]
* [[Tanzania]]
* [[Democratic Republic of the Congo]]
* [[Central African Republic]]
* [[Rwanda]]
Chikusangikasongaso mu Ethiopia pa nyengo zinyake.
Chimanyikwika chomene mu madambo ghakuru gha Sudd mu South Sudan na malo ghanyontho agho ghali pafupi na nyanja mu Uganda.<ref name="IUCN">{{Cite web|url=https://doi.org/10.2305/IUCN.UK.2018-2.RLTS.T22697583A133840708.en|title=Balaeniceps rex: The IUCN Red List of Threatened Species|website=IUCN|date=2018|access-date=9 November 2026}}</ref><ref name="SDZ"/>
== Vyakurya ==
Chiyuni cha mlomo wa skapato chikurya chomene somba izo zikusangika mu maji ghambura kwenda luŵiro.
Vyakurya vyake vikuphatikizapo:
* [[Somba]].
* Lungfish.
* Vyamoyo vichoko vya mu maji.
* [[Vyotcha vya mu maji]].
* Vyamoyo vinyake vyakukhala mu madambo.
Chiyuni ichi chikwendakwenda pachokopachoko mu maji agho ngapasi. Para chawona chakurya, chikukora na mlomo wake ukuru.
Chimanyikwika kuti chikukhala pachekha, ndipo nangauli viyuni vinyake vingaŵa na munyake, vikukhala na malo ghawo ghakupokera vyakurya.<ref name="SDZ"/>
== Kubabika na kulera twana ==
Chiyuni ichi chikuzenga chisa chake pa vyakumera ivyo vikututuma pa maji panji pa malo ghanyontho agho ghali na vyakumera vinandi.
Chisa chikuzengeka na vyakumera ivyo vikufuma mu malo agha. Chisankho cha malo gha chisa ntchakuzirwa kuti chiwovwire kuvikilira mahe na twana.
Chiyuni ichi chingakandira mahe pakati pa limoza na ghatatu, ndipo kanandi chikuŵa na mahe ghaŵiri.<ref name="SDZ"/>
== Kusungilira chiyuni ichi ==
Chiyuni cha mlomo wa skapato chili pa mndandanda wa vyamoyo ivyo vili mu ngozi ya kumara. Bungwe la International Union for Conservation of Nature (IUCN) likuchiŵika mu gulu la ''Vulnerable''.
Mwakuyana na kuyezgera kwa IUCN kwa 2018, pa charu chose pakaŵa viyuni vyakukura pakati pa 3,300 na 5,300. Chiŵelengero ichi chikakhumbikwiranga kupwelelerika chifukwa chakuti unandi wake ukaŵa kuti ukuchepa.<ref name="IUCN"/>
Masuzgo agho ghakupweteka umoyo wa chiyuni ichi ghakusazgapo:
* Kuparanyika kwa madambo.
* Kusintha kwa malo gha maji.
* Ulimi na ntchito za ŵanthu mu madambo.
* Kukora viyuni na mahe mwambura kuzomerezgeka.
* Ukazuzi wa maji.
* Kusintha kwa nyengo.
Kusungilira madambo gha mu Africa nkhwakuzirwa kuti chiyuni ichi chiŵe na malo ghakukhalamo na kubabiramo.
== Wonaniso ==
* [[Viyuni]]
* [[Somba]]
* [[Madambo]]
* [[Vyotcha vya mu maji]]
* [[Tizilombo]]
* [[Chilengedwe cha Africa]]
* [[Vyamoyo vyakupwetekeka]]
* [[Uganda]]
* [[South Sudan]]
== Ukaboni ==
<references/>
[[Category:Viyuni]]
[[Category:Vyamoyo vya ku Africa]]
[[Category:Vyamoyo vya mu madambo]]
[[Category:Vyamoyo vyakupwetekeka]]
fgcudxwihlkaf1pzfvqi19ljixx1t5a
Parker Solar Probe
0
50259
124115
2026-11-09T19:50:50Z
Tumbuka Arch
6863
Redirected page to [[Chombo cha Parker]]
124115
wikitext
text/x-wiki
#REDIRECT [[Chombo cha Parker]]
ll6jw7666v2qdbkcu3qwu8y2biri29y
Chombo cha Parker
0
50260
124116
2026-11-09T19:51:01Z
Tumbuka Arch
6863
Created page with "{{Short description|Chombo cha NASA icho chikufufuza Dazi na mphepo yake}} {{Infobox | above = Parker Solar Probe | label1 = Mtundu wa chombo | data1 = Chombo chakwendakwenda kuzungulira Dazi | label2 = Bungwe | data2 = [[NASA]] | label3 = Charu | data3 = [[Charu cha Amelika]] | label4 = Zuŵa ilo chikatumizgikira | data4 = 12 Ogasiti 2018 | label5 = Malo agho chikufufuza | data5 = [[Dazi]] | label6 = Malo ghakwendakwenda | data6 = Kuzungulira Dazi | label7 = Mazina agho..."
124116
wikitext
text/x-wiki
{{Short description|Chombo cha NASA icho chikufufuza Dazi na mphepo yake}}
{{Infobox
| above = Parker Solar Probe
| label1 = Mtundu wa chombo
| data1 = Chombo chakwendakwenda kuzungulira Dazi
| label2 = Bungwe
| data2 = [[NASA]]
| label3 = Charu
| data3 = [[Charu cha Amelika]]
| label4 = Zuŵa ilo chikatumizgikira
| data4 = 12 Ogasiti 2018
| label5 = Malo agho chikufufuza
| data5 = [[Dazi]]
| label6 = Malo ghakwendakwenda
| data6 = Kuzungulira Dazi
| label7 = Mazina agho chikaŵa nagho pakwamba
| data7 = Solar Probe Plus
| label8 = Mulimo wa sayansi
| data8 = Kufufuza corona na solar wind
| label9 = Mkhalidwe
| data9 = Chikugwira ntchito
}}
[[File:Parker Solar Probe.jpg|thumb|right|Chithuzithuzi cha Parker Solar Probe apo chikuyandikiraso ku Dazi.]]
[[File:Artist's impression of PSP and magnetic switchback.png|thumb|right|Parker Solar Probe apo yikufufuza mphepo na magineti gha Dazi.]]
[[File:Parker Solar Probe coronal stream wispr-big 1-st flyby.jpg|thumb|right|Chithuzithuzi cha chilengedwe cha Dazi icho chikatorwa na vyakupimira vya chombo ichi.]]
[[File:A Stellar Prospect Captured By NASA's Parker Solar Probe (51733480269).png|thumb|right|Chithuzithuzi cha nyenyezi icho chikatorwa mu ulendo wa Parker Solar Probe.]]
'''Parker Solar Probe''' ni chombo chakufufuza mu mlengalenga icho chikapangika na [[NASA]] kuti chifufuze [[Dazi]]. Chombo ichi chikutembenuka kuzungulira Dazi ndipo chikupangika kuti chiyandikire chomene ku Dazi kuluska vyombo vinyake ivyo vikatumizgikapo pambere ichi chindafike.
Chilato cha ulendo uwu nkhuwovwira ŵasayansi kupulikiska umo Dazi likugwilira ntchito, umo mphepo yake yikupangikira na umo vyakuchitika vyake vikukhwaskira [[charu chapasi]].<ref name="NASA">{{Cite web|url=https://science.nasa.gov/mission/parker-solar-probe/|title=Parker Solar Probe|website=NASA Science|access-date=9 November 2026}}</ref>
== Kwamba kwa ulendo ==
Parker Solar Probe yikatumizgika mu mlengalenga pa 12 Ogasiti 2018 kufuma ku Kennedy Space Center mu Florida, [[Charu cha Amelika]].
Chombo ichi chikatumizgika na roketi ya Delta IV Heavy. Pakwamba chikamanyikwanga kuti Solar Probe Plus, kweni pamanyuma chikapika zina lakuti Parker Solar Probe, pa kukumbukira wasayansi Eugene Parker.
Eugene Parker wakaŵa wasayansi wa vya mlengalenga uyo wakasambizga chomene vya umo mphepo yakufuma ku Dazi yikupangikira.<ref name="NASA"/><ref name="Launch">{{Cite web|url=https://www.nasa.gov/news-release/nasa-ula-launch-parker-solar-probe-on-historic-journey-to-touch-sun/|title=NASA, ULA Launch Parker Solar Probe on Historic Journey to Touch Sun|website=NASA|date=12 August 2018|access-date=9 November 2026}}</ref>
== Chilato cha kafukufuku ==
Chilato chikuru cha Parker Solar Probe nkhufufuza chigaŵa cha kuwaro kwa Dazi icho chikupangika na mphepo na vyakuchitika vya magineti.
Chigaŵa ichi chikumanyikwa kuti ''corona''. Corona ni chigaŵa cha kuwaro kwa Dazi icho chili na mphepo yakuzizima yayi kweni chili na kutentha kukuru chomene.
Parker Solar Probe ndiyo yikaŵa chombo chakwamba kuluta mukati mwa corona ya Dazi kuti chifufuze mwachindunji umo malo agha ghakugwilira ntchito.<ref name="NASA"/>
Kafukufuku wake wakovwira kupulikiska:
* Umo mphepo ya Dazi yikupangikira.
* Umo magineti gha Dazi ghakugwilira ntchito.
* Umo vyakuchitika vya Dazi vikuyambira.
* Umo vyakuchitika vya Dazi vikukhwaskira charu chapasi.
* Umo tingamanya kale nyengo ya mlengalenga.
== Vyakupimira vya mu chombo ==
Parker Solar Probe chili na magulu ghanayi gha vyakupimira vya sayansi.
Vyakupimira ivi vikugwira ntchito yakusonkhaniska vinjeru vya magineti, mphepo ya Dazi, vinthu vichoko ivyo vikufuma ku Dazi na vithuzithuzi vya malo agho chombo chikujumphamo.
Magulu agha ghakumanyikwa na mazina gha sayansi ghakuti:
* FIELDS.
* ISʘIS.
* WISPR.
* SWEAP.
Vyakupimira ivi vikovwira ŵasayansi kusambira vya mkhalidwe wa corona na mphepo ya Dazi.<ref name="NASA"/>
== Kuyandikira ku Dazi ==
Mu 2021, Parker Solar Probe yikafika mu corona ya Dazi, ndipo yikapokera vinjeru vyakuzirwa vya sayansi.
Pa 24 Disembala 2024, chombo ichi chikafika pa mtunda wa pafupifupi makilomita 6.2 miliyoni kufuma pa chigaŵa cha kuwaro kwa Dazi. Pa nyengo iyi chikafika pa liŵiro la pafupifupi makilomita 692,000 pa ora.
Ivi vikapangiska kuti chombo ichi chiŵe chimoza mwa vyombo vyakupangika na ŵanthu ivyo vikwendapo mwaluŵiro chomene.<ref name="NASA2026">{{Cite web|url=https://science.nasa.gov/blogs/parker-solar-probe/2026/09/10/after-latest-swing-past-sun-nasas-parker-solar-probe-checks-in/|title=After Latest Swing Past Sun, NASA’s Parker Solar Probe Checks in|website=NASA Science|date=10 September 2026|access-date=9 November 2026}}</ref>
Pa 4 September 2026, Parker Solar Probe yikafiska ulendo wake wa pafupi na Dazi wa nambala 29. Yikafikaso pa mtunda na liŵiro ivyo vikaŵa kale vyapimika pa ulendo wake wa mu Disembala 2024.
NASA yikati chombo ichi chizamukhalilira kufufuza Dazi, ndipo mulimo wake wasazgikira mpaka mu 2029.<ref name="NASA2026"/>
== Kukhumbikwa kwa mulimo uwu ==
Parker Solar Probe yikovwira ŵasayansi kupulikiska umo Dazi likukhwaskira vyakuchitika mu mlengalenga.
Dazi likufumiska mphepo iyo yili na tinthu tuchoko na magineti. Mphepo iyi yikufika ku charu chapasi ndipo yingaŵa na vyakukhwaska pa vyakupangika na ŵanthu, mauthenga gha pa wayilesi na vyombo vyakuzungulira charu chapasi.
Kumanya umo mphepo iyi yikupangikira kungawovwira ŵasayansi kumanyilira kale vyakuchitika vyakofya vya mu mlengalenga.<ref name="NASA"/>
== Wonaniso ==
* [[Dazi]]
* [[NASA]]
* [[Mlengalenga]]
* [[Charu chapasi]]
* [[Mphepo ya Dazi]]
* [[Magineti]]
* [[Nyenyezi]]
* [[Umo vyombo vya mlengalenga vikugwilira ntchito]]
* [[Eugene Parker]]
== Ukaboni ==
<references/>
[[Category:Vyombo vya mlengalenga]]
[[Category:NASA]]
[[Category:Sayansi ya mlengalenga]]
[[Category:Kufufuza kwa Dazi]]
[[Category:Sayansi]]
5n2wd6hdhqv957uys0w0tndyoj4yy2i
Category:Vyombo vya mlengalenga
14
50261
124117
2026-11-09T19:51:29Z
Tumbuka Arch
6863
Created blank page
124117
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Sayansi ya mlengalenga
14
50262
124118
2026-11-09T19:51:33Z
Tumbuka Arch
6863
Created blank page
124118
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Kufufuza kwa Dazi
14
50263
124119
2026-11-09T19:51:36Z
Tumbuka Arch
6863
Created blank page
124119
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Sayansi
14
50264
124120
2026-11-09T19:51:38Z
Tumbuka Arch
6863
Created blank page
124120
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:NASA
14
50265
124121
2026-11-09T19:52:08Z
Tumbuka Arch
6863
Created blank page
124121
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Galimoto yapasi yaku machanya
0
50266
124122
2026-11-09T19:52:35Z
Tumbuka Arch
6863
Created page with "{{Short description|Galimoto ya roboti iyo yikugwiliskika ntchito pakufufuza malo gha pa mapulaneti}} {{Infobox | above = Galimoto yapasi yaku machanya | label1 = Mtundu | data1 = Galimoto ya roboti yakufufuza | label2 = Mulimo | data2 = Kufufuza malo gha pa mapulaneti na mwezi | label3 = Umo yikugwilira ntchito | data3 = Maukonde gha mawayilesi na ndondomeko za makompyuta | label4 = Malo agho yingagwiliskikire ntchito | data4 = Mars, Mwezi na mathupi ghanyake gha mu mle..."
124122
wikitext
text/x-wiki
{{Short description|Galimoto ya roboti iyo yikugwiliskika ntchito pakufufuza malo gha pa mapulaneti}}
{{Infobox
| above = Galimoto yapasi yaku machanya
| label1 = Mtundu
| data1 = Galimoto ya roboti yakufufuza
| label2 = Mulimo
| data2 = Kufufuza malo gha pa mapulaneti na mwezi
| label3 = Umo yikugwilira ntchito
| data3 = Maukonde gha mawayilesi na ndondomeko za makompyuta
| label4 = Malo agho yingagwiliskikire ntchito
| data4 = Mars, Mwezi na mathupi ghanyake gha mu mlengalenga
| label5 = Vyakwendeskera
| data5 = Mawiro, makamera na vyakupimira
| label6 = Vyakupeleka nkhongono
| data6 = Mphamvu ya Dazi panji nyukiliya
| label7 = Ŵakugwiliskira ntchito
| data7 = Mabungwe gha sayansi ya mlengalenga
}}
[[File:Curiosity - The Next Mars Rover.jpg|thumb|right|Chithuzithuzi cha galimoto ya Curiosity iyo yikapangika kuti ifufuze Mars.]]
[[File:First photo from Perseverance Rover.jpg|thumb|right|Chithuzithuzi chakwamba cha ku Mars icho chikatumizgika na Perseverance.]]
[[File:Diagram of the perseverance rover-instruments.jpg|thumb|right|Vyakupimira na vigaŵa vya galimoto ya Perseverance.]]
[[File:Curiosity on Mars.jpg|thumb|right|Galimoto ya Curiosity yikujipima pa malo agho yikafikako pa Mars.]]
'''Galimoto yapasi yaku machanya''' (rover) ni galimoto ya roboti iyo yikutumizgika ku malo ghanyake gha mu mlengalenga kuti yifufuze malo agho yikufikako.
Galimoto ya rover yikupangika kuti yendenge pa charu panji mwezi unyake kwambura kuyowoyeskana nayo mwakudunjika nga ni umo munthu wangachitira para wakwendeska galimoto.
Vyombo ivi vikugwiliskika ntchito chomene pakufufuza [[Mars]] na [[Mwezi]]. Vikovwira ŵasayansi kusonkhaniska vinjeru vya malo, malibwe, dongo, mphepo na vyakuchitika vya mu mlengalenga.<ref name="NASA">{{Cite web|url=https://science.nasa.gov/resource/nasas-perseverance-rover-lands-successfully-on-mars/|title=NASA’s Perseverance Rover Lands Successfully on Mars|website=NASA Science|date=18 February 2021|access-date=9 November 2026}}</ref>
== Mawonekedwe na umo yikugwilira ntchito ==
Galimoto ya rover yikupangika nga ni galimoto kweni yili na vyakupimira vya sayansi na ndondomeko za makompyuta.
Vigaŵa vyake vikuphatikizapo:
* Mawiro ghakwendeskera galimoto.
* Makamera ghakuwonera malo.
* Mikono yakukora panji kupima vinthu.
* Vyakupimira vya nyengo na chilengedwe.
* Makompyuta ghakulongozga ntchito za galimoto.
* Vyakupeleka nkhongono.
* Vyombo vyakutumizgira mauthenga ku charu chapasi.
Vyakupimira ivi vikovwira galimoto kuti yiwone malo, yimanye uko yili na kutumizga vinjeru ku ŵasayansi.
Rover zinyake zikugwiliskira ntchito mphamvu ya Dazi, apo zinyake zikugwiliskira ntchito mphamvu yakufuma ku nyukiliya.<ref name="NASA2">{{Cite web|url=https://www.nasa.gov/reference/nasa-glenn-press-kit/|title=NASA Glenn Press Kit|website=NASA|access-date=9 November 2026}}</ref>
== Ma rover gha pa Mars ==
[[Mars]] njimoza mwa malo agho ŵasayansi ŵatumizgako ma rover ghanandi kuti ghafufuze.
Ma rover agha ghakovwira kusambira za mbiri ya Mars na kumanya usange malo agha ghakaŵa na vyakukhumbikwa kuti vyamoyo vikhale.
=== Curiosity ===
Curiosity ni galimoto ya roboti iyo yikatumizgika na NASA kuti ikafufuze chigaŵa cha Gale Crater pa Mars.
Yikafika pa Mars pa 6 Ogasiti 2012. Yikupima malibwe, dongo na vinthu vinyake kuti ŵasayansi ŵapulikiske umo Mars yikaŵira kale.
Chilato chake chikuru nkhufufuza usange malo agha ghakaŵa na mikhalidwe yakwenelera kuti vyamoyo vichoko vikhale.<ref name="Curiosity">{{Cite web|url=https://science.nasa.gov/mission/msl-curiosity/|title=Curiosity Mars Rover|website=NASA Science|access-date=9 November 2026}}</ref>
=== Perseverance ===
Perseverance ni rover iyo yikafika pa Mars pa 18 February 2021. Yikafika mu chigaŵa cha Jezero Crater, icho ŵasayansi ŵakusachizga kuti kale chikaŵa na nyanja na mlonga.
Chombo ichi chikupima malo na kusonkhaniska tumasampuli twa malibwe na dongo kuti tiviŵikemo na kusungika kuti pa nyengo yinyake tingazakatoleke kuti tikasambirike pa charu chapasi.
Chilato chinyake cha Perseverance nkhupenja ukaboni wakuti vyamoyo vichoko vikaŵako pa Mars kale.<ref name="NASA"/>
== Ma rover gha pa Mwezi ==
Mwezi nawo wafufuzikapo na ma rover gha roboti. Vyombo ivi vikawovwira ŵasayansi kusambira umo malo gha pa Mwezi ghaliri, kusazgapo malibwe, dongo na malo ghakuzama.
Soviet Union ndiyo yikatuma ma rover gha Lunokhod ku Mwezi. Pamanyuma pake vyaru vinyake, kusazgapo China, navyo vikatumizga ma rover agho ghakafufuza malo gha pa Mwezi.
== Umo ma rover ghakulongozgekera ==
Ma rover ghakulongozgeka na ŵasayansi kufuma pa charu chapasi kwizira mu mauthenga gha wayilesi agho ghakutumizgika pakati pa rover na vyombo vinyake vya mlengalenga.
Chifukwa chakuti Mars na charu chapasi vili kutali chomene, mauthenga agha ghakutora nyengo kuti ghafike. Ntheura ma rover ghanyake ghali na ndondomeko za makompyuta izo zikughamovwira kugwilira ntchito ghanyake ghambura kudumulizgika na ŵanthu.
Makamera ghawo ghakutora vithuzithuzi vya malo kuti ŵasayansi ŵawone uko galimoto yingendera na ivyo yikuwona.<ref name="Curiosity"/>
== Kukhumbikwa kwa ma rover ==
Ma rover ngakuzirwa chomene pa kafukufuku wa mlengalenga chifukwa ghakovwira kusonkhaniska vinjeru vya malo agho munthu wandafikepo.
Ghakovwira ŵasayansi:
* Kusambira mbiri ya mapulaneti.
* Kupima malibwe na dongo.
* Kuphara umo nyengo yikukhalira pa mapulaneti.
* Kunjira mu malo agho ghali kutali na vyombo vikuru.
* Kupenja ukaboni wa umoyo uwo ukaŵako kale.
* Kunozgekera maulendo gha ŵanthu ku mapulaneti ghanyake.
== Wonaniso ==
* [[Mars]]
* [[Mwezi]]
* [[NASA]]
* [[Curiosity]]
* [[Perseverance]]
* [[Ingenuity]]
* [[Vyombo vya mlengalenga]]
* [[Roboti]]
* [[Mapulaneti]]
* [[Kufufuza mlengalenga]]
== Ukaboni ==
<references/>
[[Category:Vyombo vya mlengalenga]]
[[Category:Makina gha roboti]]
[[Category:Kufufuza mlengalenga]]
[[Category:Sayansi ya mlengalenga]]
f47dtvpbhp5980qq4be6mvu2ef6337u
Palawan
0
50267
124123
2026-11-09T19:53:02Z
Tumbuka Arch
6863
Created page with "{{Short description|Chirwa chikuru cha ku Philippines icho chili na vyamoyo vinandi}} {{Infobox | above = Palawan | label1 = Malo | data1 = [[Charu cha Philippines]] | label2 = Chigaŵa | data2 = Western Visayas na chigaŵa cha kumwera kwa Philippines | label3 = Mtundu wa malo | data3 = Chirwa | label4 = Malo ghakufupi | data4 = Nyanja ya South China na Nyanja ya Sulu | label5 = Likuru la chigaŵa | data5 = Puerto Princesa | label6 = Chiŵelengero cha visumbu mu chigaŵa..."
124123
wikitext
text/x-wiki
{{Short description|Chirwa chikuru cha ku Philippines icho chili na vyamoyo vinandi}}
{{Infobox
| above = Palawan
| label1 = Malo
| data1 = [[Charu cha Philippines]]
| label2 = Chigaŵa
| data2 = Western Visayas na chigaŵa cha kumwera kwa Philippines
| label3 = Mtundu wa malo
| data3 = Chirwa
| label4 = Malo ghakufupi
| data4 = Nyanja ya South China na Nyanja ya Sulu
| label5 = Likuru la chigaŵa
| data5 = Puerto Princesa
| label6 = Chiŵelengero cha visumbu mu chigaŵa chose
| data6 = Vyajumpha 1,700
| label7 = Malo gha chilengedwe cha UNESCO
| data7 = Palawan Biosphere Reserve
| label8 = Chaka icho chikasankhikira
| data8 = 1990
| label9 = Makonzedwe gha malo
| data9 = {{Coord|10|11|N|119|03|E|display=inline}}
}}
[[File:El Nido in Palawan.jpg|thumb|right|Malo gha El Nido mu chirwa cha Palawan.]]
[[File:Inside the Palawan underground River.jpg|thumb|right|Mlonga wa pasi pa charu mu chigaŵa cha Puerto Princesa.]]
[[File:Varanus palawanensis 578315370.jpg|thumb|right|Chiwombankhanga cha mu maji yayi, kweni mtundu wa varanid uwo ukusangika mu Palawan.]]
'''Palawan''' ni chirwa chikuru icho chili mu [[Charu cha Philippines]], ku chigaŵa cha kumanjiliro gha dazi kwa charu ichi. Chirwa ichi chili na malo ghakutowa, mapiri, nkhorongo, madambo, milonga ya pasi pa charu na magombe ghakupambanapambana.
Zina lakuti Palawan likugwiliskirikaso ntchito pa chigaŵa cha boma icho chili na chirwa chikuru ichi na visumbu vinyake vinandi.
Palawan yikumanyikwa chomene chifukwa cha vyamoyo vyake vinandi, malo ghakutowa na vyakuchitika vya ŵanthu ŵakwambilira.<ref name="UNESCO">{{Cite web|url=https://www.unesco.org/en/mab/palawan|title=Palawan|website=UNESCO Man and the Biosphere Programme|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Palawan chili ku kumanjiliro gha dazi kwa [[Charu cha Philippines]]. Chigaŵa ichi chili pakati pa Nyanja ya South China na [[Nyanja ya Sulu]].
Chirwa chikuru cha Palawan ntchitali ndipo chili na mapiri, nkhorongo na vigaŵa vya mumphepete mwa nyanja.
Chigaŵa cha boma cha Palawan chili na chirwa chikuru ichi kweniso visumbu vinyake vyakujumpha 1,700. Bungwe la UNESCO likulongosora kuti Palawan Biosphere Reserve yikusazgapo chigaŵa chose cha boma la Palawan.<ref name="UNESCO"/>
== Misumba na malo ghakumanyikwa ==
Malo ghanyake agho ghakumanyikwa chomene mu Palawan ni:
* '''Puerto Princesa''' – ni likuru la chigaŵa cha boma la Palawan.
* '''El Nido''' – yikumanyikwa chifukwa cha malibwe ghakuru gha limestone, magombe na maji ghatuŵa.
* '''Coron''' – yikumanyikwa chifukwa cha vyaru vyake vya mu nyanja na malo gha kusambira pasi pa maji.
* '''Taytay''' – ni malo agho ghali na mbiri ya kale.
* '''Balabac''' – ni chigaŵa icho chili na visumbu na magombe.
Malo agha ghakovwira chomene pa ntchito za ulendo wa ŵanthu awo ŵakufuma mu Philippines na vyaru vinyake.
== Vyamoyo na chilengedwe ==
Palawan yili na vyamoyo vinandi chomene vya mu charu na mu nyanja. UNESCO yikulongosora kuti chigaŵa cha Palawan chili na mitundu yakupambanapambana ya vyakumera na vinyama.
Mu vyamoyo ivyo vikusangika mu chigaŵa ichi muli:
* [[Viyuni]] vyakupambanapambana.
* [[Vyamoyo vya mu nyanja]].
* [[Njovu ya mu nyanja]].
* [[Tizilombo]] twakupambanapambana.
* [[Vyaru vya mu madambo]].
* [[Vyakumera vya mu nkhorongo]].
* [[Vyamoyo vyakukhala mu maji ghawemi]].
UNESCO yikulongosora kuti mu chigaŵa cha Palawan muli mitundu 105 mwa mitundu 475 ya vyamoyo ivyo vili mu ngozi ya kumara mu Philippines. Mitundu 42 mwa vyamoyo ivyo vikukhumbikwira kusungililika ni vyamoyo ivyo vikukhala mu Palawan pera.<ref name="UNESCO"/>
== Nkhorongo na vyakumera ==
Palawan yili na nkhorongo zakale na nkhorongo izo zakuliskikaso pamanyuma pa kuparanyika. Malo agha ghali na vyakumera vinandi vyakupambanapambana.
Mu chigaŵa ichi muli:
* Nkhorongo za mu vyaru vyakufunda.
* Nkhorongo za m'mphepete mwa nyanja.
* Nkhorongo za mitengo ya mangrove.
* Malo gha limestone.
* Malo gha vyakumera vya m'mphepete mwa maji.
* Malo ghakukhala vyamoyo vya mu maji ghawemi.
Malo gha mangrove gha Palawan ngakuzirwa chomene chifukwa ghakovwira pa kusungilira maji na kupeleka malo ghakukhala vyamoyo vya mu nyanja.<ref name="UNESCO"/>
== Nyanja na vyamoyo vyake ==
Mumphepete mwa Palawan pali malo ghanandi gha nyanja agho ghali na vyamoyo vyakupambanapambana.
UNESCO yikulongosora kuti mu malo gha nyanja agha muli mitundu yakujumpha 379 ya [[coral]], mitundu 13 ya vyakumera vya mu maji na mitundu 31 ya vyakumera vya mangrove.
Vinyama vinyake ivyo vikusangika mu nyanja za Palawan ni:
* [[Turtle wa mu nyanja]].
* [[Dugong]].
* [[Whale shark]].
* [[Somba]] za mitundu yakupambanapambana.
* Vyamoyo vinyake vya mu maji.<ref name="UNESCO"/>
== Mlonga wa pasi pa charu wa Puerto Princesa ==
Mu chigaŵa cha Puerto Princesa muli malo ghakumanyikwa gha mlonga wa pasi pa charu, uwo ukuluta mukati mwa mapanga gha malibwe.
Mlonga uwu ukusangika mu malo ghakusungirako chilengedwe gha Puerto-Princesa Subterranean River National Park. Ŵalendo ŵakuyenda mu boti kuti ŵawone mapanga na malibwe ghakupambanapambana agho ghali mukati mwa malo agha.
Malo agha ngakuzirwa chomene pa nkhani ya chilengedwe na ulendo wa ŵanthu.
== Ŵanthu na umoyo wawo ==
Palawan yili na mitundu yinandi ya ŵanthu awo ŵali na viyowoyero, maluso na chikhalidwe chakupambanapambana.
Mwakuyana na UNESCO, mu chigaŵa ichi muli pafupifupi magulu 57 gha ŵanthu awo ŵali na viyowoyero vya mitundu yakupambanapambana. Mu magulu agha muli:
* [[ŴaPalaw'an]].
* [[ŴaTagbanwa]].
* [[ŴaBatak]].
Ŵanthu ŵanandi ŵakugwira ntchito ya ulimi, kusomba somba na ntchito za ulendo wa ŵanthu.<ref name="UNESCO"/>
== Chuma ==
Ntchito zikuru izo zikovwira pa chuma cha Palawan ni:
* [[Ulimi]].
* Kusomba somba.
* Ulendo wa ŵanthu.
* Kuguliska vyakumera vya mu nkhorongo.
* Kugwira ntchito za migodi.
* Kulima na kupwelelera vyakumera vya mu maji.
Ulendo wa ŵanthu ngwakuzirwa chomene chifukwa cha magombe, mapanga, nyanja na malo ghanyake ghakutowa.
== Kusungilira chilengedwe ==
UNESCO yikasankha Palawan kuŵa chigaŵa cha biosphere reserve mu 1990 chifukwa cha vyamoyo vyake vinandi na kukhumbikwa kwake pa chilengedwe.
Kusungilira nkhorongo, magombe, madambo, mapanga na vyamoyo vya mu nyanja nkhwakuzirwa kuti chigaŵa ichi chilutilire kuŵa na vyamoyo vyakupambanapambana.<ref name="UNESCO"/>
== Wonaniso ==
* [[Charu cha Philippines]]
* [[ŴaPalaw'an]]
* [[El Nido]]
* [[Puerto Princesa]]
* [[Nyanja ya Sulu]]
* [[Nyanja ya South China]]
* [[Nkhorongo za mangrove]]
* [[Chilengedwe]]
* [[Malo gha chiharo cha pa charu chose]]
* [[Vyamoyo vyakupwetekeka]]
== Ukaboni ==
<references/>
[[Category:Virwa vya ku Asia]]
[[Category:Vinthu vya ku Philippines]]
[[Category:Kakhalilo ka malo]]
[[Category:Chilengedwe]]
[[Category:Malo gha chilengedwe gha UNESCO]]
1vke0nfpvkr66tswjeoi2hbsuvw1jqz
Category:Ulimi
14
50268
124125
2026-11-09T19:54:17Z
Tumbuka Arch
6863
Created blank page
124125
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Vyakurya
0
50269
124126
2026-11-09T19:54:38Z
Tumbuka Arch
6863
Redirected page to [[Chakulya]]
124126
wikitext
text/x-wiki
#REDIRECT [[Chakulya]]
2f9zzjvgcjse6gthj0zg2om939nu6ez
Category:Vyakukhumbikwa pa umoyo
14
50270
124127
2026-11-09T19:54:47Z
Tumbuka Arch
6863
Created blank page
124127
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Umoyo wa ŵanthu
14
50271
124129
2026-11-09T19:55:47Z
Tumbuka Arch
6863
Created blank page
124129
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vyakurya
14
50272
124130
2026-11-09T19:55:51Z
Tumbuka Arch
6863
Created blank page
124130
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Mutianyu
0
50273
124131
2026-11-09T20:04:00Z
Tumbuka Arch
6863
Created page with "{{Short description|Chigaŵa chakumanyikwa cha Chimakoma Chikuru cha China}} {{Infobox | above = Mutianyu | label1 = Malo | data1 = Huairou, [[Mzinda wa Beijing]], [[Charu cha China]] | label2 = Mtundu wa malo | data2 = Chigaŵa cha Chimakoma Chikuru cha China | label3 = Nyengo iyo chikazengekera chomene | data3 = Mbumba ya Ming | label4 = Ŵanthu awo ŵakazenga | data4 = Ŵalongozgi na ŵasilikari ŵa China | label5 = Chigaŵa cha mbiri | data5 = Northern China | label6..."
124131
wikitext
text/x-wiki
{{Short description|Chigaŵa chakumanyikwa cha Chimakoma Chikuru cha China}}
{{Infobox
| above = Mutianyu
| label1 = Malo
| data1 = Huairou, [[Mzinda wa Beijing]], [[Charu cha China]]
| label2 = Mtundu wa malo
| data2 = Chigaŵa cha Chimakoma Chikuru cha China
| label3 = Nyengo iyo chikazengekera chomene
| data3 = Mbumba ya Ming
| label4 = Ŵanthu awo ŵakazenga
| data4 = Ŵalongozgi na ŵasilikari ŵa China
| label5 = Chigaŵa cha mbiri
| data5 = Northern China
| label6 = Malo gha chiharo cha charu chose
| data6 = Chimakoma Chikuru cha China
| label7 = Makonzedwe gha malo
| data7 = {{Coord|40|25|N|116|33|E|display=inline}}
}}
[[File:The Mutianyu section of the Great Wall of China.jpg|thumb|right|Chigaŵa cha Mutianyu cha Chimakoma Chikuru cha China.]]
[[File:Great Wall of China, Mutianyu Section.jpg|thumb|right|Chimakoma cha ku Mutianyu chikujumpha pa mapiri.]]
[[File:Mutianyu Great Wall, Beijing, China (9761824011).jpg|thumb|right|Minara ya Chimakoma Chikuru mu chigaŵa cha Mutianyu.]]
[[File:Great Wall at Mutianyu (11513482695).jpg|thumb|right|Nthowa ya pa Chimakoma Chikuru mu Mutianyu.]]
'''Mutianyu''' ni chigaŵa cha [[Chimakoma Chikuru cha China]] icho chili mu chigaŵa cha Huairou, kufupi na [[Mzinda wa Beijing]] mu [[Charu cha China]]. Chigaŵa ichi ntchimoza mwa vigaŵa vyakusungika makora chomene vya Chimakoma Chikuru.
Mutianyu chikazengeka chomene mu nyengo ya [[Mbumba ya Ming]] ndipo chikaŵa chigaŵa chakovwira pa kuvikilira mphaka ya kumpoto kwa ufumu wa China. Mazuŵa ghano chikumanyikwa chomene chifukwa cha mbiri yake, kuzenga kwake na malo ghakutowa agho ghali kuzingilizgika na mapiri na nkhorongo.<ref name="Beijing">{{Cite web|url=https://english.beijing.gov.cn/travellinginbeijing/attractions/202603/t20260325_4566115.html|title=Mutianyu Great Wall|website=People's Government of Beijing Municipality|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Mutianyu chili mu chigaŵa cha Huairou, kumpoto cha kumafumiro gha dazi kwa Beijing.
Malo agha ghali pa mapiri agho ghali na nkhorongo. Chifukwa cha malo agho chili, Chimakoma chikujumpha pa mapiri na kupanga mawonekedwe ghakukondweska.
Mwakuyana na boma la Beijing, malo agha ghali na vyakumera vinandi chomene ndipo chiŵelengero cha malo ghakusazgikira na vyakumera chili pachanya chomene.<ref name="Beijing"/>
== Mbiri ya Mutianyu ==
Chigaŵa cha Mutianyu chikazengeka chomene mu nyengo ya Mbumba ya Ming. Mbumba iyi yikalamulira China pakati pa 1368 na 1644 ndipo yikazenga na kunozga vigaŵa vinandi vya Chimakoma Chikuru kuti ivikilire charu ku viwukirano vya kufuma kumpoto.
Chigaŵa ichi chikaŵa chimoza mwa malo ghakuzirwa pa ntchito ya ŵasilikari na kuvikilira mphaka za ufumu.
Mutianyu chikaŵa pakati pa vigaŵa vya Gubeikou kumafumiro gha dazi na Juyongguan kumanjiliro gha dazi.<ref name="Beijing"/>
== Umo Chimakoma cha Mutianyu chiliri ==
Chimakoma cha Mutianyu chili na mawonekedwe ghakupambanapambana agho ghakulongora umo ŵanthu ŵakazengera kuti ŵavikilire malo agha.
Vinthu vyake vikuphatikizapo:
* Minara yakulaŵilira.
* Vipata vya ŵasilikari.
* Makoma ghakukhora gha malibwe.
* Nthowa zakwendamo ŵasilikari.
* Malo ghakupokelera ŵanthu awo ŵakendanga.
* Makoma gha mphanyi gha vigaŵa vyose viŵiri.
Chigaŵa ichi chili na minara yinandi iyo yikaŵa yakovwira kulinda malo na kuwona awo ŵakendanga kufupi na mphaka.
Minara yinyake yakumanyikwa ni Zhengguan Pass na Dajiaolou.<ref name="Beijing"/>
== Chimakoma Chikuru na Mbumba ya Ming ==
Chimakoma Chikuru cha China ni chimakoma cha mbiri icho chikazengeka, kunozgekaso na kusazgikira kwa vyaka vinandi.
UNESCO yikulongosora kuti ntchito yakuzenga chigaŵa ichi yikachitika kufuma m'ma 200 B.C.E. m'paka m'ma 1600. Mu nyengo ya Ming, Chimakoma Chikuru chikafika pa kukura kwake kukuru chomene pa ntchito ya ŵasilikari na kuzenga.<ref name="UNESCO">{{Cite web|url=https://whc.unesco.org/en/list/438/|title=The Great Wall|website=UNESCO World Heritage Centre|access-date=9 November 2026}}</ref>
Mu 1987, Chimakoma Chikuru chikasankhika kuŵa malo gha chiharo cha pa charu chose gha UNESCO.<ref name="UNESCO"/>
Mutianyu ni chigaŵa chimoza icho chikulongora makora luso lwa ŵanthu ŵa ku China pa kuzenga makoma ghakuru.
== Ulendo wa ŵanthu ==
Mazuŵa ghano Mutianyu ni malo ghakumanyikwa chomene gha ulendo wa ŵanthu mu Beijing.
Ŵalendo ŵakufuma mu vyaru vinandi ŵakwendako kuti ŵawone Chimakoma Chikuru na kusambira za mbiri ya China.
Vinthu vinyake ivyo ŵalendo ŵangachita ni:
* Kwenda pa Chimakoma Chikuru.
* Kuwona minara yakale.
* Kujara vithuzithuzi vya mapiri na nkhorongo.
* Kugwiliskira ntchito magalimoto gha chingwe kuti ŵafike ku malo ghapachanya.
* Kusambirapo vya mbiri ya mbumba za ku China.
Mu 2011, malo gha Mutianyu ghakapika udindo wa chigaŵa cha ulendo wa ŵanthu cha gulu la 5A mu China.<ref name="Beijing"/>
== Kusungilira malo gha Mutianyu ==
Chimakoma Chikuru ni chinthu chakuzirwa pa mbiri ya charu cha China na pa mdauko wa ŵanthu pa charu chose.
Kusungilira makoma, minara na malo ghakuzingilizga kukovwira kuti ŵanthu ŵa mazuŵa ghano na ŵa munthazi ŵazakaŵe na mwaŵi wakusambira za mbiri ya kuzenga kwa kale.
== Wonaniso ==
* [[Chimakoma Chikuru cha China]]
* [[Mbumba ya Ming]]
* [[Mzinda wa Beijing]]
* [[Charu cha China]]
* [[Huairou]]
* [[Mbiri ya China]]
* [[Kuzenga]]
* [[Malo gha chiharo cha pa charu chose]]
* [[Ulendo wa ŵanthu]]
== Ukaboni ==
<references/>
[[Category:Mbiri ya China]]
[[Category:Vinthu vya ku China]]
[[Category:Kuzenga kwa kale]]
[[Category:Malo gha ulendo wa ŵanthu]]
[[Category:Malo gha chiharo cha pa charu chose]]
81w7xqh8ksq6bnhauzasz6mywo6rvgr
Category:Vinthu vya ku China
14
50274
124132
2026-11-09T20:04:22Z
Tumbuka Arch
6863
Created blank page
124132
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Kuzenga kwa kale
14
50275
124133
2026-11-09T20:04:25Z
Tumbuka Arch
6863
Created blank page
124133
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Malo gha ulendo wa ŵanthu
14
50276
124134
2026-11-09T20:04:29Z
Tumbuka Arch
6863
Created blank page
124134
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Malo gha chiharo cha pa charu chose
14
50277
124135
2026-11-09T20:04:34Z
Tumbuka Arch
6863
Created blank page
124135
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Malibwe
0
50278
124136
2026-11-09T20:12:09Z
Tumbuka Arch
6863
Redirected page to [[Libwe]]
124136
wikitext
text/x-wiki
#REDIRECT [[Libwe]]
aqzuzp2vk2fnm24xdkfu8w7t8pq2vw0
Libwe
0
50279
124137
2026-11-09T20:12:23Z
Tumbuka Arch
6863
Created page with "{{Short description|Chinthu chakukhoma icho chikupangika mwachilengedwe mu charu}} {{Infobox | name = Libwe | image = Granite rock.jpg | caption = Libwe la granite | category = Vinthu vya mu charu }} '''Libwe''' ni chinthu chakukhoma icho chikupangika mwachilengedwe mu charu chapasi. Malibwe ghali na mitundu yakupambanapambana ndipo ghakusiyana mu kawonekero, mtundu, ukuru na vinthu ivyo ghakupangikira. Malibwe ngakuzirwa chomene mu [[geology]] ndipo ghakovwira kumanya..."
124137
wikitext
text/x-wiki
{{Short description|Chinthu chakukhoma icho chikupangika mwachilengedwe mu charu}}
{{Infobox
| name = Libwe
| image = Granite rock.jpg
| caption = Libwe la granite
| category = Vinthu vya mu charu
}}
'''Libwe''' ni chinthu chakukhoma icho chikupangika mwachilengedwe mu charu chapasi. Malibwe ghali na mitundu yakupambanapambana ndipo ghakusiyana mu kawonekero, mtundu, ukuru na vinthu ivyo ghakupangikira.
Malibwe ngakuzirwa chomene mu [[geology]] ndipo ghakovwira kumanya mbiri ya charu chapasi.
== Mitundu ya malibwe ==
Ŵasayansi ŵakagaŵa malibwe mu magulu ghatatu ghakuru.
=== Malibwe ghakufuma ku magma ===
Malibwe agha ghakupangika para magma panji lava yazizima na kukhora.
Chiyerezgero chake ni:
* Granite.
* Basalt.
* Obsidian.
=== Malibwe ghakupangika na kusonkhana kwa vinthu ===
Malibwe agha ghakupangika para mchenga, dongo na vinthu vinyake vikusonkhana na kukhora kwa nyengo yitali.
Chiyerezgero chake ni:
* Sandstone.
* Limestone.
* Shale.
=== Malibwe ghakusintha kawonekero ===
Malibwe agha ghakusintha chifukwa cha kutentha kukuru panji msinjiro wa mu charu.
Chiyerezgero chake ni:
* Marble.
* Slate.
* Gneiss.
== Kuzirwa kwa malibwe ==
Malibwe ghali na ntchito zinandi:
* Kugwiliskira ntchito pakuzenga nyumba.
* Kupanga misewu.
* Kupanga vimanyikwiro na vyakudyo.
* Kusanga visulo na vinthu vinyake vya mu charu.
* Kovwira ŵasayansi kusambira mbiri ya charu chapasi.
== Malibwe na chilengiwa ==
Malibwe ghakovwira kupanga mapiri, vikwezga na malo ghanyake gha chilengiwa. Maji na mphepo vikhoza kusintha kawonekero ka malibwe mu nyengo yitali.
Malibwe ghanyake ghali na viswaswa vya vyamoyo vyakale ivyo vikovwira kumanya umo umoyo ukaŵira mu nyengo zakale.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Granite rock.jpg|Libwe la granite
Basalt rock.jpg|Libwe la basalt
Sandstone rock.jpg|Libwe la sandstone
Marble stone.jpg|Libwe la marble
Obsidian.jpg|Libwe la obsidian
Limestone rock.jpg|Libwe la limestone
</gallery>
== Wonaniso ==
* [[Geology]]
* [[Mapiri]]
* [[Dongo]]
* [[Mchenga]]
* [[Chilengiwa]]
== Ukaboni ==
* [https://www.britannica.com/science/rock-geology Rock – Encyclopaedia Britannica]
* [https://www.usgs.gov/ US Geological Survey]
* [https://www.nps.gov/subjects/geology/index.htm National Park Service – Geology]
[[Category:Malibwe]]
[[Category:Geology]]
[[Category:Chilengiwa]]
[[Category:Vinthu vya mu charu]]
bbjmg6uwhgws813hf7vilmwpcd2fmsm
Category:Malibwe
14
50280
124138
2026-11-09T20:12:47Z
Tumbuka Arch
6863
Created blank page
124138
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vinthu vya mu charu
14
50281
124139
2026-11-09T20:12:49Z
Tumbuka Arch
6863
Created blank page
124139
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Chilengiwa
14
50282
124140
2026-11-09T20:12:53Z
Tumbuka Arch
6863
Created blank page
124140
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Articles using infobox templates with no data rows
14
50283
124141
2026-11-09T20:12:56Z
Tumbuka Arch
6863
Created blank page
124141
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Makuni
0
50284
124142
2026-11-09T20:13:36Z
Tumbuka Arch
6863
Redirected page to [[Khuni]]
124142
wikitext
text/x-wiki
#REDIRECT [[Khuni]]
1zq8kopnxscbk1cyrckvcvwv0v2to8a
Khuni
0
50285
124143
2026-11-09T20:13:46Z
Tumbuka Arch
6863
Created page with "{{Short description|Chigaŵa chikuru cha chimera icho chili na thunthu na minthavi}} {{Infobox | name = Khuni | image = Tree.jpg | caption = Khuni likuru | category = Vyakumera }} '''Khuni''' ni chimera chikuru icho kanandi chikuŵa na thunthu limoza lakukhoma, minthavi na masamba. Makuni ghakupambanapambana mu ukuru, kawonekero na malo agho ghakukulira. Makuni ghalipo mu vigaŵa vinandi vya charu chapasi ndipo ngakuzirwa chomene pa umoyo wa ŵanthu na nyama. == Viga..."
124143
wikitext
text/x-wiki
{{Short description|Chigaŵa chikuru cha chimera icho chili na thunthu na minthavi}}
{{Infobox
| name = Khuni
| image = Tree.jpg
| caption = Khuni likuru
| category = Vyakumera
}}
'''Khuni''' ni chimera chikuru icho kanandi chikuŵa na thunthu limoza lakukhoma, minthavi na masamba. Makuni ghakupambanapambana mu ukuru, kawonekero na malo agho ghakukulira.
Makuni ghalipo mu vigaŵa vinandi vya charu chapasi ndipo ngakuzirwa chomene pa umoyo wa ŵanthu na nyama.
== Vigaŵa vya khuni ==
Khuni kanandi lili na vigaŵa ivi:
* Mizi: yikovwira kukaka khuni mu dongo na kuyamwa maji.
* Thunthu: likovwira kunyamura minthavi na masamba.
* Minthavi: yikukulira kufuma pa thunthu.
* Masamba: ghakovwira khuni kupanga chakulya chake.
* Maluwa: ghakovwira pa kubabana kwa vyakumera vinandi.
* Vipambi: vikupangika pa makuni ghanyake ndipo vingaŵa na mbuto.
== Mitundu ya makuni ==
Pali mitundu yinandi ya makuni pa charu chapasi.
Makuni ghanyake ghakukhala na masamba nyengo zose, apo ghanyake ghakuthiska masamba ghake mu nyengo zinyake.
Makuni ghanyake ghakumanyikwa ni:
* [[Mupaini]].
* [[Mubawa]].
* [[Mango]].
* [[Baobab]].
* [[Mkuyu]].
== Kuzirwa kwa makuni ==
Makuni ghali na ntchito zinandi:
* Ghakovwira kupanga mphepo yakupemeka.
* Ghakupereka chakulya ku ŵanthu na nyama.
* Ghakupereka malo ghakukhala viyuni na nyama.
* Ghakovwira kuchepeska kunangika kwa dongo.
* Ghakovwira kusunga maji mu dongo.
* Ghakupereka makuni ghakuzengera nyumba na kupanga vinthu.
== Makuni na chilengiwa ==
Makuni ngakuzirwa chomene mu nkhorongo. Ghakovwira kuti malo gha vyamoyo ghakhalenge na umoyo.
Makuni ghakugwiliskirikaso ntchito pa kuchepeska mpweya wa carbon dioxide mu mlengalenga kwizira mu ndondomeko ya photosynthesis.
== Kusungilira makuni ==
Kudumura makuni ghanandi kwambura kupandaso ghanyake kungananga nkhorongo. Ntheura, kupanda makuni na kusungilira nkhorongo ni vinthu vyakuzirwa pa kupwelelera chilengiwa.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Tree.jpg|Khuni
Baobab tree.jpg|Khuni la baobab
Oak tree.jpg|Khuni la oak
Pine trees.jpg|Makuni gha mupaini
Rainforest trees.jpg|Makuni gha mu nkhorongo
</gallery>
== Wonaniso ==
* [[Vyakumera]]
* [[Nkhorongo]]
* [[Chilengiwa]]
* [[Mizi ya khuni]]
* [[Masamba]]
== Ukaboni ==
* [https://www.britannica.com/plant/tree Tree – Encyclopaedia Britannica]
* [https://www.fao.org/forestry/en/ FAO – Forestry]
* [https://www.unep.org/ United Nations Environment Programme]
[[Category:Makuni]]
[[Category:Vyakumera]]
[[Category:Chilengiwa]]
[[Category:Sayansi ya vyakumera]]
0rhnwme2o8xgesgsrimv7bwwy6tfkqn
UNESCO World Heritage Site
0
50286
124144
2026-11-09T20:14:59Z
Tumbuka Arch
6863
Redirected page to [[Ukaboni wa pa Charu Chose wa vya UNESCO]]
124144
wikitext
text/x-wiki
#REDIRECT [[Ukaboni wa pa Charu Chose wa vya UNESCO]]
5wf6mq8d3mrsypj61w7a094iedq54me
Ukaboni wa pa Charu Chose wa vya UNESCO
0
50287
124145
2026-11-09T20:15:09Z
Tumbuka Arch
6863
Created page with "{{Short description|Malo agho ghali na kuzirwa kukuru pa charu chose}} {{Infobox | name = Ukaboni wa pa Charu Chose | image = World Heritage emblem.svg | caption = Chimanyikwiro cha Ukaboni wa pa Charu Chose | organisation = UNESCO | established = 1972 }} '''Ukaboni wa pa Charu Chose''' ni malo panji vinthu ivyo vili na kuzirwa kukuru chomene pa charu chose chifukwa cha mbiri, mitheto, sayansi panji [[chilengiwa]] chake. Malo agha ghakuzomerezgeka na [[UNESCO]] mwakuya..."
124145
wikitext
text/x-wiki
{{Short description|Malo agho ghali na kuzirwa kukuru pa charu chose}}
{{Infobox
| name = Ukaboni wa pa Charu Chose
| image = World Heritage emblem.svg
| caption = Chimanyikwiro cha Ukaboni wa pa Charu Chose
| organisation = UNESCO
| established = 1972
}}
'''Ukaboni wa pa Charu Chose''' ni malo panji vinthu ivyo vili na kuzirwa kukuru chomene pa charu chose chifukwa cha mbiri, mitheto, sayansi panji [[chilengiwa]] chake.
Malo agha ghakuzomerezgeka na [[UNESCO]] mwakuyana na Phangano la Ukaboni wa pa Charu Chose la 1972.
== Mbiri ==
Mu 1972, vyaru ivyo vikaŵa mu UNESCO vikazomerezga phangano lakuvikilira malo ghakuzirwa pa charu chose.
Phangano ili likamba kugwira ntchito mu 1975. Chilato chake chikaŵa chakuti vyaru vigwirane ntchito kuti visungilire malo agho ghali na kuzirwa kukuru ku ŵanthu wose.
== Mitundu ya Ukaboni wa pa Charu Chose ==
Pali mitundu yitatu yikuru.
=== Ukaboni wa mitheto ===
Uwu ukusazgapo nyumba zakale, mizinda, malo gha mbiri na vinthu ivyo vikulongora umoyo wa ŵanthu mu nyengo zakale.
=== Ukaboni wa chilengiwa ===
Uwu ukusazgapo malo agho ghali na vinthu vyapadera vya chilengiwa, nga ni mapiri, nkhorongo, nyanja na malo gha vyamoyo vyakupambanapambana.
=== Ukaboni wakusazgikana ===
Malo ghanyake ghali na kuzirwa kwa mitheto na chilengiwa pa nyengo yimoza.
== Malo ghakumanyikwa gha Ukaboni wa pa Charu Chose ==
Malo agha ghakusazgapo:
* [[Chiliŵa chikulu cha China]] ku China.
* [[Meteora]] ku Greece.
* [[Taj Mahal]] ku India.
* [[Mapiri gha Kilimanjaro]] ku Tanzania.
* [[Victoria Falls]] pakati pa Zambia na Zimbabwe.
* [[Galápagos Islands]] ku Ecuador.
== Kufuma pa mndandanda ==
Malo ghakusankhika na Komiti ya Ukaboni wa pa Charu Chose. Vyaru vikwenera kulemba malo agho vikukhumba kuti ghazomerezgeke ndipo vikupereka ukaboni wakulongora chifukwa icho malo agha ngakuzirwa.
== Kusungilira malo agha ==
Vyaru ivyo vili na malo gha Ukaboni wa pa Charu Chose vili na udindo wa kughasungilira. UNESCO yikovwira kwizira mu fundo za sayansi, masambiro na kovwirana kwa vyaru.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
World Heritage emblem.svg|Chimanyikwiro cha Ukaboni wa pa Charu Chose
Great Wall of China.jpg|Chiliŵa chikulu cha China
Meteora monasteries Greece.jpg|Meteora
Taj Mahal in March 2004.jpg|Taj Mahal
Mount Kilimanjaro.jpg|Phiri la Kilimanjaro
Victoria Falls aerial view.jpg|Chipopoma cha Victoria
</gallery>
== Wonaniso ==
* [[UNESCO]]
* [[Chilengiwa]]
* [[Mbiri]]
* [[Mitheto]]
* [[Chiliŵa chikulu cha China]]
* [[Meteora]]
== Ukaboni ==
* [https://whc.unesco.org/en/convention/ UNESCO – World Heritage Convention]
* [https://whc.unesco.org/en/list/ UNESCO – World Heritage List]
* [https://www.unesco.org/en UNESCO]
[[Category:UNESCO]]
[[Category:Ukaboni wa pa Charu Chose]]
[[Category:Mitheto]]
[[Category:Chilengiwa]]
30r05aso2vpcjejhbokmlk3c4cck922
Category:Ukaboni wa pa Charu Chose
14
50288
124146
2026-11-09T20:15:30Z
Tumbuka Arch
6863
Created blank page
124146
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mitheto
14
50289
124147
2026-11-09T20:15:33Z
Tumbuka Arch
6863
Created blank page
124147
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Milonga
0
50290
124148
2026-11-09T20:16:02Z
Tumbuka Arch
6863
Redirected page to [[Mlonga]]
124148
wikitext
text/x-wiki
#REDIRECT [[Mlonga]]
l5chiom7go30334xytywbfbx4c1b8cz
Mlonga
0
50291
124149
2026-11-09T20:16:13Z
Tumbuka Arch
6863
Created page with "{{Short description|Maji agho ghakwenda mu nthowa yakujumpha pa charu}} {{Infobox | name = Mlonga | image = Amazon River.jpg | caption = Mlonga wa Amazon | category = Malo gha maji }} '''Mlonga''' ni maji agho ghakwenda mwakufuma ku malo ghapachanya kuya ku malo ghapasi, mu nyanja panji mu mlonga unyake. Milonga njimoza mwa vinthu vyakuzirwa chomene mu [[chilengiwa]]. Milonga yikusangika mu vyaru vinandi pa charu chose. Yikovwira ŵanthu, nyama na vyakumera kusanga maj..."
124149
wikitext
text/x-wiki
{{Short description|Maji agho ghakwenda mu nthowa yakujumpha pa charu}}
{{Infobox
| name = Mlonga
| image = Amazon River.jpg
| caption = Mlonga wa Amazon
| category = Malo gha maji
}}
'''Mlonga''' ni maji agho ghakwenda mwakufuma ku malo ghapachanya kuya ku malo ghapasi, mu nyanja panji mu mlonga unyake. Milonga njimoza mwa vinthu vyakuzirwa chomene mu [[chilengiwa]].
Milonga yikusangika mu vyaru vinandi pa charu chose. Yikovwira ŵanthu, nyama na vyakumera kusanga maji.
== Kapangidwe ka mlonga ==
Mlonga kanandi ukwambira pa malo ghapachanya nga ni mapiri, malo gha maji ghakufuma mu charu, panji mu madambo.
Mlonga ungamalira mu:
* [[Nyanja]].
* [[Nyanja yikuru]].
* Mlonga unyake.
* Malo ghanyake gha maji.
Malo agho maji ghakufuma kuti ghapange mlonga ghakuchemeka mutu wa mlonga.
== Vigaŵa vya mlonga ==
Mlonga ungaŵa na vigaŵa vitatu:
* Chigaŵa chapachanya, uko maji ghakwenda luŵiro chifukwa cha malo ghakukwera.
* Chigaŵa chapakati, uko mlonga ukwamba kuŵa ukuru.
* Chigaŵa chapasi, uko maji ghakwenda mwapusu kuya ku malo agho mlonga ukumalira.
== Milonga yikuru pa charu chose ==
Milonga yikuru yikusazgapo:
* [[Mlonga wa Amazon]] mu South America.
* [[Mlonga wa Nile]] mu Africa.
* [[Mlonga wa Yangtze]] mu China.
* [[Mlonga wa Mississippi]] mu North America.
* [[Mlonga wa Congo]] mu Africa.
== Kuzirwa kwa milonga ==
Milonga yikovwira mu nthowa zinandi:
* Kupereka maji ghakumwa.
* Kuthilira minda.
* Kupereka malo ghakukhala somba na vyamoyo vinyake.
* Kovwira pa mayendedwe gha maboti.
* Kupereka maji ghakugwiliskira ntchito kupanga magesi.
* Kovyera pa ulovi.
== Milonga na chilengiwa ==
Milonga njimoza mwa vigaŵa vikuru vya chilengiwa. Yikupereka maji ku vyamoyo na kovwira kuti malo ghakupambanapambana ghaŵe na umoyo.
Kweni, kunanga maji, kutaya viswaswa na kuzenga vinthu mu malo gha mlonga kungananga malo agha.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Amazon River.jpg|Mlonga wa Amazon
Nile River.jpg|Mlonga wa Nile
Congo River aerial view.jpg|Mlonga wa Congo
Mississippi River.jpg|Mlonga wa Mississippi
Yangtze River.jpg|Mlonga wa Yangtze
</gallery>
== Wonaniso ==
* [[Maji]]
* [[Nyanja]]
* [[Mlonga wa Amazon]]
* [[Mlonga wa Nile]]
* [[Chilengiwa]]
* [[Kukola somba]]
== Ukaboni ==
* [https://www.britannica.com/science/river River – Encyclopaedia Britannica]
* [https://www.usgs.gov/special-topics/water-science-school Water Science School – USGS]
* [https://www.unep.org/ United Nations Environment Programme]
[[Category:Milonga]]
[[Category:Maji]]
[[Category:Chilengiwa]]
[[Category:Geography]]
26st2906pr3eob5v6qe8y2od7bdiaoz
Category:Maji
14
50292
124150
2026-11-09T20:16:30Z
Tumbuka Arch
6863
Created blank page
124150
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Meteora
0
50293
124151
2026-11-09T20:16:47Z
Tumbuka Arch
6863
Created page with "{{Short description|Malo gha mapiri na nyumba zakusoperamo zakale mu Greece}} {{Infobox | name = Meteora | image = Meteora monasteries Greece.jpg | caption = Nyumba zakusoperamo pa mapiri gha Meteora | location = Thessaly, Greece | designation = Ukaboni wa pa Charu Chose | established = 1988 }} '''Meteora''' ni malo ghakumanyikwa chomene mu chigaŵa cha [[Thessaly]] mu charu cha [[Greece]]. Malo agha ghali na mapiri ghakuru gha malibwe agho ghakwera pachanya chomene. Pa..."
124151
wikitext
text/x-wiki
{{Short description|Malo gha mapiri na nyumba zakusoperamo zakale mu Greece}}
{{Infobox
| name = Meteora
| image = Meteora monasteries Greece.jpg
| caption = Nyumba zakusoperamo pa mapiri gha Meteora
| location = Thessaly, Greece
| designation = Ukaboni wa pa Charu Chose
| established = 1988
}}
'''Meteora''' ni malo ghakumanyikwa chomene mu chigaŵa cha [[Thessaly]] mu charu cha [[Greece]]. Malo agha ghali na mapiri ghakuru gha malibwe agho ghakwera pachanya chomene. Pachanya pa mapiri agha pali nyumba zakusoperamo zakale izo zikazengeka na ŵanthu ŵa chisopa cha Orthodox.
Zina lakuti Meteora likufuma ku mazgu gha Chigiriki agho ghakung'anamura vinthu ivyo vikuwoneka nga kuti vili mu mlengalenga.
== Mbiri ==
Ŵanthu awo ŵakakhumbanga kukhala paŵekha kuti ŵasopenge ŵakamba kukhala mu malo agha mu vyaka vya m'ma 1000. Pamanyuma, nyumba zakusoperamo zinandi zikazengeka pachanya pa mapiri agha.
Mu vyaka vya m'ma 1400 na 1500, malo agha ghakaŵa na nyumba zakusoperamo zinandi chomene.
== Nyumba zakusoperamo ==
Meteora yikaŵa na nyumba zakusoperamo 24. Mazuŵa ghano, zinyake mwa nyumba izi ndizo zikulutilira kugwira ntchito.
Zinyake mwa nyumba zakumanyikwa ni:
* Great Meteoron.
* Varlaam.
* Rousanou.
* Holy Trinity.
* St. Stephen.
* St. Nicholas Anapausas.
== Chilengiwa cha Meteora ==
Malo agha ghali na malibwe ghakuru gha mchenga agho ghakawumbika mu vyaka mamiliyoni vinandi ivyo vyajumpha. Maji, mphepo na kusunkhunyika kwa charu vikawovwira kusintha kawonekero ka mapiri agha.
== Ukaboni wa pa Charu Chose ==
Mu 1988, [[UNESCO]] likasazgirako Meteora pa Mndandanda wa Ukaboni wa pa Charu Chose. Malo agha ngakuzirwa chifukwa cha nyumba zakusoperamo, vinthu vya mbiri na kawonekero ka chilengiwa chake.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Meteora monasteries Greece.jpg|Nyumba zakusoperamo za Meteora
Meteora Greece landscape.jpg|Mapiri gha Meteora
Great Meteoron Monastery.jpg|Great Meteoron
Varlaam Monastery Meteora.jpg|Nyumba ya Varlaam
Holy Trinity Monastery Meteora.jpg|Nyumba ya Holy Trinity
</gallery>
== Wonaniso ==
* [[Greece]]
* [[Thessaly]]
* [[UNESCO]]
* [[Ukaboni wa pa Charu Chose]]
* [[Chilengiwa]]
== Ukaboni ==
* [https://whc.unesco.org/en/list/455/ UNESCO – Meteora]
* [https://www.britannica.com/place/Meteora Meteora – Encyclopaedia Britannica]
[[Category:Malo gha ku Greece]]
[[Category:Mbiri ya Greece]]
[[Category:Nyumba zakusoperamo]]
[[Category:Ukaboni wa pa Charu Chose]]
dp3la9fnppu89yq8xxfo1o29kng97no
Category:Nyumba zakusoperamo
14
50294
124152
2026-11-09T20:17:17Z
Tumbuka Arch
6863
Created blank page
124152
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Malo gha ku Greece
14
50295
124153
2026-11-09T20:17:21Z
Tumbuka Arch
6863
Created blank page
124153
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya Greece
14
50296
124154
2026-11-09T20:17:23Z
Tumbuka Arch
6863
Created blank page
124154
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Chilengiwa
0
50297
124155
2026-11-09T20:17:38Z
Tumbuka Arch
6863
Created page with "{{Short description|Vinthu vyose vyamoyo na vyambura umoyo ivyo vilipo pa charu}} {{Infobox | above = Chilengiwa | image = Earth seen from Apollo 17.jpg | caption = Charu chapasi chikuwoneka kufuma mu mlengalenga }} '''Chilengiwa''' ni vinthu vyose ivyo vilipo pa charu chapasi kwambura kupangika na munthu. Chilengiwa chikusazgapo vyamoyo na vinthu vyambura umoyo nga ni [[miti]], [[nyama]], [[maji]], [[malibwe]], [[mphepo]] na [[mapiri]]. Chilengiwa chikovwira kuti umoy..."
124155
wikitext
text/x-wiki
{{Short description|Vinthu vyose vyamoyo na vyambura umoyo ivyo vilipo pa charu}}
{{Infobox
| above = Chilengiwa
| image = Earth seen from Apollo 17.jpg
| caption = Charu chapasi chikuwoneka kufuma mu mlengalenga
}}
'''Chilengiwa''' ni vinthu vyose ivyo vilipo pa charu chapasi kwambura kupangika na munthu. Chilengiwa chikusazgapo vyamoyo na vinthu vyambura umoyo nga ni [[miti]], [[nyama]], [[maji]], [[malibwe]], [[mphepo]] na [[mapiri]].
Chilengiwa chikovwira kuti umoyo wa vyamoyo pa charu chapasi ulutilire. Ŵanthu, nyama na vyakumera vikukhala mu malo agho ghali mu chilengiwa.
== Vigaŵa vya chilengiwa ==
=== Vyamoyo ===
Vyamoyo ni vinthu ivyo vingaŵa na umoyo. Vikusazgapo:
* [[Ŵanthu]].
* [[Nyama]].
* [[Vyakumera]].
* [[Vibungu]].
* [[Mabakiteriya]].
* [[Bowa]].
=== Vinthu vyambura umoyo ===
Vinthu ivi vilije umoyo, kweni ni vyakuzirwa chomene pa umoyo wa vyamoyo. Vikusazgapo:
* [[Maji]].
* [[Mpweya]].
* [[Libwe]].
* [[Dongo]].
* [[Mazuŵa]].
* [[Mchenga]].
== Malo gha chilengiwa ==
Chilengiwa chili na malo ghakupambanapambana, nga ni:
* [[Nkhorongo]].
* [[Nyanja]].
* [[Milonga]].
* [[Mapiri]].
* [[Madambo]].
* [[Chipululu]].
Malo agha ghali na vyamoyo vyakupambanapambana ivyo vikukhala na kukulira mu malo ghawo.
== Kuzirwa kwa chilengiwa ==
Chilengiwa chili na ntchito zinandi pa umoyo wa charu. Mwachiyerezgero:
* Miti yikovwira kupanga mphepo iyo ŵanthu na nyama ŵakupema.
* Milonga na nyanja vikupereka maji.
* Dongo likovwira kuti vyakumera vikure.
* Nkhorongo zikupereka malo ghakukhala nyama.
* Vyamoyo vikovwira kuti vinthu mu chilengiwa vilutilire kwendera lumoza.
== Kusungilira chilengiwa ==
Kusungilira chilengiwa nkhwakuzirwa kuti vinthu vyamoyo vileke kumara. Ŵanthu ŵakukhumbikwira kuchepeska uheni uwo ukuchitikira nkhorongo, maji, dongo na malo ghanyake.
Nthowa zakusungilira chilengiwa ni:
* Kupanda miti.
* Kuchepeska kunanga nkhorongo.
* Kusunga maji ghakutowa.
* Kuvikilira nyama zakuthengere.
* Kuchepeska kunanga malo ghakukhala vyamoyo.
* Kugwiliskira ntchito vinthu mwamahara.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Earth seen from Apollo 17.jpg|Charu chapasi
Amazon rainforest.jpg|Nkhorongo
Victoria Falls aerial view.jpg|Chipopoma
Mount Kilimanjaro.jpg|Phiri
Great Barrier Reef.jpg|Vyamoyo mu nyanja
African savanna.jpg|Malo gha vyamoyo
</gallery>
== Wonaniso ==
* [[Sayansi ya chilengiwa]]
* [[Chilengiwa cha vyamoyo]]
* [[Nyengo]]
* [[Nkhorongo]]
* [[Maji]]
* [[Vyamoyo]]
== Ukaboni ==
* [https://www.britannica.com/science/nature Nature – Encyclopaedia Britannica]
* [https://www.unep.org/ United Nations Environment Programme]
* [https://www.worldwildlife.org/ World Wide Fund for Nature]
[[Category:Chilengiwa]]
[[Category:Sayansi ya chilengiwa]]
[[Category:Vyamoyo]]
[[Category:Charu chapasi]]
gvkgdm87fapa72gh5i4vqro6cfguobc
Category:Charu chapasi
14
50298
124156
2026-11-09T20:18:08Z
Tumbuka Arch
6863
Created blank page
124156
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Vyamoyo
14
50299
124157
2026-11-09T20:18:11Z
Tumbuka Arch
6863
Created blank page
124157
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Sayansi ya chilengiwa
14
50300
124158
2026-11-09T20:18:14Z
Tumbuka Arch
6863
Created blank page
124158
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Badaling
0
50301
124159
2026-11-09T20:18:47Z
Tumbuka Arch
6863
Created page with "{{Short description|Chigaŵa chakumanyikwa cha Chiliŵa chikulu cha China}} {{Infobox settlement | name = Badaling | image = Great Wall of China at Badaling.jpg | caption = Chiliŵa chikulu cha China ku Badaling | country = China | subdivision_type = Chigaŵa | subdivision_name = Beijing }} '''Badaling''' ni malo agho ghakusangika kumpoto kwa msumba wa [[Beijing]] mu charu cha [[China]]. Malo agha ngakumanyikwa chomene chifukwa cha kuŵa na chigaŵa chakuzirwa cha Chi..."
124159
wikitext
text/x-wiki
{{Short description|Chigaŵa chakumanyikwa cha Chiliŵa chikulu cha China}}
{{Infobox settlement
| name = Badaling
| image = Great Wall of China at Badaling.jpg
| caption = Chiliŵa chikulu cha China ku Badaling
| country = China
| subdivision_type = Chigaŵa
| subdivision_name = Beijing
}}
'''Badaling''' ni malo agho ghakusangika kumpoto kwa msumba wa [[Beijing]] mu charu cha [[China]]. Malo agha ngakumanyikwa chomene chifukwa cha kuŵa na chigaŵa chakuzirwa cha [[Chiliŵa chikulu cha China]].
Badaling ni malo agho ŵalendo ŵanandi ŵakutemwa kuluta kukawona chiliŵa chakale ichi.
== Mbiri ==
Chigaŵa cha Badaling cha Chiliŵa chikulu cha China chikazengeka chomene mu nyengo ya [[Mbumba ya Ming]]. Chiliŵa ichi chikagwiriskikanga ntchito nga ntchivikiliro cha kumpoto kwa China.
Pamanyuma, Badaling yikazgoka malo ghakuzirwa pa mbiri na ulendo wa ŵalendo.
== Malo agha ==
Badaling yili mu mapiri gha kumpoto kwa Beijing. Chiliŵa chikujumpha mu mapiri agha ndipo chili na nyumba zakale zakuwonera na vigaŵa vyakupambanapambana.
== Ulendo wa ŵalendo ==
Badaling ni limoza mwa malo agho ghakutemweka chomene na ŵalendo mu China. Ŵanthu ŵakufuma mu vyaru vinandi ŵakuluta kukawona kapangidwe ka chiliŵa ichi na malo ghake.
== Ukaboni wa pa Charu Chose ==
Badaling njimoza mwa vigaŵa vya [[Chiliŵa chikulu cha China]], icho chikazomerezgeka na [[UNESCO]] kuŵa malo gha Ukaboni wa pa Charu Chose mu 1987.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Great Wall of China at Badaling.jpg|Chiliŵa ku Badaling
Badaling Great Wall China.jpg|Chigaŵa cha Badaling
Great Wall of China watchtower.jpg|Nyumba yakuwonera
Great Wall of China panorama.jpg|Chiliŵa mu mapiri
</gallery>
== Wonaniso ==
* [[Chiliŵa chikulu cha China]]
* [[China]]
* [[Beijing]]
* [[UNESCO]]
== Ukaboni ==
* [https://whc.unesco.org/en/list/438/ UNESCO – The Great Wall]
* [https://whc.unesco.org/document/162535 UNESCO – The Great Wall (Badaling)]
[[Category:Malo gha ku China]]
[[Category:Mbiri ya China]]
[[Category:Ulendo wa ŵalendo]]
[[Category:Ukaboni wa pa Charu Chose]]
99poqp3ujedchhp6pv1alm6oy7bvbuc
Category:Malo gha ku China
14
50302
124160
2026-11-09T20:19:16Z
Tumbuka Arch
6863
Created blank page
124160
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Chiliŵa chikulu cha China
0
50303
124161
2026-11-09T20:19:38Z
Tumbuka Arch
6863
Created page with "{{Short description|Chiliŵa chakale cha ku China}} {{Infobox monument | name = Chiliŵa chikulu cha China | native_name = 万里长城 | image = Great Wall of China.jpg | caption = Chiliŵa chikulu cha China | location = China | type = Chiliŵa chakale | built = Kwambira mu vyaka vya m'ma 700 B.C. | length = Makilomita ghakujumpha 20,000 | designation = Ukaboni wa pa Charu Chose }} '''Chiliŵa chikulu cha China''' ni chiliŵa chakale chomene icho chili mu charu cha C..."
124161
wikitext
text/x-wiki
{{Short description|Chiliŵa chakale cha ku China}}
{{Infobox monument
| name = Chiliŵa chikulu cha China
| native_name = 万里长城
| image = Great Wall of China.jpg
| caption = Chiliŵa chikulu cha China
| location = China
| type = Chiliŵa chakale
| built = Kwambira mu vyaka vya m'ma 700 B.C.
| length = Makilomita ghakujumpha 20,000
| designation = Ukaboni wa pa Charu Chose
}}
'''Chiliŵa chikulu cha China''' ni chiliŵa chakale chomene icho chili mu charu cha [[China]]. Chiliŵa ichi chikujumpha mu mapiri, madambo na malo ghanyake gha kumpoto kwa China. Chikazengeka mu nyengo zakupambanapambana na mafumu gha China kuti chivikilire vigaŵa vya charu chawo.
Chiliŵa ichi ntchimoza mwa vyakuzenga vikuru chomene mu mbiri ya ŵanthu. Mu 1987, chikazomerezgeka na [[UNESCO]] kuŵa malo gha Ukaboni wa pa Charu Chose.
== Mbiri ==
Kuzenga vigaŵa vyakupambanapambana vya chiliŵa ichi kukamba kale chomene, apo maufumu gha ku China ghakazenganga viliŵa kuti ghavikilire malo ghawo.
Mu 221 B.C., Themba [[Qin Shi Huang]] likawunganiska vigaŵa vinandi vya viliŵa vyakale kuti viŵe chivikiliro chimoza.
Pamanyuma, mafumu ghanyake ghakalutilira kuzenga na kunozga chiliŵa ichi. Chikazengeka chomene mu nyengo ya [[Mbumba ya Ming]] (1368–1644).
== Kapangidwe ==
Chiliŵa ichi chili na:
* Viliŵa virefu.
* Nkhongono zakuvikilira.
* Vipata.
* Nyumba zakuwonera.
* Nthowa zakwendera ŵasilikari.
Chikazengeka na malibwe, njerwa, dongo na vinthu vinyake kuyana na malo.
== Malo gha Badaling ==
[[Badaling]] ni chigaŵa chakumanyikwa chomene cha Chiliŵa chikulu cha China. Chili kufupi na msumba wa Beijing ndipo ŵalendo ŵanandi ŵakiza kuzakachiwona.
== Ukaboni wa pa Charu Chose ==
Mu 1987, UNESCO likasazgirako Chiliŵa chikulu cha China pa Mndandanda wa Ukaboni wa pa Charu Chose chifukwa cha kuzirwa kwake pa mbiri, kapangidwe na mitheto ya China.
== Vithuzithuzi ==
<gallery mode="packed" heights="180">
Great Wall of China.jpg|Chiliŵa chikulu cha China
Great Wall of China at Jinshanling.jpg|Chigaŵa cha chiliŵa mu mapiri
Great Wall of China Mutianyu.jpg|Chiliŵa ku Mutianyu
Great Wall of China Badaling.jpg|Chiliŵa ku Badaling
Great Wall of China watchtower.jpg|Nyumba yakuwonera pa chiliŵa
</gallery>
== Wonaniso ==
* [[Badaling]]
* [[China]]
* [[Mbumba ya Ming]]
* [[UNESCO]]
* [[Ukaboni wa pa Charu Chose]]
== Ukaboni ==
* [https://whc.unesco.org/en/list/438/ UNESCO – The Great Wall]
* [https://www.britannica.com/topic/Great-Wall-of-China Encyclopaedia Britannica – Great Wall of China]
[[Category:Mbiri ya China]]
[[Category:Nyumba zakale]]
[[Category:Ukaboni wa pa Charu Chose]]
[[Category:UNESCO]]
hgyvygdvekz7a2my4kfoqsg0jfdskm1
UNESCO
0
50304
124162
2026-11-09T20:20:15Z
Tumbuka Arch
6863
Created page with "{{Short description|Gulu la vya masambiro, sayansi na mitheto la United Nations}} {{Infobox organization | name = UNESCO | full_name = United Nations Educational, Scientific and Cultural Organization | image = UNESCO flag.jpg | headquarters = Paris, France | formation = 16 Novembala 1945 | type = Gulu la United Nations | website = https://www.unesco.org/ }} '''UNESCO''' ni gulu la [[United Nations]] ilo likugwira ntchito pa nkhani za masambiro, sayansi, mitheto na kuvik..."
124162
wikitext
text/x-wiki
{{Short description|Gulu la vya masambiro, sayansi na mitheto la United Nations}}
{{Infobox organization
| name = UNESCO
| full_name = United Nations Educational, Scientific and Cultural Organization
| image = UNESCO flag.jpg
| headquarters = Paris, France
| formation = 16 Novembala 1945
| type = Gulu la United Nations
| website = https://www.unesco.org/
}}
'''UNESCO''' ni gulu la [[United Nations]] ilo likugwira ntchito pa nkhani za masambiro, sayansi, mitheto na kuvikilira vinthu vyakuzirwa vya charu. Zina lakuti UNESCO likufuma ku mazgu gha Chingelezi ghakuti ''United Nations Educational, Scientific and Cultural Organization''.
Gulu ili likakhazikiskika pa 16 Novembala 1945 ndipo likulu lake lili mu msumba wa [[Paris]], mu charu cha [[France]].
== Mbiri ==
UNESCO likakhazikiskika pamanyuma pa [[Nkhondo Yachiŵiri ya pa Charu Chose]]. Chilato chake chikaŵa chakuti vyaru vigwiliranenge ntchito kuti viŵe na mtende kwizira mu masambiro, sayansi na mitheto.
Gulu ili likamba kugwira ntchito mu 1946. Likugwira ntchito na maboma gha vyaru vyakupambanapambana kweniso mabungwe ghanyake gha pa charu chose.
== Milimo ya UNESCO ==
UNESCO likugwira ntchito mu vigaŵa vinandi:
=== Masambiro ===
UNESCO likovwira kusazgirako mwaŵi wa masambiro ku ŵanthu wose. Likukhozga masambiro ghapachanya, masambiro gha ŵana na kusambizga ŵanthu ŵalara.
=== Sayansi ===
Gulu ili likukhozga kafukufuku wa sayansi, kusungilira maji, na kupwelelera [[chilengiwa]].
=== Mitheto ===
UNESCO likovwira kusungilira malo gha mbiri, nyumba zakale, viŵiya, viyowoyero na mitheto ya ŵanthu.
=== Ukaboni wa pa charu chose ===
UNESCO likusunga ndondomeko ya malo agho ghali pa Mndandanda wa Ukaboni wa pa Charu Chose.
== Malo gha Ukaboni wa pa Charu Chose ==
Mu 1972, UNESCO likazomerezga Phangano la Ukaboni wa pa Charu Chose. Phangano ili likovwira kuvikilira malo agho ghali na kuzirwa kukuru pa mbiri, mitheto panji chilengiwa cha charu chose.
Malo agha ghakusazgapo:
* [[Chiliŵa chikulu cha China]].
* [[Meteora]] mu Greece.
* [[Malo gha chilengiwa gha Galápagos]] mu Ecuador.
* [[Taj Mahal]] mu India.
* [[Mapiri gha Kilimanjaro]] mu Tanzania.
== Ukulu wa gulu ili ==
UNESCO likovwira kuti ŵanthu ŵa mu vyaru vyakupambanapambana ŵasungilire mbiri na vinthu vyawo vyakuzirwa. Likukhozga kuti masambiro na sayansi viŵe vyakovwira ku ŵanthu wose.
== Wonaniso ==
* [[United Nations]]
* [[Ukaboni wa pa Charu Chose]]
* [[Masambiro]]
* [[Sayansi]]
* [[Mitheto]]
== Ukaboni ==
* [https://www.unesco.org/en UNESCO – Webusayiti ya boma]
* [https://www.unesco.org/en/about-us UNESCO – About us]
* [https://whc.unesco.org/en/list/ UNESCO World Heritage List]
[[Category:UNESCO]]
[[Category:Mabungwe gha pa charu chose]]
[[Category:United Nations]]
[[Category:Mitheto]]
[[Category:Masambiro]]
j223traz2f0ag8xg3n2w972d5yy55c4
Template:Infobox monument
10
50305
124163
2026-09-30T01:27:36Z
en>Zackmann08
0
No longer a valid parameter
124163
wikitext
text/x-wiki
<includeonly>{{main other|{{#ifeq:{{#invoke:Is infobox in lead|main|[Ii]nfobox [Mm]onument}}|true|{{#if:{{{location|}}}|{{str ≤ len |{{{location|}}}|60|{{Short description|Monument in {{Plain text|{{{location|}}}}}|noreplace}}}}}}}}}}
{{Infobox
| bodyclass = vcard
| titleclass = fn org
| title = {{If empty|{{{name|}}}|{{PAGENAMEBASE}}}}
| subheader = {{#if:{{{native_name|}}}|<div class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{native_name}}}</div>}}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{image_size|}}}|sizedefault=frameless|alt={{{alt|}}}}}
| caption = {{{caption|}}}
| image2 = {{#invoke:Location map|infobox_pushpin_map}}
| image3 = {{#invoke:Infobox mapframe
| autoWithCaption
| onByDefault = {{#if:{{{pushpin_map|}}}|no|yes}}
| mapframe-type = landmark
| mapframe-marker = monument
| mapframe-frame-width = 250
| mapframe-caption = Interactive map of {{If empty|{{{name|}}}|{{PAGENAMEBASE}}}}
}}
| label1 = Location
| data1 = {{{location|}}}
| class1 = label
| label2 = Coordinates
| data2 = {{#if:{{{coordinates|}}}|{{#invoke:Coordinates|coordinsert|{{{coordinates|}}}|type:{{if empty|{{{geohack-type|}}}|landmark}}|<!--
-->{{#if:{{{area_km2|}}}{{{area_sqmi|}}}{{{area_acre|}}}{{{area_ha|}}}<!--
-->{{{length_km|}}}{{{length_mi|}}}{{{width_km|}}}{{{width_mi|}}}|<!---
-->dim:{{Infobox dim|length_km={{{length_km|}}}|length_mi={{{length_mi|}}}|<!--
-->width_km={{{width_km|}}}|width_mi={{{width_mi|}}}|<!--
-->area_km2={{{area_km2|}}}|area_mi2={{{area_sqmi|}}}|<!--
-->area_ha={{{area_ha|}}}|area_acre={{{area_acre|}}} }} }}<!--
-->}}{{{coords_ref|}}}|}}
| label3 = Designer
| data3 = {{{designer|}}}
| label4 = Fabricator
| data4 = {{{fabricator|}}}
| label5 = Builder
| data5 = {{{builder|}}}
| label6 = Type
| data6 = {{{type|}}}
| label7 = Material
| data7 = {{{material|}}}
| label8 = Length
| data8 = {{{length|}}}
| label9 = Width
| data9 = {{{width|}}}
| label10 = Height
| data10 = {{{height|}}}
| label11 = Weight
| data11 = {{{weight|}}}
| label12 = Visitors
| data12 = {{#if:{{{visitors_num|}}}|{{{visitors_num|}}}{{#if:{{{visitors_year|}}}| (in {{{visitors_year}}})}}}}
| label13 = Beginning date
| data13 = {{{begin|}}}
| label14 = Completion date
| data14 = {{{complete|}}}
| label15 = Opening date
| data15 = {{{open|}}}
| label16 = Dedicated date
| data16 = {{{dedicated|}}}
| label17 = Inauguration date
| data17 = {{{inaugurated|}}}
| label18 = Restored date
| data18 = {{{restore|}}}
| label19 = Dedicated to
| data19 = {{{dedicated_to|}}}
| label20 = Dismantled date
| data20 = {{{dismantled|}}}
| label21 = Website
| data21 = {{{website|}}}
| label22 = {{{extra_label|}}}
| data22 = {{{extra|}}}
| label23 = Remarks
| data23 = {{{remarks|}}}
| header23 = {{{module|}}}
}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using infobox monument with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Infobox monument]] with unknown parameter "_VALUE_"|ignoreblank=y|mapframe_args=y|pushpin_map_args=y| alt | area_acre | area_ha | area_km2 | area_sqmi | begin | builder | caption | complete | coordinates | coords_ref | dedicated | dedicated_to | designer | dismantled | extra | extra_label | fabricator | geohack-type | height | image | image_size | inaugurated | length | length_km | length_mi | location | material | module | name | native_name | native_name_lang | open | remarks | restore | type | visitors_num | visitors_year | website | weight | width | width_km | width_mi }}<noinclude>
{{Documentation}}
<!-- PLEASE ADD CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS. -->
</noinclude>
e43idpjzaymyvu2dpvxva7csfqopv2w
124164
124163
2026-11-09T20:20:36Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_monument]]
124163
wikitext
text/x-wiki
<includeonly>{{main other|{{#ifeq:{{#invoke:Is infobox in lead|main|[Ii]nfobox [Mm]onument}}|true|{{#if:{{{location|}}}|{{str ≤ len |{{{location|}}}|60|{{Short description|Monument in {{Plain text|{{{location|}}}}}|noreplace}}}}}}}}}}
{{Infobox
| bodyclass = vcard
| titleclass = fn org
| title = {{If empty|{{{name|}}}|{{PAGENAMEBASE}}}}
| subheader = {{#if:{{{native_name|}}}|<div class="nickname" {{#if:{{{native_name_lang|}}}|lang="{{{native_name_lang}}}"}}>{{{native_name}}}</div>}}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{image_size|}}}|sizedefault=frameless|alt={{{alt|}}}}}
| caption = {{{caption|}}}
| image2 = {{#invoke:Location map|infobox_pushpin_map}}
| image3 = {{#invoke:Infobox mapframe
| autoWithCaption
| onByDefault = {{#if:{{{pushpin_map|}}}|no|yes}}
| mapframe-type = landmark
| mapframe-marker = monument
| mapframe-frame-width = 250
| mapframe-caption = Interactive map of {{If empty|{{{name|}}}|{{PAGENAMEBASE}}}}
}}
| label1 = Location
| data1 = {{{location|}}}
| class1 = label
| label2 = Coordinates
| data2 = {{#if:{{{coordinates|}}}|{{#invoke:Coordinates|coordinsert|{{{coordinates|}}}|type:{{if empty|{{{geohack-type|}}}|landmark}}|<!--
-->{{#if:{{{area_km2|}}}{{{area_sqmi|}}}{{{area_acre|}}}{{{area_ha|}}}<!--
-->{{{length_km|}}}{{{length_mi|}}}{{{width_km|}}}{{{width_mi|}}}|<!---
-->dim:{{Infobox dim|length_km={{{length_km|}}}|length_mi={{{length_mi|}}}|<!--
-->width_km={{{width_km|}}}|width_mi={{{width_mi|}}}|<!--
-->area_km2={{{area_km2|}}}|area_mi2={{{area_sqmi|}}}|<!--
-->area_ha={{{area_ha|}}}|area_acre={{{area_acre|}}} }} }}<!--
-->}}{{{coords_ref|}}}|}}
| label3 = Designer
| data3 = {{{designer|}}}
| label4 = Fabricator
| data4 = {{{fabricator|}}}
| label5 = Builder
| data5 = {{{builder|}}}
| label6 = Type
| data6 = {{{type|}}}
| label7 = Material
| data7 = {{{material|}}}
| label8 = Length
| data8 = {{{length|}}}
| label9 = Width
| data9 = {{{width|}}}
| label10 = Height
| data10 = {{{height|}}}
| label11 = Weight
| data11 = {{{weight|}}}
| label12 = Visitors
| data12 = {{#if:{{{visitors_num|}}}|{{{visitors_num|}}}{{#if:{{{visitors_year|}}}| (in {{{visitors_year}}})}}}}
| label13 = Beginning date
| data13 = {{{begin|}}}
| label14 = Completion date
| data14 = {{{complete|}}}
| label15 = Opening date
| data15 = {{{open|}}}
| label16 = Dedicated date
| data16 = {{{dedicated|}}}
| label17 = Inauguration date
| data17 = {{{inaugurated|}}}
| label18 = Restored date
| data18 = {{{restore|}}}
| label19 = Dedicated to
| data19 = {{{dedicated_to|}}}
| label20 = Dismantled date
| data20 = {{{dismantled|}}}
| label21 = Website
| data21 = {{{website|}}}
| label22 = {{{extra_label|}}}
| data22 = {{{extra|}}}
| label23 = Remarks
| data23 = {{{remarks|}}}
| header23 = {{{module|}}}
}}</includeonly>{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using infobox monument with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Infobox monument]] with unknown parameter "_VALUE_"|ignoreblank=y|mapframe_args=y|pushpin_map_args=y| alt | area_acre | area_ha | area_km2 | area_sqmi | begin | builder | caption | complete | coordinates | coords_ref | dedicated | dedicated_to | designer | dismantled | extra | extra_label | fabricator | geohack-type | height | image | image_size | inaugurated | length | length_km | length_mi | location | material | module | name | native_name | native_name_lang | open | remarks | restore | type | visitors_num | visitors_year | website | weight | width | width_km | width_mi }}<noinclude>
{{Documentation}}
<!-- PLEASE ADD CATEGORIES AND INTERWIKIS TO THE /doc SUBPAGE, THANKS. -->
</noinclude>
e43idpjzaymyvu2dpvxva7csfqopv2w
Module:Location map/data/India Gujarat
828
50306
124197
2021-08-03T12:14:42Z
en>Paine Ellsworth
0
per edit request on talk page - update coordinates
124197
Scribunto
text/plain
return {
name = 'Gujarat',
top = 24.82,
bottom = 19.9500,
left = 68.0000,
right = 74.62,
image = 'India Gujarat location map.svg',
image1 = 'Gujarat relief map.svg'
}
o6ebwjh7rlfjsqgwydtmrs127p9q6s9
124198
124197
2026-11-09T20:20:42Z
Tumbuka Arch
6863
1 revision imported from [[:en:Module:Location_map/data/India_Gujarat]]
124197
Scribunto
text/plain
return {
name = 'Gujarat',
top = 24.82,
bottom = 19.9500,
left = 68.0000,
right = 74.62,
image = 'India Gujarat location map.svg',
image1 = 'Gujarat relief map.svg'
}
o6ebwjh7rlfjsqgwydtmrs127p9q6s9
Template:Infobox monument/doc
10
50307
124207
2026-07-28T22:22:40Z
en>Pburka
0
/* Usage */ rm. duplicate param
124207
wikitext
text/x-wiki
{{Documentation subpage}}
{{High-use}}
{{Auto short description}}
<!-- Please place categories where indicated at the bottom of this page and interwikis at Wikidata (see [[Wikipedia:Wikidata]]) -->
{{Lua|Module:Infobox|Module:InfoboxImage|Module:Location map|Module:Coordinates|Module:Check for unknown parameters}}
== Usage ==
Copy and paste the template below:
{{Parameter names example|name|native_name|native_name_lang|image|image_size|alt|caption
| pushpin_map = Africa
| pushpin_relief
| pushpin_alt
| pushpin_label_position
| pushpin_caption
| pushpin_map_size
| mapframe = yes<!-- See [[#Mapframe maps]] for more information. -->
| coordinates={{coord|12|34}}
| location|designer|type|material|length|width|height|visitors_num|visitors_year|begin|complete|open|restore|dismantled|dedicated_to|website|extra_label|extra|weight}}
<syntaxhighlight lang="wikitext" style="overflow: auto;">{{Infobox monument
| name =
| native_name =
| image =
| image_size =
| caption =
| location =
| designer =
| type =
| material =
| length =
| width =
| height =
| weight =
| visitors_num =
| visitors_year =
| begin =
| complete =
| dedicated =
| open =
| restore =
| dismantled =
| dedicated_to =
| pushpin_map =
| pushpin_relief =
| pushpin_alt =
| pushpin_label_position =
| pushpin_caption =
| pushpin_map_size =
| mapframe = yes<!-- See [[#Mapframe maps]] for more information. -->
| coordinates =
| website =
| extra_label =
| extra =
}}</syntaxhighlight>
==Parameter descriptions==
* {{Para|name}} – Name of monument
* {{Para|native_name}} – Native name of monument
* {{Para|image}} – Filename of monument's image
* {{Para|caption}} – Text for caption beneath image
* {{Para|coordinates}} – Latitude and longitude. Use the {{tl|coord}} template.
: i.e. <nowiki>{{coord|50|01|01|N|90|01|01|W|region:US_type:landmark|display=inline,title}}</nowiki>
* {{Para|location}} – Area where located (San Francisco, Indiana-Kentucky State Line)
* {{Para|designer}} – Monument designer (Isambard Kingdom Brunel)
* {{Para|type}} – Type of monument ([[obelisk]], [[megalithic]], [[tomb]], [[mausoleum]], [[tumulus]], [[victory column]], [[triumphal arch]])
* {{Para|material}} – Construction material (concrete, steel, iron, stone, brick, wood)
* {{Para|length}} – Length of monument, w/ conversions
* {{Para|width}} – Width of monument, w/ conversions
* {{Para|height}} – Height of monument, w/ conversions
* {{Para|weight}} – Weight of monument, w/ conversions
* {{Para|visitors_num}} – Most recent number of visitors to the monument in a given year. If a specific year is not known, average annual number of visitors can be used
* {{Para|visitors_year}} – If a specific year was used for {{Para|visitors_num}}, the year goes here
* {{Para|begin}} – Beginning date of construction
* {{Para|complete}} – Completion date
* {{Para|open}} – Opening date
* {{Para|restore}} – Restoration date
* {{Para|dedicated_to}} – Dedicated to
* {{Para|pushpin_map}} – Name of monument's location map
* {{Para|pushpin_caption}} – Caption of monument's map image
* {{Para|pushpin_map_size}} – Map width in a standard value (pixels, for example) without the "px" suffix
* {{Para|pushpin_relief}} – Displays a physical location map (if available), instead of the default blank administrative location map
* {{para|mapframe}} – Displays an {{tl|Infobox mapframe}}. See [[#Mapframe maps]] for more information.
* {{Para|website}} – Official website
* {{Para|extra}} – Spare field for additional information
* {{Para|extra_label}} – Label/description for value in {{Para|extra}}
===Mapframe maps===
{{Infobox mapframe/doc/parameters
| onByDefault = yes, unless {{para|pushpin_map}} is set
| mapframe-type = landmark
| mapframe-marker = monument
| mapframe-frame-width = 250
}}
=== Pushpin map ===
{{Location map/doc/infobox parameters}}
== Tracking categories ==
{{Infobox tracking cats}}
==TemplateData==
{{collapse top|[[Wikipedia:TemplateData|TemplateData]] documentation used by [[Wikipedia:VisualEditor|VisualEditor]] and other tools}}
{{TemplateData header|noheader=1}}
<templatedata>
{
"params": {
"name": {
"type": "string"
},
"native_name": {
"description": "Native name of monument",
"type": "string"
},
"native_name_lang": {
"description": "The language that the native name is in",
"type": "string"
},
"image": {
"description": "Filename of monument's image",
"type": "wiki-file-name"
},
"image_size": {},
"alt": {},
"caption": {},
"coordinates": {
"description": "Latitude and longitude. Use the {{coord}} template.",
"example": "{{coord|50|01|01|N|90|01|01|W|region:US_type:landmark|display=inline,title}}",
"type": "unknown"
},
"pushpin_map": {},
"pushpin_relief": {},
"pushpin_alt": {},
"pushpin_label_position": {},
"pushpin_caption": {},
"pushpin_map_size": {},
"mapframe": {
"label": "Show mapframe map",
"description": "Specify yes or no to show or hide the map, overriding the default",
"example": "yes",
"type": "string",
"default": "no",
"suggested": true
},
"mapframe-caption": {
"label": "Mapframe caption",
"description": "Caption for the map. If mapframe-geomask is set, then the default is \"Location in <<geomask's label>>\"",
"type": "string"
},
"mapframe-custom": {
"label": "Custom mapframe",
"description": "Use a custom map instead of the automatic mapframe. Specify either a {{maplink}} template, or another template that generates a mapframe map, or an image name. If used, other mapframe parameters will be ignored.",
"type": "wiki-template-name"
},
"mapframe-id": {
"aliases": [
"id",
"qid"
],
"label": "Mapframe Wikidata item",
"description": "Id (Q-number) of Wikidata item to use.",
"type": "string",
"default": "(item for current page)"
},
"mapframe-coordinates": {
"aliases": [
"mapframe-coord",
"coordinates",
"coord"
],
"label": "Mapframe coordinates ",
"description": "Coordinates to use, instead of any on Wikidata. Use the {{Coord}} template.",
"example": "{{Coord|12.34|N|56.78|E}}",
"type": "wiki-template-name",
"default": "(coordinates from Wikidata)"
},
"mapframe-wikidata": {
"label": "Mapframe shapes from Wikidata",
"description": "et to yes to show shape/line features from the wikidata item, if any, when coordinates are specified by parameter",
"example": "yes",
"type": "string"
},
"mapframe-shape": {
"label": "Mapframe shape feature",
"description": "Override display of mapframe shape feature. Turn off by setting to \"none\". Use an inverse shape (geomask) instead of a regular shape by setting to \"inverse\"",
"type": "string"
},
"mapframe-point": {
"label": "Mapframe point feature",
"description": "Override display of mapframe point feature. Turn off display of point feature by setting to \"none\". Force point marker to be displayed by setting to \"on\"",
"type": "string"
},
"mapframe-geomask": {
"label": "Mapframe geomask",
"description": "Wikidata item to use as a geomask (everything outside the boundary is shaded darker). Can either be a specific Wikidata item (Q-number), or a property that specifies the item to use (e.g. P17 for country, or P131 for located in the administrative territorial entity)",
"example": "Q100",
"type": "wiki-page-name"
},
"mapframe-switcher": {
"label": "Mapframe switcher",
"description": "Set to \"auto\" or \"geomasks\" or \"zooms\" to enable Template:Switcher-style switching between multiple mapframes. IF SET TO auto – switch geomasks found in location (P276) and located in the administrative territorial entity (P131) statements on the page's Wikidata item, searching recursively. E.g. an item's city, that city's state, and that state's country. IF SET TO geomasks – switch between the geomasks specified as a comma-separated list of Wikidata items (Q-numbers) in the mapframe-geomask parameter. IF SET TO zooms – switch between \"zoomed in\"/\"zoomed midway\"/\"zoomed out\", where \"zoomed in\" is the default zoom (with a minimum of 3), \"zoomed out\" is 1, and \"zoomed midway\" is the average.",
"type": "string"
},
"mapframe-frame-width": {
"aliases": [
"mapframe-width"
],
"label": "Mapframe width",
"description": "Frame width in pixels",
"type": "number",
"default": "270"
},
"mapframe-frame-height": {
"aliases": [
"mapframe-height"
],
"label": "Mapframe height",
"description": "Frame height in pixels",
"type": "number",
"default": "200"
},
"mapframe-shape-fill": {
"label": "Mapframe shape fill",
"description": "Color used to fill shape features",
"type": "string",
"default": "#606060"
},
"mapframe-shape-fill-opacity": {
"label": "Mapframe shape fill opacity",
"description": "Opacity level of shape fill, a number between 0 and 1",
"type": "number",
"default": "0.5"
},
"mapframe-stroke-color": {
"aliases": [
"mapframe-stroke-colour"
],
"label": "Mapframe stroke color",
"description": "Color of line features, and outlines of shape features",
"type": "string",
"default": "#ff0000"
},
"mapframe-stroke-width": {
"label": "Mapframe stroke width",
"description": "Width of line features, and outlines of shape features",
"type": "number",
"default": "5"
},
"mapframe-marker": {
"label": "Mapframe marker",
"description": "Marker symbol to use for coordinates; see [[mw:Help:Extension:Kartographer/Icons]] for options",
"example": "museum",
"type": "string"
},
"mapframe-marker-color": {
"aliases": [
"mapframe-marker-colour"
],
"label": "Mapframe marker color",
"description": "Background color for the marker",
"type": "string",
"default": "#5E74F3"
},
"mapframe-geomask-stroke-color": {
"aliases": [
"mapframe-geomask-stroke-colour"
],
"label": "Mapframe geomask stroke color",
"description": "Color of outline of geomask shape",
"type": "string",
"default": "#555555"
},
"mapframe-geomask-stroke-width": {
"label": "Mapframe geomask stroke width",
"description": "Width of outline of geomask shape",
"type": "number",
"default": "2"
},
"mapframe-geomask-fill": {
"label": "Mapframe geomask fill",
"description": "Color used to fill outside geomask features",
"type": "string",
"default": "#606060"
},
"mapframe-geomask-fill-opacity": {
"label": "Mapframe geomask fill opacity",
"description": "Opacity level of fill outside geomask features, a number between 0 and 1",
"type": "number",
"default": "0.5"
},
"mapframe-zoom": {
"label": "Mapframe zoom",
"description": "Set the zoom level, from \"1\" to \"18\", to used if the zoom level cannot be determined automatically from object length or area",
"example": "12",
"type": "number",
"default": "10"
},
"mapframe-length_km": {
"label": "Mapframe length (km)",
"description": "Object length in kilometres, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-length_mi": {
"label": "Mapframe length (mi)",
"description": "Object length in miles, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-area_km2": {
"label": "Mapframe area (km^2)",
"description": "Object arean square kilometres, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-area_mi2": {
"label": "Mapframe area (mi^2)",
"description": "Object area in square miles, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-frame-coordinates": {
"aliases": [
"mapframe-frame-coord"
],
"label": "Mapframe frame coordinates",
"description": "Alternate latitude and longitude coordinates for initial placement of map, using {{coord}}",
"example": "{{Coord|12.35|N|56.71|E}}",
"type": "wiki-template-name"
},
"mapframe-line": {},
"mapframe-type": {
"label": "Mapframe type",
"description": "Type of the object rendered in the mapframe, like with {{coord}}.",
"type": "string"
},
"location": {},
"designer": {},
"fabricator": {},
"builder": {},
"type": {},
"material": {},
"length": {},
"width": {},
"height": {},
"weight": {},
"visitors_num": {
"description": "Most recent number of visitors to the monument in a given year. If a specific year is not known, average annual number of visitors can be used"
},
"visitors_year": {
"description": "If a specific year was used for visitors_num, the year goes here"
},
"begin": {
"description": "The date the monument's construction began"
},
"complete": {
"description": "The date the monument's construction finished"
},
"open": {
"description": "The date the monument opened"
},
"dedicated": {
"description": "The date the monument was dedicated"
},
"inaugurated": {
"description": "The date the monument was inaugurated"
},
"restore": {
"description": "Restoration date"
},
"dedicated_to": {
"description": "The people or group that the monument is dedicated to",
"type": "string"
},
"dismantled": {},
"website": {},
"extra_label": {},
"extra": {},
"module": {}
}
}
</templatedata>
==Examples==
{{Infobox monument
| name = ''Statue of Unity''
| image = Statue_of_Unity.jpg
| location = Narmada Valley [[Kevadiya, Narmada, Gujarat]], India
| designer = [[Ram V. Sutar]]
| type = [[Statue]]
| material = Steel framing, reinforced by concrete and brass coating, [[bronze]] cladding<ref name="ibn">{{cite news|url=http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|title=Gujarat: Sardar Patel statue to be twice the size of Statue of Liberty|date=30 October 2013|access-date=30 October 2013|archive-url=https://web.archive.org/web/20131031222804/http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|archive-date=31 October 2013|url-status=live|publisher=CNN-IBN}}</ref>
| length =
| width =
| height = {{convert|182|meter|ft}}
| visitors_num = 2.8 million<ref>{{Cite web|url=https://timesofindia.indiatimes.com/city/ahmedabad/in-11-months-sou-got-26-lakh-visitors/articleshow/71712391.cms|title=In 11 months, Statue of Unity got 2.6 million visitors Ahmedabad News - Times of India|last=Dave|first=Kapil|date=23 October 2019|website=The Times of India|language=en|access-date=22 January 2020}}</ref>
| visitors_year = 2018-19
| begin = {{start date|df=y|2013|10|31}}
| complete = 30 October 2018
| open = 31 October 2018
| dedicated_to = [[Vallabhbhai Patel]]
| mapframe = yes
| pushpin_map = India Gujarat#India
| pushpin_caption = Location of the ''Statue of Unity'' in Gujarat
| coordinates = {{coord|21.8380|73.7191|type:landmark_region:IN-GJ|display=it}}
| website = {{URL|https://statueofunity.in}}
| image_size = 250px
}}
<syntaxhighlight lang="moin" style="overflow:auto;">
{{Infobox monument
| name = ''Statue of Unity''
| image = Statue_of_Unity.jpg
| location = Narmada Valley [[Kevadiya, Narmada, Gujarat]], India
| designer = [[Ram V. Sutar]]
| type = [[Statue]]
| material = Steel framing, reinforced by concrete and brass coating, [[bronze]] cladding<ref name="ibn">{{cite news|url=http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|title=Gujarat: Sardar Patel statue to be twice the size of Statue of Liberty|date=30 October 2013|access-date=30 October 2013|archive-url=https://web.archive.org/web/20131031222804/http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|archive-date=31 October 2013|url-status=live|publisher=CNN-IBN}}</ref>
| length =
| width =
| height = {{convert|182|meter|ft}}
| visitors_num = 2.8 million<ref>{{Cite web|url=https://timesofindia.indiatimes.com/city/ahmedabad/in-11-months-sou-got-26-lakh-visitors/articleshow/71712391.cms|title=In 11 months, Statue of Unity got 2.6 million visitors Ahmedabad News - Times of India|last=Dave|first=Kapil|date=23 October 2019|website=The Times of India|language=en|access-date=22 January 2020}}</ref>
| visitors_year = 2018-19
| begin = {{start date|df=y|2013|10|31}}
| complete = 30 October 2018
| open = 31 October 2018
| dedicated_to = [[Vallabhbhai Patel]]
| mapframe = yes
| pushpin_map = India Gujarat#India
| map caption = Location of the ''Statue of Unity'' in Gujarat
| coordinates = {{coord|21.8380|73.7191|type:landmark_region:IN-GJ|display=it}}
| website = {{URL|https://statueofunity.in}}
| image_size = 250px
}}
</syntaxhighlight>
{{cob}}
== See also ==
* {{t|Infobox building}}
* {{t|Infobox ancient site}}
{{Buildings and structures infobox templates}}
<includeonly>{{Sandbox other||
<!-- Categories below this line, please; interwikis at Wikidata -->
==References==
{{Reflist}}
[[Category:Buildings and structures infobox templates|Monument]]
[[Category:Infobox templates with module parameter|Monument]]
[[Category:Templates generating hCards]]
[[Category:Templates that add a tracking category]]
}}</includeonly>
qz5myzbvvubqz8utc37a0dlxnanck9b
124208
124207
2026-11-09T20:20:43Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_monument/doc]]
124207
wikitext
text/x-wiki
{{Documentation subpage}}
{{High-use}}
{{Auto short description}}
<!-- Please place categories where indicated at the bottom of this page and interwikis at Wikidata (see [[Wikipedia:Wikidata]]) -->
{{Lua|Module:Infobox|Module:InfoboxImage|Module:Location map|Module:Coordinates|Module:Check for unknown parameters}}
== Usage ==
Copy and paste the template below:
{{Parameter names example|name|native_name|native_name_lang|image|image_size|alt|caption
| pushpin_map = Africa
| pushpin_relief
| pushpin_alt
| pushpin_label_position
| pushpin_caption
| pushpin_map_size
| mapframe = yes<!-- See [[#Mapframe maps]] for more information. -->
| coordinates={{coord|12|34}}
| location|designer|type|material|length|width|height|visitors_num|visitors_year|begin|complete|open|restore|dismantled|dedicated_to|website|extra_label|extra|weight}}
<syntaxhighlight lang="wikitext" style="overflow: auto;">{{Infobox monument
| name =
| native_name =
| image =
| image_size =
| caption =
| location =
| designer =
| type =
| material =
| length =
| width =
| height =
| weight =
| visitors_num =
| visitors_year =
| begin =
| complete =
| dedicated =
| open =
| restore =
| dismantled =
| dedicated_to =
| pushpin_map =
| pushpin_relief =
| pushpin_alt =
| pushpin_label_position =
| pushpin_caption =
| pushpin_map_size =
| mapframe = yes<!-- See [[#Mapframe maps]] for more information. -->
| coordinates =
| website =
| extra_label =
| extra =
}}</syntaxhighlight>
==Parameter descriptions==
* {{Para|name}} – Name of monument
* {{Para|native_name}} – Native name of monument
* {{Para|image}} – Filename of monument's image
* {{Para|caption}} – Text for caption beneath image
* {{Para|coordinates}} – Latitude and longitude. Use the {{tl|coord}} template.
: i.e. <nowiki>{{coord|50|01|01|N|90|01|01|W|region:US_type:landmark|display=inline,title}}</nowiki>
* {{Para|location}} – Area where located (San Francisco, Indiana-Kentucky State Line)
* {{Para|designer}} – Monument designer (Isambard Kingdom Brunel)
* {{Para|type}} – Type of monument ([[obelisk]], [[megalithic]], [[tomb]], [[mausoleum]], [[tumulus]], [[victory column]], [[triumphal arch]])
* {{Para|material}} – Construction material (concrete, steel, iron, stone, brick, wood)
* {{Para|length}} – Length of monument, w/ conversions
* {{Para|width}} – Width of monument, w/ conversions
* {{Para|height}} – Height of monument, w/ conversions
* {{Para|weight}} – Weight of monument, w/ conversions
* {{Para|visitors_num}} – Most recent number of visitors to the monument in a given year. If a specific year is not known, average annual number of visitors can be used
* {{Para|visitors_year}} – If a specific year was used for {{Para|visitors_num}}, the year goes here
* {{Para|begin}} – Beginning date of construction
* {{Para|complete}} – Completion date
* {{Para|open}} – Opening date
* {{Para|restore}} – Restoration date
* {{Para|dedicated_to}} – Dedicated to
* {{Para|pushpin_map}} – Name of monument's location map
* {{Para|pushpin_caption}} – Caption of monument's map image
* {{Para|pushpin_map_size}} – Map width in a standard value (pixels, for example) without the "px" suffix
* {{Para|pushpin_relief}} – Displays a physical location map (if available), instead of the default blank administrative location map
* {{para|mapframe}} – Displays an {{tl|Infobox mapframe}}. See [[#Mapframe maps]] for more information.
* {{Para|website}} – Official website
* {{Para|extra}} – Spare field for additional information
* {{Para|extra_label}} – Label/description for value in {{Para|extra}}
===Mapframe maps===
{{Infobox mapframe/doc/parameters
| onByDefault = yes, unless {{para|pushpin_map}} is set
| mapframe-type = landmark
| mapframe-marker = monument
| mapframe-frame-width = 250
}}
=== Pushpin map ===
{{Location map/doc/infobox parameters}}
== Tracking categories ==
{{Infobox tracking cats}}
==TemplateData==
{{collapse top|[[Wikipedia:TemplateData|TemplateData]] documentation used by [[Wikipedia:VisualEditor|VisualEditor]] and other tools}}
{{TemplateData header|noheader=1}}
<templatedata>
{
"params": {
"name": {
"type": "string"
},
"native_name": {
"description": "Native name of monument",
"type": "string"
},
"native_name_lang": {
"description": "The language that the native name is in",
"type": "string"
},
"image": {
"description": "Filename of monument's image",
"type": "wiki-file-name"
},
"image_size": {},
"alt": {},
"caption": {},
"coordinates": {
"description": "Latitude and longitude. Use the {{coord}} template.",
"example": "{{coord|50|01|01|N|90|01|01|W|region:US_type:landmark|display=inline,title}}",
"type": "unknown"
},
"pushpin_map": {},
"pushpin_relief": {},
"pushpin_alt": {},
"pushpin_label_position": {},
"pushpin_caption": {},
"pushpin_map_size": {},
"mapframe": {
"label": "Show mapframe map",
"description": "Specify yes or no to show or hide the map, overriding the default",
"example": "yes",
"type": "string",
"default": "no",
"suggested": true
},
"mapframe-caption": {
"label": "Mapframe caption",
"description": "Caption for the map. If mapframe-geomask is set, then the default is \"Location in <<geomask's label>>\"",
"type": "string"
},
"mapframe-custom": {
"label": "Custom mapframe",
"description": "Use a custom map instead of the automatic mapframe. Specify either a {{maplink}} template, or another template that generates a mapframe map, or an image name. If used, other mapframe parameters will be ignored.",
"type": "wiki-template-name"
},
"mapframe-id": {
"aliases": [
"id",
"qid"
],
"label": "Mapframe Wikidata item",
"description": "Id (Q-number) of Wikidata item to use.",
"type": "string",
"default": "(item for current page)"
},
"mapframe-coordinates": {
"aliases": [
"mapframe-coord",
"coordinates",
"coord"
],
"label": "Mapframe coordinates ",
"description": "Coordinates to use, instead of any on Wikidata. Use the {{Coord}} template.",
"example": "{{Coord|12.34|N|56.78|E}}",
"type": "wiki-template-name",
"default": "(coordinates from Wikidata)"
},
"mapframe-wikidata": {
"label": "Mapframe shapes from Wikidata",
"description": "et to yes to show shape/line features from the wikidata item, if any, when coordinates are specified by parameter",
"example": "yes",
"type": "string"
},
"mapframe-shape": {
"label": "Mapframe shape feature",
"description": "Override display of mapframe shape feature. Turn off by setting to \"none\". Use an inverse shape (geomask) instead of a regular shape by setting to \"inverse\"",
"type": "string"
},
"mapframe-point": {
"label": "Mapframe point feature",
"description": "Override display of mapframe point feature. Turn off display of point feature by setting to \"none\". Force point marker to be displayed by setting to \"on\"",
"type": "string"
},
"mapframe-geomask": {
"label": "Mapframe geomask",
"description": "Wikidata item to use as a geomask (everything outside the boundary is shaded darker). Can either be a specific Wikidata item (Q-number), or a property that specifies the item to use (e.g. P17 for country, or P131 for located in the administrative territorial entity)",
"example": "Q100",
"type": "wiki-page-name"
},
"mapframe-switcher": {
"label": "Mapframe switcher",
"description": "Set to \"auto\" or \"geomasks\" or \"zooms\" to enable Template:Switcher-style switching between multiple mapframes. IF SET TO auto – switch geomasks found in location (P276) and located in the administrative territorial entity (P131) statements on the page's Wikidata item, searching recursively. E.g. an item's city, that city's state, and that state's country. IF SET TO geomasks – switch between the geomasks specified as a comma-separated list of Wikidata items (Q-numbers) in the mapframe-geomask parameter. IF SET TO zooms – switch between \"zoomed in\"/\"zoomed midway\"/\"zoomed out\", where \"zoomed in\" is the default zoom (with a minimum of 3), \"zoomed out\" is 1, and \"zoomed midway\" is the average.",
"type": "string"
},
"mapframe-frame-width": {
"aliases": [
"mapframe-width"
],
"label": "Mapframe width",
"description": "Frame width in pixels",
"type": "number",
"default": "270"
},
"mapframe-frame-height": {
"aliases": [
"mapframe-height"
],
"label": "Mapframe height",
"description": "Frame height in pixels",
"type": "number",
"default": "200"
},
"mapframe-shape-fill": {
"label": "Mapframe shape fill",
"description": "Color used to fill shape features",
"type": "string",
"default": "#606060"
},
"mapframe-shape-fill-opacity": {
"label": "Mapframe shape fill opacity",
"description": "Opacity level of shape fill, a number between 0 and 1",
"type": "number",
"default": "0.5"
},
"mapframe-stroke-color": {
"aliases": [
"mapframe-stroke-colour"
],
"label": "Mapframe stroke color",
"description": "Color of line features, and outlines of shape features",
"type": "string",
"default": "#ff0000"
},
"mapframe-stroke-width": {
"label": "Mapframe stroke width",
"description": "Width of line features, and outlines of shape features",
"type": "number",
"default": "5"
},
"mapframe-marker": {
"label": "Mapframe marker",
"description": "Marker symbol to use for coordinates; see [[mw:Help:Extension:Kartographer/Icons]] for options",
"example": "museum",
"type": "string"
},
"mapframe-marker-color": {
"aliases": [
"mapframe-marker-colour"
],
"label": "Mapframe marker color",
"description": "Background color for the marker",
"type": "string",
"default": "#5E74F3"
},
"mapframe-geomask-stroke-color": {
"aliases": [
"mapframe-geomask-stroke-colour"
],
"label": "Mapframe geomask stroke color",
"description": "Color of outline of geomask shape",
"type": "string",
"default": "#555555"
},
"mapframe-geomask-stroke-width": {
"label": "Mapframe geomask stroke width",
"description": "Width of outline of geomask shape",
"type": "number",
"default": "2"
},
"mapframe-geomask-fill": {
"label": "Mapframe geomask fill",
"description": "Color used to fill outside geomask features",
"type": "string",
"default": "#606060"
},
"mapframe-geomask-fill-opacity": {
"label": "Mapframe geomask fill opacity",
"description": "Opacity level of fill outside geomask features, a number between 0 and 1",
"type": "number",
"default": "0.5"
},
"mapframe-zoom": {
"label": "Mapframe zoom",
"description": "Set the zoom level, from \"1\" to \"18\", to used if the zoom level cannot be determined automatically from object length or area",
"example": "12",
"type": "number",
"default": "10"
},
"mapframe-length_km": {
"label": "Mapframe length (km)",
"description": "Object length in kilometres, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-length_mi": {
"label": "Mapframe length (mi)",
"description": "Object length in miles, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-area_km2": {
"label": "Mapframe area (km^2)",
"description": "Object arean square kilometres, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-area_mi2": {
"label": "Mapframe area (mi^2)",
"description": "Object area in square miles, for automatically determining zoom level. ONLY use ONE of the available parameters for length or area",
"type": "number"
},
"mapframe-frame-coordinates": {
"aliases": [
"mapframe-frame-coord"
],
"label": "Mapframe frame coordinates",
"description": "Alternate latitude and longitude coordinates for initial placement of map, using {{coord}}",
"example": "{{Coord|12.35|N|56.71|E}}",
"type": "wiki-template-name"
},
"mapframe-line": {},
"mapframe-type": {
"label": "Mapframe type",
"description": "Type of the object rendered in the mapframe, like with {{coord}}.",
"type": "string"
},
"location": {},
"designer": {},
"fabricator": {},
"builder": {},
"type": {},
"material": {},
"length": {},
"width": {},
"height": {},
"weight": {},
"visitors_num": {
"description": "Most recent number of visitors to the monument in a given year. If a specific year is not known, average annual number of visitors can be used"
},
"visitors_year": {
"description": "If a specific year was used for visitors_num, the year goes here"
},
"begin": {
"description": "The date the monument's construction began"
},
"complete": {
"description": "The date the monument's construction finished"
},
"open": {
"description": "The date the monument opened"
},
"dedicated": {
"description": "The date the monument was dedicated"
},
"inaugurated": {
"description": "The date the monument was inaugurated"
},
"restore": {
"description": "Restoration date"
},
"dedicated_to": {
"description": "The people or group that the monument is dedicated to",
"type": "string"
},
"dismantled": {},
"website": {},
"extra_label": {},
"extra": {},
"module": {}
}
}
</templatedata>
==Examples==
{{Infobox monument
| name = ''Statue of Unity''
| image = Statue_of_Unity.jpg
| location = Narmada Valley [[Kevadiya, Narmada, Gujarat]], India
| designer = [[Ram V. Sutar]]
| type = [[Statue]]
| material = Steel framing, reinforced by concrete and brass coating, [[bronze]] cladding<ref name="ibn">{{cite news|url=http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|title=Gujarat: Sardar Patel statue to be twice the size of Statue of Liberty|date=30 October 2013|access-date=30 October 2013|archive-url=https://web.archive.org/web/20131031222804/http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|archive-date=31 October 2013|url-status=live|publisher=CNN-IBN}}</ref>
| length =
| width =
| height = {{convert|182|meter|ft}}
| visitors_num = 2.8 million<ref>{{Cite web|url=https://timesofindia.indiatimes.com/city/ahmedabad/in-11-months-sou-got-26-lakh-visitors/articleshow/71712391.cms|title=In 11 months, Statue of Unity got 2.6 million visitors Ahmedabad News - Times of India|last=Dave|first=Kapil|date=23 October 2019|website=The Times of India|language=en|access-date=22 January 2020}}</ref>
| visitors_year = 2018-19
| begin = {{start date|df=y|2013|10|31}}
| complete = 30 October 2018
| open = 31 October 2018
| dedicated_to = [[Vallabhbhai Patel]]
| mapframe = yes
| pushpin_map = India Gujarat#India
| pushpin_caption = Location of the ''Statue of Unity'' in Gujarat
| coordinates = {{coord|21.8380|73.7191|type:landmark_region:IN-GJ|display=it}}
| website = {{URL|https://statueofunity.in}}
| image_size = 250px
}}
<syntaxhighlight lang="moin" style="overflow:auto;">
{{Infobox monument
| name = ''Statue of Unity''
| image = Statue_of_Unity.jpg
| location = Narmada Valley [[Kevadiya, Narmada, Gujarat]], India
| designer = [[Ram V. Sutar]]
| type = [[Statue]]
| material = Steel framing, reinforced by concrete and brass coating, [[bronze]] cladding<ref name="ibn">{{cite news|url=http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|title=Gujarat: Sardar Patel statue to be twice the size of Statue of Liberty|date=30 October 2013|access-date=30 October 2013|archive-url=https://web.archive.org/web/20131031222804/http://m.ibnlive.com/news/gujarat-sardar-patel-statue-to-be-twice-the-size-of-statue-of-liberty/431317-3-238.html|archive-date=31 October 2013|url-status=live|publisher=CNN-IBN}}</ref>
| length =
| width =
| height = {{convert|182|meter|ft}}
| visitors_num = 2.8 million<ref>{{Cite web|url=https://timesofindia.indiatimes.com/city/ahmedabad/in-11-months-sou-got-26-lakh-visitors/articleshow/71712391.cms|title=In 11 months, Statue of Unity got 2.6 million visitors Ahmedabad News - Times of India|last=Dave|first=Kapil|date=23 October 2019|website=The Times of India|language=en|access-date=22 January 2020}}</ref>
| visitors_year = 2018-19
| begin = {{start date|df=y|2013|10|31}}
| complete = 30 October 2018
| open = 31 October 2018
| dedicated_to = [[Vallabhbhai Patel]]
| mapframe = yes
| pushpin_map = India Gujarat#India
| map caption = Location of the ''Statue of Unity'' in Gujarat
| coordinates = {{coord|21.8380|73.7191|type:landmark_region:IN-GJ|display=it}}
| website = {{URL|https://statueofunity.in}}
| image_size = 250px
}}
</syntaxhighlight>
{{cob}}
== See also ==
* {{t|Infobox building}}
* {{t|Infobox ancient site}}
{{Buildings and structures infobox templates}}
<includeonly>{{Sandbox other||
<!-- Categories below this line, please; interwikis at Wikidata -->
==References==
{{Reflist}}
[[Category:Buildings and structures infobox templates|Monument]]
[[Category:Infobox templates with module parameter|Monument]]
[[Category:Templates generating hCards]]
[[Category:Templates that add a tracking category]]
}}</includeonly>
qz5myzbvvubqz8utc37a0dlxnanck9b
Template talk:Infobox monument
11
50308
124211
2026-07-01T17:05:03Z
en>Zackmann08
0
/* Pushpin map cleanup */ new section
124211
wikitext
text/x-wiki
{{Old AfD multi |date1=15 April 2013 |result1='''Keep''' |link1={{canonicalurl:Wikipedia:Templates for discussion/Log/2013 April 15#Template:Infobox_monument}} |date2=2018 April 13 |result2='''Keep''' |link2={{canonicalurl:Wikipedia:Templates for discussion/Log/2018 April 13#Template:Infobox_monument}} |date3=2020 March 22 |result3='''Do not merge''' |link3={{canonicalurl:Wikipedia:Templates for discussion/Log/2020 March 22#Template:Ancient monuments in Rome}} |date4=2020 March 22 |result4='''No consensus''' |link4={{canonicalurl:Wikipedia:Templates for discussion/Log/2020 March 22#Template:Infobox military memorial}}}}
{{WikiProject banner shell|
{{WikiProject Historic sites}}
}}
== Merge/replace with {{tl|Infobox historic site}} ==
I started a conversation at [[Template talk:Infobox historic site#.7B.7BInfobox_monument.7D.7D]] about the two templates and looking forward for some feedback on a possible merge. Thanks --[[User:Codrinb|Codrin.B]] ([[User talk:Codrinb|talk]]) 22:04, 21 February 2012 (UTC)
: An [[Wikipedia:Templates for discussion/Log/2013 April 15#Template:Infobox monument|April 2013 discussion]] decided to keep the templates separate, I think this stems from the confusion of monument-meaning-memorial and monument in the "Wiki Loves Monuments", monumental-building, sense. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:12, 15 January 2014 (UTC)
== Recent rewrite: feature lost ==
This infobox has recently been rewritten, and several parameters are no longer recognised: {{para|map_cue}} {{para|map_text}} {{para|map_width}} {{para|lat}} {{para|long}} {{para|coord_region}}. Regarding the last three, these were used to generate a {{tlx|coord}} with {{para|display|inline,title}}, and that feature has been lost. --[[User:Redrose64|<span style="color:#a80000; background:#ffeeee; text-decoration:inherit">Red</span>rose64]] ([[User talk:Redrose64|talk]]) 17:06, 9 September 2012 (UTC)
:I've just seen {{diff|Template:Infobox monument|521544980|511557963|these two edits}}, which have added support for separate coordinate parameters {{para|latitude}}{{para|latd}}{{para|latm}}{{para|lats}}{{para|latNS}}{{para|longitude}}{{para|longd}}{{para|longm}}{{para|longs}}{{para|longEW}}{{para|iso_region}}. My immediate thought was "surely this was already present" - and indeed something very similar ''was'', but was lost with {{diff|Template:Infobox monument|prev|511534992|this edit}} as described above. We may therefore have articles using parameters which are no longer supported. Should we restore the old parameters to the infobox, or hunt down and fix the articles using these parameters? --[[User:Redrose64|<span style="color:#a80000; background:#ffeeee; text-decoration:inherit">Red</span>rose64]] ([[User talk:Redrose64|talk]]) 19:57, 5 November 2012 (UTC)
:: we could do both. I noticed this was in the documentation, but missing in the template, and didn't really have the time to update the articles. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 20:00, 5 November 2012 (UTC)
::: I added backwards compatibility for everything mentioned but {{para|map_cue}} {{para|map_text}}. will add tracking for those. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 20:05, 5 November 2012 (UTC)
:::: I cleared the tracking template transclusions and removed the tracking code. Thanks! [[User:Plastikspork|Plastikspork]] [[User talk:Plastikspork|<sub style="font-size: 60%">―Œ</sub><sup style="margin-left:-3ex">(talk)</sup>]] 23:16, 27 April 2013 (UTC)
== Native Name ==
Good morning, I have a question about the meaning of this parameter: is native name
a) the name of the landmark given by the people who built it or
b) the current name in the language spoken today in that place?
Example: the native name of "Colosseum" is a) Colosseum (Latin) or b) Colosseo (Italian)?
Thanks, [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 08:49, 15 January 2014 (UTC)
: Very good question. For the naming of monuments erected in the ancient era, we need maybe an additional parameter as "original name" so that the parameter "native name" may point out to the name in current language and time. If agreed, I can add that parameter. --[[User talk:CeeGee|CeeGee]] 11:32, 15 January 2014 (UTC)
:: Hallo CeeGee, nice to see you here :-) This is the question which I asked you one week ago. I looked to a dozen templates, and by them the native name is today's name. Example: Galata tower, Gaklata Kulesi, NOT Torre di Cristo. For me, you can proceed and insert it. Should we ask someone else? Bye, [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 12:31, 15 January 2014 (UTC)
:You could enter both names, using {{tl|Plainlist}}, but there is no need to enter the former, as it is the same as the current, English name; so just enter the Italian. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 13:42, 15 January 2014 (UTC)
::Thanks, but this was only a simple example: I came here because of Hagia Sophia, where the original name is Ἁγία Σοφία (the greek version) and the current name is Ayasofia müzesi (Turkish). I would like to have a parameter added, otherwise there will always be lenghty discussions about which name comes first, which second, and so on (Hagia Sophia is here a typical example).[[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:01, 15 January 2014 (UTC)
::: Hi [[User:Alessandro57|Alex]]! It seems that I didn't understand your earlier question. Anyway, I'm gonna add that par now with proper description. Hopefully, it will help. Cheers. --[[User talk:CeeGee|CeeGee]] 13:56, 15 January 2014 (UTC)
::::Hallo [[User:CeeGee|CeeGee]], you understood very well (see my post above), and go ahead! [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:01, 15 January 2014 (UTC)
:::::P.S. Anyway, [[User:CeeGee|CeeGee]], we have a problem: how will the user distinguish the original name from the current one? [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:04, 15 January 2014 (UTC)
:::See my example, below. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:16, 15 January 2014 (UTC)
{{od}}
Dual values may be entered using markup like:
<pre><code><nowiki>
{{Plainlist|
* {{lang|gr|Ἁγία Σοφία}}
* {{lang|tr|Ayasofia müzesi}}
}}
</nowiki></code></pre>
in which case, the {{Para|native_name_lang}} parameter is not used. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:16, 15 January 2014 (UTC)
:::Hallo [[User:Pigsonthewing|Andy]], thanks, but it is exactly the problem: Turkish and Greek Users fights again and again to put their name above the other. Moreover, with the list one does not understand which is the native name. What we should have is a fixed order with parameters, which avoids this kind of fights and brings clarity. [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:25, 15 January 2014 (UTC)
:::: {{done}} Pls, check if it's OK. --[[User talk:CeeGee|CeeGee]] 14:19, 15 January 2014 (UTC)
:::::Thanks [[User talk:CeeGee|CeeGee]], but how do we distinguish what is what? :-) [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:28, 15 January 2014 (UTC)
:::::: The only way is to relocate the par original_name by taking it off the title and place it into the infobox body with parameter-title "Original name". Do you mean this would help? --[[User talk:CeeGee|CeeGee]] 14:48, 15 January 2014 (UTC)
:::::I'm reverting; this needs more though discussion. Also, what of there are English and non-English versions of an original name, different to the current name(s)? How are those cases handled in comparable infoboxes, such as those for buildings or settlements? <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 15:02, 15 January 2014 (UTC)
::::I think you're over-thinking this. Firstly, we don't need to add template parameters just to avoid a local content dispute. Secondly, a non-English original name ''is'' a native name. (It might help to replace "native name" in your mind with "non-Englsh name".) <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 15:14, 15 January 2014 (UTC)
::::: All this happens maybe due to lack of clear-cut rules for use of original (ancient)-name and (native (current)-names and their order in the infobox title as well as in the lead section. I'm not aware of them. It could be helpful, I guess. --[[User talk:CeeGee|CeeGee]] 15:19, 15 January 2014 (UTC)
::::::I welcome an extended discussion here. Andy, [[User:Pigsonthewing|Andy Mabbett]], about your explaination of native names: does this mean that if a monument like Hagia Sophia changed hands 3 times in its history, it will have 3 native names? This infobox is almost never used so, since as native name is almost always adopted the current local name, i.e. the name used in the country hosting the landmark now. Moreover, in the specialistic literature is often given relevance to the current local name. IMHO, what we need to do is to distinguish among the original name, which is one, the current name, which is - except for multilingual entitities like Belgium - one, and the other names used during the landmark history. [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 15:33, 15 January 2014 (UTC)
== No parameter "monument dismantled"; I need one! ==
Currently there is no parameter in this template where an editor can put the date of dismantling, destruction or removal of a monument. I think one is needed. As you might know the [[Statue of Lenin in Kharkiv]] and [[Vladimir Lenin monument, Kiev]] and [[Decommunization in Ukraine#Results|hundreds of other communist monuments in Ukraine have also been dismantled]]. There are also former Stalin monuments and monuments to other dictators that have been dismantled. I think an extra parameter to indicate this would be a good extra feature for this template. I don't know how to add it.... — '''[[User:Yulia Romero|<span style="font-family:Script MT;color:orange">Yulia Romero</span>]]''' • [[User_talk:Yulia Romero|<span style="font-family:Script MT;color:blue">Talk to me!</span>]] 21:30, 11 April 2016 (UTC)
: [[User:Yulia Romero]], using {{para|dismantled}} should work now. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 22:31, 8 May 2016 (UTC)
==New parameter "Restored" ==
I added the Restore parameter as many monuments, especially really old ones, under restorations every, perhaps, 50 years or so. With my limited scripting knowledge, I hope it works! Thx. [[User:Mercy11|Mercy11]] ([[User talk:Mercy11|talk]]) 02:48, 20 January 2017 (UTC)
OK. So, it seems to work fine (tested it [http://en.wikipedia.org/wiki/Monumento_a_la_abolici%C3%B3n_de_la_esclavitud HERE]) except there is too much space before and after the new parameter, and which I can't figure out why. Thx! [[User:Mercy11|Mercy11]] ([[User talk:Mercy11|talk]]) 02:57, 20 January 2017 (UTC)
== Location parameter listed twice ==
The location parameter is listed twice: at the top under caption and way at the bottom. And if only the top one is filled in, it is ignored; no alert message given, just no location shown in the infobox. Can someone fix the duplication? Thanks, [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 19:37, 30 January 2017 (UTC)
: [[User:Leschnei|Leschnei]], can you provide an example? I am not seeing any errors. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 19:21, 27 February 2017 (UTC)
:: [[User:Frietjes|Frietjes]], I'm not sure which article(s) I was editing when I noticed this, so I copy/pasted the infobox monument template into a sandbox and copied some data from [[Pilgrim Monument]]. I put the location information into the first instance of 'location' in the infobox and left the second one blank. As you can see (here: [[User:Sandbox]]), the location does not show up in the resulting infobox. I hope that this isn't just a weirdness of my computer! [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 19:47, 27 February 2017 (UTC)
::: [[User:Leschnei|Leschnei]], I see. the problem was in the blank template in the documentation having the same parameter listed twice. I have fixed this. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 21:13, 27 February 2017 (UTC)
:::: [[User:Frietjes|Frietjes]], thank you! [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 21:28, 27 February 2017 (UTC)
== New Parameter needed ==
A parameter depicting the '''''tourist footfall (number of visiting tourists)''''' (yearly preferably) should be added to the infobox template.Number of tourists visiting is an important info about the monument.[[User:Sanyam.wikime|Sanyam.wikime]] ([[User talk:Sanyam.wikime|talk]]) 18:14, 22 December 2019 (UTC)
:I am adding the above mentioned parameter to the template as ''visitors_num'' and ''visitors_year'', view doc for more details. For any concern regarding the same, leave a message here. --[[User:Sanyam.wikime|Sanyam.wikime]] ([[User talk:Sanyam.wikime|talk]]) 14:15, 22 January 2020 (UTC)
== extra_label ==
The template supports an {{Para|extra}} parm for an ad-hoc value at the bottom, but there is no {{Para|extra_label}} field to label it. Any objection to my adding it? <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 22:29, 13 March 2020 (UTC)
:Seems reasonable. Plus side is that if it's not used the current view will show, so nothing existing will break. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 14:17, 15 March 2020 (UTC)
:: {{Done}} I added the {{Para|extra_label}} parm, documented it, and implemented it at [[Liberty Bell]]. <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 08:05, 16 March 2020 (UTC)
:::{{u|AlanM1}}, well done. I don't suppose it would be reasonably doable to make it appear where you put it in the specific template instead of only at the bottom? [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 08:56, 16 March 2020 (UTC)
::::Unfortunately that's not how templates work; we can only put info in the order it shows up. I do agree, it would make more sense to add it in further up the page (near the height etc) but that would require adding in a new param altogether. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 12:27, 16 March 2020 (UTC)
:::::Thanks, it was worth asking. An improvement, nontheless. [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 15:11, 16 March 2020 (UTC)
:::::: Is the template used a lot for things that have known/verifiable weight (mass)? I could add parms {{Para|weight}} with alias {{Para|mass}} below the {{Para|height}} if there is no objection. (Other templates have separate SI and imperial units parms and do conversions automatically, but this one doesn't do that for the other dimensions, so it should probably be consistent and let the user use a {{Tl|Convert}} if they want to.) <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 21:48, 18 March 2020 (UTC)
:::::::I randomly sampled about a half-dozen and they were mostly structures like [[Civil Rights Memorial]], [[Offa's Dyke]], and [[Hagia Sophia]], which don't really merit a weight param. I know that we're "allowed" to have params that aren't in use on every page, but if it's only going to be valid on a few pages it's not really worth it. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 13:14, 20 March 2020 (UTC)
{{Od}}
{{Re|Primefac|Gråbergs Gråa Sång}} A little [https://en.wikipedia.org/w/index.php?title=Special:Search&limit=250&offset=0&ns0=1&search=hastemplate%3A%22Infobox+monument%22+AND+insource%3A%2F%28weigh%5Bst%5D%3F%7Cmass+%29%2Fi&advancedSearch-current={} creative searching] (incomplete{{Snd}} I always forget the weird regex that Cirrus almost supports) suggests there would be sufficient use, I think. <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 17:24, 20 March 2020 (UTC)
:Fair enough. {{done}}. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 23:22, 20 March 2020 (UTC)
== New Parameter: Area? ==
Looking at [[NAMES Project AIDS Memorial Quilt]], I saw it was using Length as an ad-hoc area parameter because it can be made wider or narrower to fit a display area. There are also monuments like battlefields that have a large area that may not be cleanly rectangular that could use an area parameter. Could this parameter be added? [[Special:Contributions/~2026-22816-44|~2026-22816-44]] ([[User talk:~2026-22816-44|talk]]) 23:58, 8 June 2026 (UTC)
:Agreed, this would be great. I mistakenly switched length for area, not realizing I broke the template by doing so. I've moved the missing statistic into the body text for now, but it would be better to have it in the infobox. [[User:MercyStreet|MercyStreet]] ([[User talk:MercyStreet|talk]]) 03:56, 12 June 2026 (UTC)
== Pushpin map cleanup ==
As part of a larger refactor of [[Module:Location map]], I will be refactoring the way that this Infobox calls the location map code. The only noticeable change for most will be that the parameter names related to the pushpin maps will now all start with {{para|pushpin_...}}. This is part of a larger effort to make things consistent across Infoboxes. When this is done, ALL infoboxes using pushpin maps will use the same parameters. For more information about this, please see [[Module_talk:Location_map#Proposal_to_refactor_the_way_Template:Location_map_works_in_Infoboxes|this post]]. As part of this cleanup, I am also going to resolving any conflicting parameters that I can find and cleaning up parameter names that fail to conform to [[MOS:INFOBOXNAME]]. Note that this follows a long list of similar clean ups that I have done on countless other Infoboxes. The parameters I plan to replace are the following:
{| class="wikitable"
! Deprecate
! Replace with
|-
|{{para|image_alt}}
|{{para|alt}}
|-
|{{para|pushpin label position}}
|{{para|pushpin_label_position}}
|-
|{{para|pushpin map alt}}
|{{para|pushpin_alt}}
|-
|{{para|relief}}
|{{para|pushpin_relief}}
|-
|{{para|pushpin mapsize}}
|{{para|pushpin_map_size}}
|-
|{{para|embedded}}
|{{para|extra}}
|}
Please chime in below with any questions, comments or concerns about this cleanup. '''[[User:Zackmann08|<span style="color:#00d5ff !important">Zack</span><span style="color:#007F94 !important">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange !important">What I been doing</span>]]</sub>) 17:05, 1 July 2026 (UTC)
ggabqdhokh7irea0ytaanoydus1kivb
124212
124211
2026-11-09T20:20:44Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template_talk:Infobox_monument]]
124211
wikitext
text/x-wiki
{{Old AfD multi |date1=15 April 2013 |result1='''Keep''' |link1={{canonicalurl:Wikipedia:Templates for discussion/Log/2013 April 15#Template:Infobox_monument}} |date2=2018 April 13 |result2='''Keep''' |link2={{canonicalurl:Wikipedia:Templates for discussion/Log/2018 April 13#Template:Infobox_monument}} |date3=2020 March 22 |result3='''Do not merge''' |link3={{canonicalurl:Wikipedia:Templates for discussion/Log/2020 March 22#Template:Ancient monuments in Rome}} |date4=2020 March 22 |result4='''No consensus''' |link4={{canonicalurl:Wikipedia:Templates for discussion/Log/2020 March 22#Template:Infobox military memorial}}}}
{{WikiProject banner shell|
{{WikiProject Historic sites}}
}}
== Merge/replace with {{tl|Infobox historic site}} ==
I started a conversation at [[Template talk:Infobox historic site#.7B.7BInfobox_monument.7D.7D]] about the two templates and looking forward for some feedback on a possible merge. Thanks --[[User:Codrinb|Codrin.B]] ([[User talk:Codrinb|talk]]) 22:04, 21 February 2012 (UTC)
: An [[Wikipedia:Templates for discussion/Log/2013 April 15#Template:Infobox monument|April 2013 discussion]] decided to keep the templates separate, I think this stems from the confusion of monument-meaning-memorial and monument in the "Wiki Loves Monuments", monumental-building, sense. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:12, 15 January 2014 (UTC)
== Recent rewrite: feature lost ==
This infobox has recently been rewritten, and several parameters are no longer recognised: {{para|map_cue}} {{para|map_text}} {{para|map_width}} {{para|lat}} {{para|long}} {{para|coord_region}}. Regarding the last three, these were used to generate a {{tlx|coord}} with {{para|display|inline,title}}, and that feature has been lost. --[[User:Redrose64|<span style="color:#a80000; background:#ffeeee; text-decoration:inherit">Red</span>rose64]] ([[User talk:Redrose64|talk]]) 17:06, 9 September 2012 (UTC)
:I've just seen {{diff|Template:Infobox monument|521544980|511557963|these two edits}}, which have added support for separate coordinate parameters {{para|latitude}}{{para|latd}}{{para|latm}}{{para|lats}}{{para|latNS}}{{para|longitude}}{{para|longd}}{{para|longm}}{{para|longs}}{{para|longEW}}{{para|iso_region}}. My immediate thought was "surely this was already present" - and indeed something very similar ''was'', but was lost with {{diff|Template:Infobox monument|prev|511534992|this edit}} as described above. We may therefore have articles using parameters which are no longer supported. Should we restore the old parameters to the infobox, or hunt down and fix the articles using these parameters? --[[User:Redrose64|<span style="color:#a80000; background:#ffeeee; text-decoration:inherit">Red</span>rose64]] ([[User talk:Redrose64|talk]]) 19:57, 5 November 2012 (UTC)
:: we could do both. I noticed this was in the documentation, but missing in the template, and didn't really have the time to update the articles. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 20:00, 5 November 2012 (UTC)
::: I added backwards compatibility for everything mentioned but {{para|map_cue}} {{para|map_text}}. will add tracking for those. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 20:05, 5 November 2012 (UTC)
:::: I cleared the tracking template transclusions and removed the tracking code. Thanks! [[User:Plastikspork|Plastikspork]] [[User talk:Plastikspork|<sub style="font-size: 60%">―Œ</sub><sup style="margin-left:-3ex">(talk)</sup>]] 23:16, 27 April 2013 (UTC)
== Native Name ==
Good morning, I have a question about the meaning of this parameter: is native name
a) the name of the landmark given by the people who built it or
b) the current name in the language spoken today in that place?
Example: the native name of "Colosseum" is a) Colosseum (Latin) or b) Colosseo (Italian)?
Thanks, [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 08:49, 15 January 2014 (UTC)
: Very good question. For the naming of monuments erected in the ancient era, we need maybe an additional parameter as "original name" so that the parameter "native name" may point out to the name in current language and time. If agreed, I can add that parameter. --[[User talk:CeeGee|CeeGee]] 11:32, 15 January 2014 (UTC)
:: Hallo CeeGee, nice to see you here :-) This is the question which I asked you one week ago. I looked to a dozen templates, and by them the native name is today's name. Example: Galata tower, Gaklata Kulesi, NOT Torre di Cristo. For me, you can proceed and insert it. Should we ask someone else? Bye, [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 12:31, 15 January 2014 (UTC)
:You could enter both names, using {{tl|Plainlist}}, but there is no need to enter the former, as it is the same as the current, English name; so just enter the Italian. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 13:42, 15 January 2014 (UTC)
::Thanks, but this was only a simple example: I came here because of Hagia Sophia, where the original name is Ἁγία Σοφία (the greek version) and the current name is Ayasofia müzesi (Turkish). I would like to have a parameter added, otherwise there will always be lenghty discussions about which name comes first, which second, and so on (Hagia Sophia is here a typical example).[[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:01, 15 January 2014 (UTC)
::: Hi [[User:Alessandro57|Alex]]! It seems that I didn't understand your earlier question. Anyway, I'm gonna add that par now with proper description. Hopefully, it will help. Cheers. --[[User talk:CeeGee|CeeGee]] 13:56, 15 January 2014 (UTC)
::::Hallo [[User:CeeGee|CeeGee]], you understood very well (see my post above), and go ahead! [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:01, 15 January 2014 (UTC)
:::::P.S. Anyway, [[User:CeeGee|CeeGee]], we have a problem: how will the user distinguish the original name from the current one? [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:04, 15 January 2014 (UTC)
:::See my example, below. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:16, 15 January 2014 (UTC)
{{od}}
Dual values may be entered using markup like:
<pre><code><nowiki>
{{Plainlist|
* {{lang|gr|Ἁγία Σοφία}}
* {{lang|tr|Ayasofia müzesi}}
}}
</nowiki></code></pre>
in which case, the {{Para|native_name_lang}} parameter is not used. <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 14:16, 15 January 2014 (UTC)
:::Hallo [[User:Pigsonthewing|Andy]], thanks, but it is exactly the problem: Turkish and Greek Users fights again and again to put their name above the other. Moreover, with the list one does not understand which is the native name. What we should have is a fixed order with parameters, which avoids this kind of fights and brings clarity. [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:25, 15 January 2014 (UTC)
:::: {{done}} Pls, check if it's OK. --[[User talk:CeeGee|CeeGee]] 14:19, 15 January 2014 (UTC)
:::::Thanks [[User talk:CeeGee|CeeGee]], but how do we distinguish what is what? :-) [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 14:28, 15 January 2014 (UTC)
:::::: The only way is to relocate the par original_name by taking it off the title and place it into the infobox body with parameter-title "Original name". Do you mean this would help? --[[User talk:CeeGee|CeeGee]] 14:48, 15 January 2014 (UTC)
:::::I'm reverting; this needs more though discussion. Also, what of there are English and non-English versions of an original name, different to the current name(s)? How are those cases handled in comparable infoboxes, such as those for buildings or settlements? <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 15:02, 15 January 2014 (UTC)
::::I think you're over-thinking this. Firstly, we don't need to add template parameters just to avoid a local content dispute. Secondly, a non-English original name ''is'' a native name. (It might help to replace "native name" in your mind with "non-Englsh name".) <span class="vcard"><span class="fn">[[User:Pigsonthewing|Andy Mabbett]]</span> (<span class="nickname">Pigsonthewing</span>); [[User talk:Pigsonthewing|Talk to Andy]]; [[Special:Contributions/Pigsonthewing|Andy's edits]]</span> 15:14, 15 January 2014 (UTC)
::::: All this happens maybe due to lack of clear-cut rules for use of original (ancient)-name and (native (current)-names and their order in the infobox title as well as in the lead section. I'm not aware of them. It could be helpful, I guess. --[[User talk:CeeGee|CeeGee]] 15:19, 15 January 2014 (UTC)
::::::I welcome an extended discussion here. Andy, [[User:Pigsonthewing|Andy Mabbett]], about your explaination of native names: does this mean that if a monument like Hagia Sophia changed hands 3 times in its history, it will have 3 native names? This infobox is almost never used so, since as native name is almost always adopted the current local name, i.e. the name used in the country hosting the landmark now. Moreover, in the specialistic literature is often given relevance to the current local name. IMHO, what we need to do is to distinguish among the original name, which is one, the current name, which is - except for multilingual entitities like Belgium - one, and the other names used during the landmark history. [[User:Alessandro57|Alex2006]] ([[User talk:Alessandro57|talk]]) 15:33, 15 January 2014 (UTC)
== No parameter "monument dismantled"; I need one! ==
Currently there is no parameter in this template where an editor can put the date of dismantling, destruction or removal of a monument. I think one is needed. As you might know the [[Statue of Lenin in Kharkiv]] and [[Vladimir Lenin monument, Kiev]] and [[Decommunization in Ukraine#Results|hundreds of other communist monuments in Ukraine have also been dismantled]]. There are also former Stalin monuments and monuments to other dictators that have been dismantled. I think an extra parameter to indicate this would be a good extra feature for this template. I don't know how to add it.... — '''[[User:Yulia Romero|<span style="font-family:Script MT;color:orange">Yulia Romero</span>]]''' • [[User_talk:Yulia Romero|<span style="font-family:Script MT;color:blue">Talk to me!</span>]] 21:30, 11 April 2016 (UTC)
: [[User:Yulia Romero]], using {{para|dismantled}} should work now. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 22:31, 8 May 2016 (UTC)
==New parameter "Restored" ==
I added the Restore parameter as many monuments, especially really old ones, under restorations every, perhaps, 50 years or so. With my limited scripting knowledge, I hope it works! Thx. [[User:Mercy11|Mercy11]] ([[User talk:Mercy11|talk]]) 02:48, 20 January 2017 (UTC)
OK. So, it seems to work fine (tested it [http://en.wikipedia.org/wiki/Monumento_a_la_abolici%C3%B3n_de_la_esclavitud HERE]) except there is too much space before and after the new parameter, and which I can't figure out why. Thx! [[User:Mercy11|Mercy11]] ([[User talk:Mercy11|talk]]) 02:57, 20 January 2017 (UTC)
== Location parameter listed twice ==
The location parameter is listed twice: at the top under caption and way at the bottom. And if only the top one is filled in, it is ignored; no alert message given, just no location shown in the infobox. Can someone fix the duplication? Thanks, [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 19:37, 30 January 2017 (UTC)
: [[User:Leschnei|Leschnei]], can you provide an example? I am not seeing any errors. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 19:21, 27 February 2017 (UTC)
:: [[User:Frietjes|Frietjes]], I'm not sure which article(s) I was editing when I noticed this, so I copy/pasted the infobox monument template into a sandbox and copied some data from [[Pilgrim Monument]]. I put the location information into the first instance of 'location' in the infobox and left the second one blank. As you can see (here: [[User:Sandbox]]), the location does not show up in the resulting infobox. I hope that this isn't just a weirdness of my computer! [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 19:47, 27 February 2017 (UTC)
::: [[User:Leschnei|Leschnei]], I see. the problem was in the blank template in the documentation having the same parameter listed twice. I have fixed this. [[User:Frietjes|Frietjes]] ([[User talk:Frietjes|talk]]) 21:13, 27 February 2017 (UTC)
:::: [[User:Frietjes|Frietjes]], thank you! [[User:Leschnei|Leschnei]] ([[User talk:Leschnei|talk]]) 21:28, 27 February 2017 (UTC)
== New Parameter needed ==
A parameter depicting the '''''tourist footfall (number of visiting tourists)''''' (yearly preferably) should be added to the infobox template.Number of tourists visiting is an important info about the monument.[[User:Sanyam.wikime|Sanyam.wikime]] ([[User talk:Sanyam.wikime|talk]]) 18:14, 22 December 2019 (UTC)
:I am adding the above mentioned parameter to the template as ''visitors_num'' and ''visitors_year'', view doc for more details. For any concern regarding the same, leave a message here. --[[User:Sanyam.wikime|Sanyam.wikime]] ([[User talk:Sanyam.wikime|talk]]) 14:15, 22 January 2020 (UTC)
== extra_label ==
The template supports an {{Para|extra}} parm for an ad-hoc value at the bottom, but there is no {{Para|extra_label}} field to label it. Any objection to my adding it? <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 22:29, 13 March 2020 (UTC)
:Seems reasonable. Plus side is that if it's not used the current view will show, so nothing existing will break. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 14:17, 15 March 2020 (UTC)
:: {{Done}} I added the {{Para|extra_label}} parm, documented it, and implemented it at [[Liberty Bell]]. <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 08:05, 16 March 2020 (UTC)
:::{{u|AlanM1}}, well done. I don't suppose it would be reasonably doable to make it appear where you put it in the specific template instead of only at the bottom? [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 08:56, 16 March 2020 (UTC)
::::Unfortunately that's not how templates work; we can only put info in the order it shows up. I do agree, it would make more sense to add it in further up the page (near the height etc) but that would require adding in a new param altogether. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 12:27, 16 March 2020 (UTC)
:::::Thanks, it was worth asking. An improvement, nontheless. [[User:Gråbergs Gråa Sång|Gråbergs Gråa Sång]] ([[User talk:Gråbergs Gråa Sång|talk]]) 15:11, 16 March 2020 (UTC)
:::::: Is the template used a lot for things that have known/verifiable weight (mass)? I could add parms {{Para|weight}} with alias {{Para|mass}} below the {{Para|height}} if there is no objection. (Other templates have separate SI and imperial units parms and do conversions automatically, but this one doesn't do that for the other dimensions, so it should probably be consistent and let the user use a {{Tl|Convert}} if they want to.) <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 21:48, 18 March 2020 (UTC)
:::::::I randomly sampled about a half-dozen and they were mostly structures like [[Civil Rights Memorial]], [[Offa's Dyke]], and [[Hagia Sophia]], which don't really merit a weight param. I know that we're "allowed" to have params that aren't in use on every page, but if it's only going to be valid on a few pages it's not really worth it. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 13:14, 20 March 2020 (UTC)
{{Od}}
{{Re|Primefac|Gråbergs Gråa Sång}} A little [https://en.wikipedia.org/w/index.php?title=Special:Search&limit=250&offset=0&ns0=1&search=hastemplate%3A%22Infobox+monument%22+AND+insource%3A%2F%28weigh%5Bst%5D%3F%7Cmass+%29%2Fi&advancedSearch-current={} creative searching] (incomplete{{Snd}} I always forget the weird regex that Cirrus almost supports) suggests there would be sufficient use, I think. <span style="color:red">—[</span>[[User:AlanM1|<span style="font-variant:small-caps;color:green">Alan</span><span style="color:blue">M</span><span style="color:purple">1</span>]] ([[User talk:AlanM1|talk]])<span style="color:red">]—</span> 17:24, 20 March 2020 (UTC)
:Fair enough. {{done}}. [[User:Primefac|Primefac]] ([[User talk:Primefac|talk]]) 23:22, 20 March 2020 (UTC)
== New Parameter: Area? ==
Looking at [[NAMES Project AIDS Memorial Quilt]], I saw it was using Length as an ad-hoc area parameter because it can be made wider or narrower to fit a display area. There are also monuments like battlefields that have a large area that may not be cleanly rectangular that could use an area parameter. Could this parameter be added? [[Special:Contributions/~2026-22816-44|~2026-22816-44]] ([[User talk:~2026-22816-44|talk]]) 23:58, 8 June 2026 (UTC)
:Agreed, this would be great. I mistakenly switched length for area, not realizing I broke the template by doing so. I've moved the missing statistic into the body text for now, but it would be better to have it in the infobox. [[User:MercyStreet|MercyStreet]] ([[User talk:MercyStreet|talk]]) 03:56, 12 June 2026 (UTC)
== Pushpin map cleanup ==
As part of a larger refactor of [[Module:Location map]], I will be refactoring the way that this Infobox calls the location map code. The only noticeable change for most will be that the parameter names related to the pushpin maps will now all start with {{para|pushpin_...}}. This is part of a larger effort to make things consistent across Infoboxes. When this is done, ALL infoboxes using pushpin maps will use the same parameters. For more information about this, please see [[Module_talk:Location_map#Proposal_to_refactor_the_way_Template:Location_map_works_in_Infoboxes|this post]]. As part of this cleanup, I am also going to resolving any conflicting parameters that I can find and cleaning up parameter names that fail to conform to [[MOS:INFOBOXNAME]]. Note that this follows a long list of similar clean ups that I have done on countless other Infoboxes. The parameters I plan to replace are the following:
{| class="wikitable"
! Deprecate
! Replace with
|-
|{{para|image_alt}}
|{{para|alt}}
|-
|{{para|pushpin label position}}
|{{para|pushpin_label_position}}
|-
|{{para|pushpin map alt}}
|{{para|pushpin_alt}}
|-
|{{para|relief}}
|{{para|pushpin_relief}}
|-
|{{para|pushpin mapsize}}
|{{para|pushpin_map_size}}
|-
|{{para|embedded}}
|{{para|extra}}
|}
Please chime in below with any questions, comments or concerns about this cleanup. '''[[User:Zackmann08|<span style="color:#00d5ff !important">Zack</span><span style="color:#007F94 !important">mann</span>]]''' (<sup>[[User_talk:Zackmann08|Talk to me]]</sup>/<sub>[[Special:Contributions/Zackmann08|<span style="color:orange !important">What I been doing</span>]]</sub>) 17:05, 1 July 2026 (UTC)
ggabqdhokh7irea0ytaanoydus1kivb
Category:UNESCO
14
50309
124223
2026-11-09T20:21:36Z
Tumbuka Arch
6863
Created blank page
124223
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Nyumba zakale
14
50310
124224
2026-11-09T20:21:39Z
Tumbuka Arch
6863
Created blank page
124224
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Kukola somba
0
50311
124225
2026-11-09T20:22:00Z
Tumbuka Arch
6863
Created page with "{{Short description|Ntchito ya kusanga somba mu maji}} {{Infobox occupation | name = Kukola somba | image = Fishing in Malawi.jpg | caption = Ŵanthu ŵakukola somba | activity = Usodzi }} '''Kukola somba''' ni ntchito iyo ŵanthu ŵakuchita kuti ŵasange [[somba]] mu maji. Somba zingasangika mu [[nyanja]], mu [[mlonga]], mu madambo na mu maji ghanyake. Ŵanthu ŵakukola somba kuti ŵasange chakulya, ndalama panji kuti ŵaguliske ku ŵanthu ŵanyake. Kukola somba ni nt..."
124225
wikitext
text/x-wiki
{{Short description|Ntchito ya kusanga somba mu maji}}
{{Infobox occupation
| name = Kukola somba
| image = Fishing in Malawi.jpg
| caption = Ŵanthu ŵakukola somba
| activity = Usodzi
}}
'''Kukola somba''' ni ntchito iyo ŵanthu ŵakuchita kuti ŵasange [[somba]] mu maji. Somba zingasangika mu [[nyanja]], mu [[mlonga]], mu madambo na mu maji ghanyake. Ŵanthu ŵakukola somba kuti ŵasange chakulya, ndalama panji kuti ŵaguliske ku ŵanthu ŵanyake.
Kukola somba ni ntchito yakale chomene iyo yikuchitika mu vyaru vinandi pa charu chose chapasi. Mu vyaru vinyake, ntchito iyi njakuzirwa chomene pa umoyo wa ŵanthu na pa chuma cha charu.
== Mbiri ==
Kukola somba kukachitika kwamba kale chomene. Ŵanthu ŵakale ŵakasanganga somba mu maji kuti ŵasange chakulya. Pamanyuma, ŵanthu ŵakamba kugwiliskira ntchito maboti na nthowa zakupambanapambana kuti ŵasange somba zinandi.
Mu nyengo yasono, kukola somba kukuchitika pa mulingo wa banja, wa muzi, na wa makampani ghakuru.
== Nthowa zakukolera somba ==
Ŵanthu ŵakugwiliskira ntchito nthowa zakupambanapambana, kuyana na malo agho ŵakukoleramo somba. Zinyake ni:
* Kugwiliskira ntchito mikwawu.
* Kugwiliskira ntchito maukonde.
* Kugwiliskira ntchito maboti.
* Kukola somba mu maji gha pa mtunda.
== Kukola somba na chuma ==
Kukola somba kukovwira ŵanthu kusanga chakulya na ndalama. Ŵanthu ŵanandi ŵakuthemba ntchito iyi kuti ŵasange ndalama zakovwilira mbumba zawo.
Somba zikusangika mu misika na mu malo ghakuguliskiramo vyakurya. Mu vyaru vya mu Africa, somba ni chakulya chakuzirwa chomene.
== Kusunga somba ==
Somba zingawola luŵiro para zikusungika mwambura kupwelelera. Ntheura, ŵanthu ŵakuzisunga mwa kuzizizimiska, kuzomora panji kuziumiska.
== Kukola somba na chilengiwa ==
Kukola somba kukwenera kuchitika mwakupwelelera kuti somba zileke kumara mu maji. Kukola somba zinandi chomene, kweniso kuparanya malo agho somba zikubabiranamo, kungachepeska somba izo zikusangika mu nyanja na mu milonga.
== Wonaniso ==
* [[Somba]]
* [[Nyanja]]
* [[Mlonga]]
* [[Chakulya]]
* [[Maji]]
== Ukaboni ==
* [https://www.fao.org/fisheries/en/ Food and Agriculture Organization – Fisheries]
* [https://www.fao.org/sofia/en/ The State of World Fisheries and Aquaculture]
[[Category:Kukola somba]]
[[Category:Vyakulya]]
[[Category:Ntchito]]
[[Category:Chuma]]
7m9maqyniiop9vliht0h0mur4e4lao9
Template:Infobox occupation
10
50312
124226
2023-01-24T19:40:57Z
en>Zackmann08
0
Adding unknown parameter tracking through [[:Category:Pages using infobox occupation with unknown parameters]] using [[Module:check for unknown parameters]]
124226
wikitext
text/x-wiki
{{Infobox
| title = {{{name|<includeonly>{{PAGENAMEBASE}}</includeonly>}}}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{imagesize|}}}|alt={{{alt|}}}}}
| caption = {{{caption|}}}
| header1 = {{#if:{{{type|}}}{{{official_names|}}}{{{activity_sector|}}}|Occupation}}
| label2 = Names
| data2 = {{{official_names|}}}
| label3 = {{#if:{{{Synonym|}}}{{{synonym|}}}{{{Synonyms|}}}{{{synonyms|}}} |{{#if:{{{Synonym|}}}{{{synonym|}}}|Synonym|Synonyms}}}}<!-- singular/plural -->
| data3 = {{{Synonym|}}}{{{synonym|}}}{{{Synonyms|}}}{{{synonyms|}}}
| label4 = Pronunciation
| data4 = {{#if:{{{pronounce|}}}{{{Pronounce|}}}{{{Pronunciation|}}}{{{pronunciation|}}}{{{pronounce comment|}}} |<!--
-->{{ubl|1={{{pronounce|}}}{{{Pronounce|}}}{{{Pronunciation|}}}{{{pronunciation|}}}{{{pronounce ref|}}} {{{pronounce comment|}}}<!--
-->|2={{{pronounce 2|}}} }}}}
| label5 = {{longitem|Occupation type}}
| data5 = {{{type|}}}
| label6 = {{longitem|Activity sectors}}
| data6 = {{{activity_sector|}}}
| label7 = {{#if:{{{activity_sector|Health care}}}|Specialty}}
| data7 = {{#if:{{{specialty|}}}{{{Specialty|}}}{{{Speciality|}}}{{{speciality|}}}
|{{{specialty|}}}{{{Specialty|}}}{{{Speciality|}}}{{{speciality|}}} |{{#statements:P1995}} }}
| header8 = {{#if:{{{competencies|}}}{{{formation|}}}{{{employment_field|}}}{{{related_occupation|}}}|Description}}
| label9 = Competencies
| data9 = {{{competencies|}}}
| label10 = {{longitem|Education required}}
| data10 = {{{formation|}}}
| label11 = {{longitem|Fields of<br/>employment}}
| data11 = {{{employment_field|}}}
| label12 = {{longitem|Related jobs}}
| data12 = {{{related_occupation|}}}
}}{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using infobox occupation with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Infobox occupation]] with unknown parameter "_VALUE_"|ignoreblank=y| activity_sector | alt | caption | competencies | employment_field | formation | image | imagesize | name | official_names | pronounce | Pronounce | pronounce 2 | pronounce comment | pronounce ref | Pronunciation | pronunciation | related_occupation | Speciality | speciality | specialty | Specialty | Synonym | synonym | Synonyms | synonyms | type }}<noinclude>
{{documentation}}
</noinclude>
gfofu2375ty0y6th70rbcgqm3ji2e1e
124227
124226
2026-11-09T20:22:32Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_occupation]]
124226
wikitext
text/x-wiki
{{Infobox
| title = {{{name|<includeonly>{{PAGENAMEBASE}}</includeonly>}}}
| image = {{#invoke:InfoboxImage|InfoboxImage|image={{{image|}}}|size={{{imagesize|}}}|alt={{{alt|}}}}}
| caption = {{{caption|}}}
| header1 = {{#if:{{{type|}}}{{{official_names|}}}{{{activity_sector|}}}|Occupation}}
| label2 = Names
| data2 = {{{official_names|}}}
| label3 = {{#if:{{{Synonym|}}}{{{synonym|}}}{{{Synonyms|}}}{{{synonyms|}}} |{{#if:{{{Synonym|}}}{{{synonym|}}}|Synonym|Synonyms}}}}<!-- singular/plural -->
| data3 = {{{Synonym|}}}{{{synonym|}}}{{{Synonyms|}}}{{{synonyms|}}}
| label4 = Pronunciation
| data4 = {{#if:{{{pronounce|}}}{{{Pronounce|}}}{{{Pronunciation|}}}{{{pronunciation|}}}{{{pronounce comment|}}} |<!--
-->{{ubl|1={{{pronounce|}}}{{{Pronounce|}}}{{{Pronunciation|}}}{{{pronunciation|}}}{{{pronounce ref|}}} {{{pronounce comment|}}}<!--
-->|2={{{pronounce 2|}}} }}}}
| label5 = {{longitem|Occupation type}}
| data5 = {{{type|}}}
| label6 = {{longitem|Activity sectors}}
| data6 = {{{activity_sector|}}}
| label7 = {{#if:{{{activity_sector|Health care}}}|Specialty}}
| data7 = {{#if:{{{specialty|}}}{{{Specialty|}}}{{{Speciality|}}}{{{speciality|}}}
|{{{specialty|}}}{{{Specialty|}}}{{{Speciality|}}}{{{speciality|}}} |{{#statements:P1995}} }}
| header8 = {{#if:{{{competencies|}}}{{{formation|}}}{{{employment_field|}}}{{{related_occupation|}}}|Description}}
| label9 = Competencies
| data9 = {{{competencies|}}}
| label10 = {{longitem|Education required}}
| data10 = {{{formation|}}}
| label11 = {{longitem|Fields of<br/>employment}}
| data11 = {{{employment_field|}}}
| label12 = {{longitem|Related jobs}}
| data12 = {{{related_occupation|}}}
}}{{#invoke:Check for unknown parameters|check|unknown={{main other|[[Category:Pages using infobox occupation with unknown parameters|_VALUE_{{PAGENAME}}]]}}|preview=Page using [[Template:Infobox occupation]] with unknown parameter "_VALUE_"|ignoreblank=y| activity_sector | alt | caption | competencies | employment_field | formation | image | imagesize | name | official_names | pronounce | Pronounce | pronounce 2 | pronounce comment | pronounce ref | Pronunciation | pronunciation | related_occupation | Speciality | speciality | specialty | Specialty | Synonym | synonym | Synonyms | synonyms | type }}<noinclude>
{{documentation}}
</noinclude>
gfofu2375ty0y6th70rbcgqm3ji2e1e
Template:Infobox occupation/doc
10
50313
124228
2023-11-11T19:28:29Z
en>OverlordQ
0
Reverted edits by [[Special:Contributions/201.168.107.145|201.168.107.145]] ([[User talk:201.168.107.145|talk]]) ([[WP:HG|HG]]) (3.4.12)
124228
wikitext
text/x-wiki
{{Documentation subpage}}
{{Lua|Module:Infobox|Module:InfoboxImage|Module:Check for unknown parameters}}
<!-- Please place categories where indicated at the bottom of this page and interwikis at Wikidata (see [[Wikipedia:Wikidata]]) -->
== Usage ==
{{Parameter names example
| name
| synonyms
| pronounce
| image
| imagesize
| alt
| caption
| official_names
| type
| activity_sector
| competencies
| formation
| employment_field
| related_occupation
}}
An occupation infobox may be used to summarize information about a particular occupation, trade, profession, job or employment. The infobox should be added using the {{tl|Infobox occupation}} template, as shown below:
<syntaxhighlight lang="wikitext" style="overflow:auto;">
{{Infobox occupation
| name =
| synonyms =
| pronounce =
| image =
| imagesize =
| alt =
| caption =
| official_names =
| type =
| activity_sector =
| competencies =
| formation =
| employment_field =
| related_occupation =
}}
</syntaxhighlight>
===General parameters===
* '''name''' – the formal name of the occupation. Can be <nowiki>{{PAGENAME}}</nowiki>.
* '''image''' – ''optional'' – an image of the occupation. The image must be given in the form: <nowiki>File:Example.jpg</nowiki>; in particular. '''imagesize''' can be left blank.
* '''caption''' and '''alt''' – ''optional'' – the text to be placed below the image.
* '''official_names''' – ''optional'' – the names or synonyms for the particular occupation, including the principal name (which can be <nowiki>{{PAGENAME}}</nowiki>).
* '''type''' – ''optional'' – the type of occupation (e.g. "[[profession]]", "[[employment]]", "[[vocation]]", "[[performing arts]]", "[[military]]", etc.).
* '''activity_sector''' – ''optional'' – the main activity sectors of the occupation (e.g. "[[management]]", "[[science]]", "[[laboratory]]", "[[circus]]", "[[Forms of government|government]]", "[[show business]]", etc.).
* '''competencies''' – ''optional'' – competencies and qualities required.
* '''formation''' – ''optional'' – formation and education necessary.
* '''employment_field''' – ''optional'' – fields of employment and places we can encounter someone with the occupation.
* '''related_occupation''' – ''optional'' – related occupations.
== Template data ==
{{TemplateData header}}
<templatedata>
{
"params": {
"name": {},
"image": {"type": "wiki-file-name"},
"imagesize": {},
"alt": {},
"caption": {},
"type": {},
"official_names": {},
"activity_sector": {},
"Synonym": {},
"synonym": {},
"Synonyms": {},
"synonyms": {},
"pronounce": {},
"Pronounce": {},
"Pronunciation": {},
"pronunciation": {},
"pronounce comment": {},
"pronounce ref": {},
"pronounce 2": {},
"specialty": {},
"Specialty": {},
"Speciality": {},
"speciality": {},
"competencies": {},
"formation": {},
"employment_field": {},
"related_occupation": {}
}
}
</templatedata>
<includeonly>{{sandbox other||
<!-- Categories below this line, please; interwikis at Wikidata -->
[[Category:Business infobox templates|Occupation]]
}}</includeonly>
{{Main other}}
do1nvhj1vleapdmxfz2vdfodt2fjpzw
124229
124228
2026-11-09T20:22:33Z
Tumbuka Arch
6863
1 revision imported from [[:en:Template:Infobox_occupation/doc]]
124228
wikitext
text/x-wiki
{{Documentation subpage}}
{{Lua|Module:Infobox|Module:InfoboxImage|Module:Check for unknown parameters}}
<!-- Please place categories where indicated at the bottom of this page and interwikis at Wikidata (see [[Wikipedia:Wikidata]]) -->
== Usage ==
{{Parameter names example
| name
| synonyms
| pronounce
| image
| imagesize
| alt
| caption
| official_names
| type
| activity_sector
| competencies
| formation
| employment_field
| related_occupation
}}
An occupation infobox may be used to summarize information about a particular occupation, trade, profession, job or employment. The infobox should be added using the {{tl|Infobox occupation}} template, as shown below:
<syntaxhighlight lang="wikitext" style="overflow:auto;">
{{Infobox occupation
| name =
| synonyms =
| pronounce =
| image =
| imagesize =
| alt =
| caption =
| official_names =
| type =
| activity_sector =
| competencies =
| formation =
| employment_field =
| related_occupation =
}}
</syntaxhighlight>
===General parameters===
* '''name''' – the formal name of the occupation. Can be <nowiki>{{PAGENAME}}</nowiki>.
* '''image''' – ''optional'' – an image of the occupation. The image must be given in the form: <nowiki>File:Example.jpg</nowiki>; in particular. '''imagesize''' can be left blank.
* '''caption''' and '''alt''' – ''optional'' – the text to be placed below the image.
* '''official_names''' – ''optional'' – the names or synonyms for the particular occupation, including the principal name (which can be <nowiki>{{PAGENAME}}</nowiki>).
* '''type''' – ''optional'' – the type of occupation (e.g. "[[profession]]", "[[employment]]", "[[vocation]]", "[[performing arts]]", "[[military]]", etc.).
* '''activity_sector''' – ''optional'' – the main activity sectors of the occupation (e.g. "[[management]]", "[[science]]", "[[laboratory]]", "[[circus]]", "[[Forms of government|government]]", "[[show business]]", etc.).
* '''competencies''' – ''optional'' – competencies and qualities required.
* '''formation''' – ''optional'' – formation and education necessary.
* '''employment_field''' – ''optional'' – fields of employment and places we can encounter someone with the occupation.
* '''related_occupation''' – ''optional'' – related occupations.
== Template data ==
{{TemplateData header}}
<templatedata>
{
"params": {
"name": {},
"image": {"type": "wiki-file-name"},
"imagesize": {},
"alt": {},
"caption": {},
"type": {},
"official_names": {},
"activity_sector": {},
"Synonym": {},
"synonym": {},
"Synonyms": {},
"synonyms": {},
"pronounce": {},
"Pronounce": {},
"Pronunciation": {},
"pronunciation": {},
"pronounce comment": {},
"pronounce ref": {},
"pronounce 2": {},
"specialty": {},
"Specialty": {},
"Speciality": {},
"speciality": {},
"competencies": {},
"formation": {},
"employment_field": {},
"related_occupation": {}
}
}
</templatedata>
<includeonly>{{sandbox other||
<!-- Categories below this line, please; interwikis at Wikidata -->
[[Category:Business infobox templates|Occupation]]
}}</includeonly>
{{Main other}}
do1nvhj1vleapdmxfz2vdfodt2fjpzw
Category:Vyakulya
14
50314
124230
2026-11-09T20:23:01Z
Tumbuka Arch
6863
Created blank page
124230
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ntchito
14
50315
124231
2026-11-09T20:23:04Z
Tumbuka Arch
6863
Created blank page
124231
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Kukola somba
14
50316
124232
2026-11-09T20:23:08Z
Tumbuka Arch
6863
Created blank page
124232
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Minamoto no Yoritomo
0
50317
124233
2026-11-09T20:29:54Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi wakwamba wa boma la Kamakura mu Japan}} [[File:MinamotoYoritomo.jpg|thumb|200px|Chithuzithuzi cha Minamoto no Yoritomo chakupangika na Nakamura Fusetsu.]] '''Minamoto no Yoritomo''' (源頼朝; 1147–1199) wakaŵa mulongozgi wa ŵasilikari wa ku [[Japan]] uyo wakakhazikiska boma la Kamakura. Wakapokera udindo wa ''[[shōgun]]'' mu 1192, ndipo wakazgoka mulongozgi wakwamba wa boma la shogunate la Kamakura.<ref>{{Cite web |url=https://www.ci..."
124233
wikitext
text/x-wiki
{{Short description|Mulongozgi wakwamba wa boma la Kamakura mu Japan}}
[[File:MinamotoYoritomo.jpg|thumb|200px|Chithuzithuzi cha Minamoto no Yoritomo chakupangika na Nakamura Fusetsu.]]
'''Minamoto no Yoritomo''' (源頼朝; 1147–1199) wakaŵa mulongozgi wa ŵasilikari wa ku [[Japan]] uyo wakakhazikiska boma la Kamakura. Wakapokera udindo wa ''[[shōgun]]'' mu 1192, ndipo wakazgoka mulongozgi wakwamba wa boma la shogunate la Kamakura.<ref>{{Cite web |url=https://www.city.kamakura.kanagawa.jp/sekaiisan/documents/jh_booklet_e02.pdf |title=The Kamakura Period (1185–1333) |publisher=City of Kamakura |access-date=9 November 2026}}</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Yoritomo wakababika mu 1147 mu banja la Minamoto, ilo likaŵa limoza mwa mbumba zikuru za ŵasilikari mu Japan. Awiske ŵakaŵa Minamoto no Yoshitomo.
Mu 1159, pa nkhondo ya Heiji, banja la Minamoto likathereskeka na banja la Taira, ilo likalongozgekanga na Taira no Kiyomori. Yoritomo wakakoleka, kweni wakakomeka yayi. Wakachimbizgikira ku chigaŵa cha Izu, uko wakakhala kwa vyaka vinandi.<ref>{{Cite web |url=https://www.city.kamakura.kanagawa.jp/sekaiisan/documents/jh_booklet_e02.pdf |title=The Kamakura Period (1185–1333) |publisher=City of Kamakura |access-date=9 November 2026}}</ref>
== Kwamba kwa nkhondo na banja la Taira ==
Mu 1180, Yoritomo wakawuska ŵasilikari ŵake na kwamba kulimbana na banja la Taira. Wakakhazikiska malo ghake ghakuru ku [[Kamakura]], uko kukaŵa malo ghawemi gha kulongozgera ŵasilikari ŵake.
Ŵabali ŵake ŵanyake, kusazgapo Minamoto no Yoshitsune na Minamoto no Noriyori, nawo ŵakamovwira. Mu 1185, ŵasilikari ŵa Minamoto ŵakathereska banja la Taira pa nkhondo ya Dan-no-ura. Ichi chikamara nkhongono za Taira pa boma la Japan.
== Boma la Kamakura ==
Pamanyuma pa kuwina nkhondo, Yoritomo wakakhazikiska ndondomeko ya boma la ŵasilikari ku Kamakura. Wakimika ŵalara ŵa mu vigaŵa awo ŵakaŵa na milimo ya kusunga dango, kulongozga vigaŵa na kuwoneseska kuti misonkho yikuperekeka.
Mu 1192, wakapokera udindo wa Seii Taishōgun kufuma kwa fumu ya Japan. Udindo uwu ukamovwira kukhozga boma la ŵasilikari ilo likamanyikwanga kuti Kamakura shogunate.
Boma la Kamakura likaŵa lakuzirwa chifukwa likasintha umo Japan yikawusikiranga. Nkhongono za ŵasilikari na ŵalongozgi ŵa mbumba zikakura, ndipo Kamakura yikazgoka likuru la ndyali kwa vyaka vinandi.
== Mbumba yake ==
Yoritomo wakatora Hōjō Masako, mwanakazi uyo wakafuma mu banja la Hōjō. Banja ili likazgoka lakuzirwa chomene mu boma la Kamakura, ndipo ŵanthu ŵake ŵakazganga na kulongozga boma pamanyuma pa nyifwa ya Yoritomo.
== Nyifwa ==
Yoritomo wakafwa mu 1199. Pamanyuma pa nyifwa yake, boma la Kamakura likalutilira kuwusa kweni nkhongono zinandi zikamba kusangika mu banja la Hōjō.
== Vithuzithuzi ==
<gallery>
File:Minamoto no Yoritomo.jpg|Chithuzithuzi icho kale chikamanyikwanga kuti chikulongora Yoritomo; ŵakusambira ŵanyake ŵakususka kuti munthu uyo walongoreka ni Yoritomo.
File:Minamoto no Yoritomo painting.jpg|Chithuzithuzi chinyake chakuyana na Yoritomo.
File:Minamoto no Yoritomo hanging scroll painting 14th century.jpg|Chithuzithuzi cha pa mpukutu cha nyengo ya pakati pa vyaka vya m'ma 1300.
File:Shugos during the Kamakura period.jpg|Mapu ghakulongora umo ŵalara ŵa vigaŵa ŵakagaŵikira mu nyengo ya Kamakura.
</gallery>
== Wonaniso ==
* [[Shōgun]]
* [[Boma la Kamakura]]
* [[Mbiri ya Japan]]
* [[Japan]]
* [[Ŵasilikari ŵa Samurai]]
== Ukaboni ==
<references />
[[Category:Ŵanthu ŵa ku Japan]]
[[Category:Ŵalongozgi ŵa ŵasilikari]]
[[Category:Mbiri ya Japan]]
[[Category:1147 births]]
[[Category:1199 deaths]]
7z87rdcbaou0ds6yiimmxqszf7z2tms
Akihito
0
50318
124234
2026-11-09T20:30:11Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu ya Japan ya nambara 125 iyo yikaleka chitengo mu 2019}} [[File:Emperor Akihito (2016).jpg|thumb|200px|Akihito mu 2016.]] '''Akihito''' (mu Chijapanizi: 明仁; wakababika pa 23 Disembala 1933) ni fumu yakale ya Japan ya nambara 125. Wakawusa kwamba pa 7 Janyuwale 1989 mpaka apo wakaleka chitengo pa 30 Epulero 2019. Pamanyuma pa kuleka chitengo, wakapika udindo wakuti fumu yakale (Emperor Emeritus).<ref>{{Cite web |url=https://www.kunaicho.go.jp/e..."
124234
wikitext
text/x-wiki
{{Short description|Fumu ya Japan ya nambara 125 iyo yikaleka chitengo mu 2019}}
[[File:Emperor Akihito (2016).jpg|thumb|200px|Akihito mu 2016.]]
'''Akihito''' (mu Chijapanizi: 明仁; wakababika pa 23 Disembala 1933) ni fumu yakale ya Japan ya nambara 125. Wakawusa kwamba pa 7 Janyuwale 1989 mpaka apo wakaleka chitengo pa 30 Epulero 2019. Pamanyuma pa kuleka chitengo, wakapika udindo wakuti fumu yakale (Emperor Emeritus).<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history02.html |title=Their Majesties the Emperor Emeritus and Empress Emerita |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Akihito wakababika ku Tokyo pa 23 Disembala 1933. Wakaŵa mwana wakwamba wa Fumu Hirohito, uyo pamanyuma wakamanyikwanga kuti Fumu Shōwa, na Mfumukazi Kōjun.
Apo wakaŵa mwana, wakaŵa na zina la mu nyumba ya ufumu lakuti Tsugu-no-Miya. Wakasambira pa sukulu ya Gakushuin, ndipo wakamalizga masambiro ghake gha ku yunivesite mu 1956.
== Nthengwa na mbumba ==
Pa 10 Epulero 1959, Akihito wakatora Michiko Shōda. Nthengwa yawo yikaŵa yakuzirwa chifukwa Michiko wakafuma mu banja ilo likaŵa la nyumba ya ufumu yayi.
Ŵakaŵa na ŵana ŵatatu:
* Naruhito, uyo wakazgoka fumu ya Japan mu 2019.
* Fumupachanya Akishino (Fumihito).
* Sayako Kuroda.
== Kuŵa fumu ya Japan ==
Pa 7 Janyuwale 1989, Akihito wakakwera pa chitengo pamanyuma pa nyifwa ya adada ŵake, Fumu Hirohito. Mwambo wake wa kuŵa fumu ukachitika pa 12 Novembala 1990.
Nyengo ya kuwusa kwake yikamanyikwanga kuti Heisei. Mu nyengo iyi, Japan yikakumana na masuzgo gha chuma, masuzgo gha vinthu vyachilengiwa, na kusintha kwa umoyo wa ŵanthu.
Mwakuyana na malango gha Japan, fumu yili na udindo wa kuŵa chimanyikwiro cha charu na umoza wa ŵanthu. Akihito wakateŵetera mu udindo uwu kwambira 1989 mpaka 2019.
== Kuleka chitengo ==
Mu 2019, Akihito wakaleka chitengo cha ufumu. Mwambo wa kuleka chitengo ukachitika pa 30 Epulero 2019, ndipo mwana wake Naruhito wakakwera pa chitengo pa 1 Meyi 2019. Ichi chikaŵa chakuzirwa chomene chifukwa chikaŵa chambura kuchitika kwa nyengo yitali mu mbiri ya nyumba ya ufumu ya Japan.<ref>{{Cite web |url=https://www.au.emb-japan.go.jp/itpr_en/accession_to_the_throne_of_his_majesty_the_emperor.html |title=Accession to the Throne of His Majesty the Emperor |publisher=Embassy of Japan in Australia |access-date=9 November 2026}}</ref>
== Vyakukondweska ivyo wakachitanga ==
Akihito wakakondwanga na sayansi, chomenechomene kusambira vya somba. Wakachita kafukufuku wa mitundu ya somba za muryango wa goby ndipo wakalemba nkhani za sayansi pa nkhani iyi.
== Vithuzithuzi ==
<gallery>
File:Emperor Akihito Formal portrait.jpg|Chithuzithuzi cha Akihito.
File:Akihito at Andrews Air Force Base 1987 (cropped).jpg|Akihito apo wakalutanga ku United States mu 1987.
File:Emperor Akihito 198901.jpg|Akihito mu nyengo iyo wakazgokera fumu.
</gallery>
== Wonaniso ==
* [[Naruhito]]
* [[Japan]]
* [[Hirohito]]
* [[Ufumu wa Japan]]
* [[Mbiri ya Japan]]
== Ukaboni ==
<references />
[[Category:Ŵafumu ŵa ku Japan]]
[[Category:Ŵanthu ŵa mu 1933]]
[[Category:Mbiri ya Japan]]
sor7yk8szjpi138prjvmdg6vv10fm4o
Category:Ŵanthu ŵa ku Japan
14
50319
124235
2026-11-09T20:30:33Z
Tumbuka Arch
6863
Created blank page
124235
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵalongozgi ŵa ŵasilikari
14
50320
124236
2026-11-09T20:30:35Z
Tumbuka Arch
6863
Created blank page
124236
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya Japan
14
50321
124237
2026-11-09T20:30:39Z
Tumbuka Arch
6863
Created blank page
124237
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵanthu ŵa mu 1933
14
50322
124238
2026-11-09T20:30:53Z
Tumbuka Arch
6863
Created blank page
124238
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵafumu ŵa ku Japan
14
50323
124239
2026-11-09T20:30:57Z
Tumbuka Arch
6863
Created blank page
124239
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Naruhito
0
50324
124240
2026-11-09T20:31:27Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu ya nambara 126 ya Japan}} [[File:Emperor Naruhito Portrait (3x4 cropped).jpg|thumb|200px|Naruhito, fumu ya Japan.]] '''Naruhito''' (mu Chijapanizi: 徳仁; wakababika pa 23 Febuluwale 1960) ni fumu ya Japan ya nambara 126. Wakakwera pa chitengo pa 1 Meyi 2019, pamanyuma pakuti adada ŵake, [[Akihito]], ŵaleka udindo wa ufumu. Naruhito ndiyo wakawusanga Japan kwamba mu nyengo ya Reiwa.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about..."
124240
wikitext
text/x-wiki
{{Short description|Fumu ya nambara 126 ya Japan}}
[[File:Emperor Naruhito Portrait (3x4 cropped).jpg|thumb|200px|Naruhito, fumu ya Japan.]]
'''Naruhito''' (mu Chijapanizi: 徳仁; wakababika pa 23 Febuluwale 1960) ni fumu ya Japan ya nambara 126. Wakakwera pa chitengo pa 1 Meyi 2019, pamanyuma pakuti adada ŵake, [[Akihito]], ŵaleka udindo wa ufumu. Naruhito ndiyo wakawusanga Japan kwamba mu nyengo ya Reiwa.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress: His Majesty the Emperor Naruhito |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Naruhito wakababika pa 23 Febuluwale 1960 ku Tokyo, Japan. Ni mwana wakwamba wa Akihito na Michiko, awo pamanyuma ŵakazgoka fumu na mfumukazi ya Japan.
Apo wakaŵa mwana, wakaŵa na zina la mu nyumba ya ufumu lakuti Hiro-no-Miya. Mu 1980 wakachita mwambo wake wa kufika pa msinkhu wa munthu mulara, ndipo mu 1991 wakapika udindo wa mulongozgi uyo wakeneranga kuzakaŵa fumu.
== Masambiro ==
Naruhito wakasambira pa yunivesite ya Gakushuin ku Tokyo, uko wakamalizga masambiro mu 1982. Kufuma mu 1983 mpaka 1985, wakasambira ku Merton College, ku [[University of Oxford]] mu [[United Kingdom]]. Wakasambira chomene nkhani zakukhwaskana na mbiri ya maji na umo ŵanthu ŵakugwiliskira ntchito maji.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=His Majesty the Emperor Naruhito |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Nthengwa na mbumba ==
Pa 9 Juni 1993, Naruhito wakatora Masako Owada. Masako wakaŵa wakusambira vya maubwezi gha vyaru na ntchito za boma la Japan pambere wandatore.
Mwana wawo mwanakazi, Aiko, wakababika pa 1 Disembala 2001. Aiko wali na zina la mu nyumba ya ufumu lakuti Toshi-no-Miya.
== Kukhala fumu ==
Pa 30 Epulero 2019, adada ŵake Akihito ŵakaleka chitengo cha ufumu. Pa 1 Meyi 2019, Naruhito wakakwera pa chitengo na kuŵa fumu ya Japan. Nyengo yiphya ya mu mbiri ya Japan yikapika zina lakuti Reiwa.
Naruhito ni fumu ya mu nyengo iyo Japan yikwendeskeka mwakuyana na malango gha boma. Mwakuyana na malango gha charu ichi, fumu yikuwoneka nga ni chimanyikwiro cha charu na umoza wa ŵanthu ŵake. Nkhongono za boma zikukhala na mabungwe agho ghakusankhika na ŵanthu.
== Vithuzithuzi ==
<gallery>
File:Crown Prince Naruhito (2018).jpg|Naruhito apo wakaŵa mulongozgi wakulondezgapo chitengo.
File:Emperor Naruhito and Empress Masako (cropped).jpg|Naruhito na muwoli wake Masako.
File:Emperor Naruhito 201905.jpg|Chithuzithuzi cha Naruhito mu 2019.
</gallery>
== Wonaniso ==
* [[Akihito]]
* [[Japan]]
* [[Ufumu wa Japan]]
* [[Masako]]
* [[Mbiri ya Japan]]
== Ukaboni ==
<references />
[[Category:Ŵafumu ŵa ku Japan]]
[[Category:Ŵanthu ŵa mu 1960]]
[[Category:Ŵanthu ŵamoyo]]
[[Category:Mbiri ya Japan]]
n8ja5qgrljj629cf0y43ypwn6fqnir8
Strawberry
0
50325
124241
2026-11-09T20:35:25Z
Tumbuka Arch
6863
Redirected page to [[Matubeni]]
124241
wikitext
text/x-wiki
#REDIRECT [[Matubeni]]
21ucliyjf9v3crudk1fyzlvvasmtinn
Matubeni
0
50326
124242
2026-11-09T20:35:52Z
Tumbuka Arch
6863
Created page with "{{Short description|Chipambi chakufipa chakuŵa chakutowa icho chikufuma pa chimeri cha Fragaria}} [[File:20140529Fragaria × ananassa.jpg|thumb|250px|Matubeni ghakukhwima gha mtundu wa Fragaria × ananassa.]] '''Matubeni''' (mu Chingelezi: ''strawberries'') ni vipambi vyakutowa vyakufipa panji vyakupenuka ivyo vikufuma pa vyakumera vya mu mtundu wa ''Fragaria''. Matubeni ghakuryeka na ŵanthu mu vyaru vinandi chifukwa cha kunowa kwake, kununkhira makora na umo ghakugwil..."
124242
wikitext
text/x-wiki
{{Short description|Chipambi chakufipa chakuŵa chakutowa icho chikufuma pa chimeri cha Fragaria}}
[[File:20140529Fragaria × ananassa.jpg|thumb|250px|Matubeni ghakukhwima gha mtundu wa Fragaria × ananassa.]]
'''Matubeni''' (mu Chingelezi: ''strawberries'') ni vipambi vyakutowa vyakufipa panji vyakupenuka ivyo vikufuma pa vyakumera vya mu mtundu wa ''Fragaria''. Matubeni ghakuryeka na ŵanthu mu vyaru vinandi chifukwa cha kunowa kwake, kununkhira makora na umo ghakugwiliskirika ntchito mu vyakurya.<ref>Royal Horticultural Society, “Fragaria × ananassa”, https://www.rhs.org.uk/plants/106127/fragaria-%C3%97-ananassa-f/details (likawelerapo pa 9 Novembala 2026).</ref>
== Umo chimeri chiliri ==
Chimeri cha matubeni chili mu mbumba ya ''Rosaceae''. Chili na mahamba agho kanandi ghali na vigawo vitatu pa phesi limoza. Chimeri ichi chikukura pafupi na pasi ndipo chikutumizga mathawiro ghakujandawuka agho ghangaŵa vyamera viphya para vyakumana na dongo.
Maluŵa ghake ghakuŵa ghatuŵa ndipo kanandi ghali na vigawo vinkhondi. Pamanyuma pa kusazgika kwa pollen, chimeri ichi chikwamba kupanga chipambi.
== Chipambi ==
Matubeni ghakumanyikwa chifukwa cha mtundu wake wakufipa na kakomedwe kake. Kweni mwakuyana na sayansi ya vyakumera, tubeni ni chipambi chamtundu wakupambanapambana (''aggregate accessory fruit''). Chigaŵa chakuthupi icho ŵanthu ŵakurya chikufuma pa chigaŵa chakuzura cha luŵa, apo tumakuŵa twakuwoneka nga ni mbuto pa kuwaro kwa tubeni ni vipambi vichoko ivyo vikuchemeka ''achenes''.<ref>University of Saskatchewan, “Strawberries”, Gardening at USask, https://gardening.usask.ca/gardening-advice/gardenline-nested-pages/food-plant-pages/fruit/strawberry.php (likawelerapo pa 9 Novembala 2026).</ref>
== Umo matubeni ghakukulira ==
Matubeni ghakumera makora mu dongo ilo lili na vyakurya ndipo likufumiska maji mwaluŵiro. Ghakukhumbikwira ungweru wa dazi na maji ghakukwana kuti ghakule makora. Maluŵa ghake ghakupokera wovwiri wa tizinyama nga ni njuchi pakusazga pollen.
Chimeri cha matubeni ni chimeri icho chingakhala vyaka vinandi, nangauli ŵalimi ŵanyake ŵakuchipanda nga ni chimeri cha chaka chimoza panji viŵiri kuyana na mtundu wa mbuto na umo ŵakulimira.
== Mitundu ==
Pali mitundu yinandi ya matubeni. Matubeni agho ŵanthu ŵakulima chomene mazuŵa ghano ghakumanyikwa na zina la sayansi lakuti ''Fragaria × ananassa''. Mtundu uwu ukafuma ku kusazgika kwa mitundu yiŵiri ya kale ya Fragaria, ndipo mazuŵa ghano ukulimika mu vyaru vinandi pa charu chose.<ref>Royal Horticultural Society, “Fragaria × ananassa”, https://www.rhs.org.uk/plants/106127/fragaria-%C3%97-ananassa-f/details (likawelerapo pa 9 Novembala 2026).</ref>
== Ntchito zake ==
Matubeni ghakuryeka ghaphya panji ghakugwiliskirika ntchito pakupanga:
* Jamu na vyakurya vyakupakika pa chingwa.
* Madzi gha chipambi na vyakumwa vinyake.
* Aisikilimu na vyakurya vyakuzizima.
* Keke, mabisiketi na vyakurya vyakuphikika.
* Saladi ya vipambi na vyakurya vinyake.
Matubeni ghaliso na vitamin C na vyakurya vinyake ivyo vikovwira kuti thupi liŵe na umoyo uwemi.<ref>Royal Botanic Gardens, Kew, “Garden strawberry – Fragaria × ananassa”, https://www.kew.org/plants/garden-strawberry (likawelerapo pa 9 Novembala 2026).</ref>
== Vithuzithuzi ==
<gallery>
File:20140529Fragaria × ananassa.jpg|Matubeni ghakukhwima.
File:-2020-06-06 Strawberry plant with fruit, (Fragaria × ananassa), Trimingham.JPG|Chimeri cha matubeni chili na vipambi.
File:-2020-06-06 Strawberry plant with unripe fruit, (Fragaria × ananassa), Trimingham.JPG|Matubeni ghambura kukhwima.
File:13 small strawberries (e-citizen).JPG|Matubeni ghanandi ghachoko.
</gallery>
== Wonaniso ==
* [[Vipambi]]
* [[Vyakurya]]
* [[Vyakumera]]
* [[Rosaceae]]
== Ukaboni ==
<references />
[[Category:Vipambi]]
[[Category:Vyakurya]]
[[Category:Vyakumera]]
[[Category:Rosaceae]]
4zeeom4guxuyz5f060alxqr9k1c7dz7
Shoebill
0
50327
124243
2026-11-09T20:38:08Z
Tumbuka Arch
6863
Redirected page to [[Chiyuni cha Bill cha mlomo wa skapato]]
124243
wikitext
text/x-wiki
#REDIRECT [[Chiyuni cha Bill cha mlomo wa skapato]]
9ueuhulf1bco6gtkbug1qs1s82u2mcm
Dolphin
0
50328
124244
2026-11-09T20:38:48Z
Tumbuka Arch
6863
Created page with "{{Short description|Chinyama cha mu nyanja icho chili mu gulu la nyama zakamwaŵa}} [[File:010 Atlantic bottlenose dolphin jumping at Pelican point Photo by Giles Laurent.jpg|thumb|250px|Dolphin ya mtundu wa bottlenose yikujumphira pachanya pa maji.]] '''Dolphin''' ni chinyama cha mu nyanja icho chili mu gulu la nyama zakamwaŵa. Nangauli chikukhala mu maji, dolphin ni nyama yakamwaŵa, nga umo viliri na ŵanthu, ndipo chikupempha mphepo kwizira mu mapapo m'malo mwa kuko..."
124244
wikitext
text/x-wiki
{{Short description|Chinyama cha mu nyanja icho chili mu gulu la nyama zakamwaŵa}}
[[File:010 Atlantic bottlenose dolphin jumping at Pelican point Photo by Giles Laurent.jpg|thumb|250px|Dolphin ya mtundu wa bottlenose yikujumphira pachanya pa maji.]]
'''Dolphin''' ni chinyama cha mu nyanja icho chili mu gulu la nyama zakamwaŵa. Nangauli chikukhala mu maji, dolphin ni nyama yakamwaŵa, nga umo viliri na ŵanthu, ndipo chikupempha mphepo kwizira mu mapapo m'malo mwa kukoka oxygen mu maji kwizira mu mathenga nga umo somba zikuchitira.<ref>National Oceanic and Atmospheric Administration (NOAA), “Are dolphins fish?”, https://oceanservice.noaa.gov/facts/dolphin.html (likawelerapo pa 9 Novembala 2026).</ref>
Pali mitundu yakupambanapambana ya dolphin. Yinyake yikukhala mu nyanja zakuzika, apo yinyake yikusangika pafupi na mphepete mwa nyanja. Mitundu yake yikusiyana pa ukuru, mtundu na umo yikukhalira.
== Umo thupi lake liliri ==
Dolphin zili na thupi lakusalala ilo likovwira kuti zisambe luŵiro mu maji. Zili na mapapiko gha pa chifuŵa agho ghakovwira kusintha nthowa, mapapiko gha pa msana agho ghakovwira kuti thupi lileke kuwira, na mchira uwo zikugwiliskira ntchito pakusambira.
Dolphin zikupuma mphepo kwizira mu kabowo ako kali pachanya pa mutu wawo. Para zikukhumbikwira kupuma, zikufumira pachanya pa maji na kutora mphepo, ndipo pamanyuma zikubizgikira so mu maji.
== Chakurya ==
Mitundu yinandi ya dolphin yikurya somba, nkhonyo na vyamoyo vinyake vya mu nyanja. Umo yikusakira chakurya ukusiyana kuyana na mtundu wake na malo agho yikukhala.
== Uchenjeri na kuyowoyeskana ==
Dolphin zikumanyikwa chifukwa cha uchenjeri na umo zikuyowoyeskana. Zikupanga mazgu ghakupambanapambana, kusazgapo viyowoyero vyakukoleka na mawu ghakufupika. Zinyake zikukhala mu magulu agho ghakumanyikwa kuti ''pods''.
Dolphin zakamwaŵa zikugwiliskiraso ntchito nthowa yakumanyikwa kuti ''echolocation''. Mu nthowa iyi, zikupanga mazgu ghakukoma na kupulikizga umo mazgu agha ghakuwelera para ghakumana na vinthu vinyake. Ivi vikuŵawovwira kumanya uko kuli vyakurya panji vinthu vinyake mu maji, nangauli maji ghangaŵa ghakuzizima panji ghakubisika.<ref>Whale and Dolphin Conservation, “How do dolphins communicate?”, https://uk.whales.org/whales-dolphins/how-do-dolphins-communicate/ (likawelerapo pa 9 Novembala 2026).</ref>
== Kubaba na kupwelelera ŵana ==
Dolphin zanakazi zikubaba ŵana ŵamoyo m’malo mwa kuyikira masumbi. Mwanakazi wakonkheska mwana wake mkaka mpaka apo wakukulira. Ŵana ŵakukhala pafupi na amama ŵawo apo ŵakusambira na kusambira umo ŵangapenjera chakurya.
== Malo agho zikukhala ==
Dolphin zikusangika mu nyanja zakupambanapambana pa charu chose. Mitundu yinyake yikusangikaso mu milonga yikuru ya maji ghakunowa. Malo agho zikukhala ghakukhwaskika na kusazgikira kwa vyakufipiska maji, kukola somba mwakujumphizga na kusintha kwa malo gha mu nyanja.
== Dolphin na ŵanthu ==
Dolphin zili na malo ghakuzirwa mu kafukufuku wa vyamoyo vya mu nyanja. Ŵanthu ŵakusambira umo zikukhala, umo zikupemphera mphepo na umo zikuyowoyeskana. Kweniso dolphin zikuŵa zakuzirwa mu ntchito za kuvikilira nyanja na vyamoyo vyake.
== Vithuzithuzi ==
<gallery>
File:010 Atlantic bottlenose dolphin jumping at Pelican point Photo by Giles Laurent.jpg|Bottlenose dolphin yikujumphira pachanya pa maji.
File:Tursiops truncatus 01.jpg|Bottlenose dolphin.
File:Tursiops truncatus 01 (cropped 2).jpg|Dolphin ya mtundu wa bottlenose.
File:Cetacea range map Bottlenose Dolphin.png|Mapu ghakulongora malo agho bottlenose dolphin yikusangikamo.
</gallery>
== Wonaniso ==
* [[Somba]]
* [[Whale]]
* [[Nyanja]]
* [[Vyamoyo vya mu nyanja]]
== Ukaboni ==
<references />
[[Category:Vinyama vya mu nyanja]]
[[Category:Vyamoyo vyakumamwaŵa]]
[[Category:Cetacea]]
i4nst8uzl2udp2ktrq2glq8b5mgrrjj
Cheetah
0
50329
124245
2026-11-09T20:39:10Z
Tumbuka Arch
6863
Created page with "{{Short description|Chinyama cha mu banja la mphaka icho chikuthamanga chomene}} [[File:Acinonyx jubatus (1).jpg|thumb|250px|Cheetah (Acinonyx jubatus).]] '''Cheetah''' (''Acinonyx jubatus'') ni chinyama chikuru cha mu banja la [[mphaka]]. Chikumanyikwa chomene chifukwa cha kuthamanga chomene. Cheetah ndicho chinyama chakuthamanga chomene pa vyamoyo ivyo vikukhala pa mtunda, ndipo chingafika pa liŵiro la pafupifupi makilomita 96 mpaka 112 pa ora kwa nyengo yichoko.<ref>..."
124245
wikitext
text/x-wiki
{{Short description|Chinyama cha mu banja la mphaka icho chikuthamanga chomene}}
[[File:Acinonyx jubatus (1).jpg|thumb|250px|Cheetah (Acinonyx jubatus).]]
'''Cheetah''' (''Acinonyx jubatus'') ni chinyama chikuru cha mu banja la [[mphaka]]. Chikumanyikwa chomene chifukwa cha kuthamanga chomene. Cheetah ndicho chinyama chakuthamanga chomene pa vyamoyo ivyo vikukhala pa mtunda, ndipo chingafika pa liŵiro la pafupifupi makilomita 96 mpaka 112 pa ora kwa nyengo yichoko.<ref>Smithsonian's National Zoo and Conservation Biology Institute, “Cheetah”, https://nationalzoo.si.edu/animals/cheetah (likawelerapo pa 9 Novembala 2026).</ref>
== Umo thupi lake liliri ==
Cheetah chili na thupi lakuwonda, malundi ghatali, nthumbo yichoko, na mchira utali uwo ukovwira pakusinthasintha apo chikuthamanga. Chikuvwara mawanga ghakufipa pa thupi lose, ndipo chikuŵa na mizere yakufipa kufuma pafupi na maso kuya ku mulomo.
Mizere iyi yikuwoneka nga ni misozi ndipo yikupangiska kuti chinyama ichi chimanyikwe luŵiro. Cheetah chili na maso ghakuwona makora ndipo chikugwiliskira ntchito mawanga gha thupi lake kujibisa mu vyakumera.
== Kuthamanga ==
Cheetah chili na thupi ilo likovwira kuti chithamange luŵiro. Chingafika pa liŵiro lakujumpha makilomita 100 pa ora, kweni chingasunga liŵiro ili kwa nyengo yichoko waka na pa mtunda wambura kutali.
Mwakuyana na Smithsonian National Zoo, pa liŵiro lake likuru cheetah chingajumpha mamita 7 pa sitepu yimoza ndipo chingachita masitepu pafupifupi ghanayi pa sekondi. Liŵiro ili ndilo likuchipangiska kuŵa chinyama chakuthamanga chomene pa mtunda.<ref>Smithsonian's National Zoo and Conservation Biology Institute, “Cheetah”, https://nationalzoo.si.edu/animals/cheetah (likawelerapo pa 9 Novembala 2026).</ref>
== Chakurya ==
Cheetah chikurya vinyama vichoko na vya pakati, ndipo chikukhala chomene mu malo agho muli vyakumera vyakujandawuka. Chikugwiliskira ntchito maso ghake kuti chiwone ivyo vikuchitika pafupi, ndipo chikuthamanga mwaluŵiro para chikuŵa kuti chikusaka chakurya.
Cheetah kanandi chikuchita ntchito zake zuŵa penepara, chomenechomene m'mawa na mise. Ichi chikupambana na mitundu yinyake ya mphaka iyo kanandi yikuchita ntchito zake usiku.
== Malo agho chikukhala ==
Cheetah chikukhala chomene mu Africa, mu malo nga ni madambo, malo gha vyakumera vyakujandawuka na mu madera ghanyake ghakupulikikwa. Mu nyengo zakale, chikapelekeka mu vigaŵa vinandi vya Africa na Asia, kweni malo agho chikukhala ghasintha chomene chifukwa cha kutaya malo ghake na vinthu vinyake.
Cheetah cha ku Asia chikusangika mu Iran, ndipo ni chichoko chomene kulinganizga na vyakale ivyo vikakhalanga mu vigaŵa vinandi vya Asia.
== Kuswana na ŵana ==
Cheetah zanakazi zikubaba ŵana, ndipo zikupwelelera ŵana awo ŵakukhumbikwira kuŵa pafupi na amama ŵawo mpaka apo ŵakukulira na kwamba kujipenjera chakurya. Ŵana ŵa cheetah ŵakuŵa na mawanga ghakufipa ndipo ŵanyake ŵakuŵa na nthenga zakuŵa nga ni mphonje pa msana, izo zikovwira kuti ŵabise mu vyakumera.
== Kuŵikapo mtima pa kuvikilira ==
Cheetah zikukumana na masuzgo nga ni kutaya malo agho zikukhala, kuchepa kwa vyakurya vyawo na kukumana na ŵanthu awo ŵakukura mu malo agho zikukhala. Kuvikilira malo ghawo na kusunga nyama zakuthengo nkhwakuzirwa kuti mitundu iyi yilutilire kuŵapo.
== Vithuzithuzi ==
<gallery>
File:Acinonyx jubatus (1).jpg|Cheetah.
File:Acinonyx jubatus (2).jpg|Cheetah yikuwoneka kufupi.
File:Cheetah (Acinonyx jubatus).jpg|Cheetah mu malo ghakukhala vyamoyo vya kuthengo.
File:Acinonyx jubatus -Southern Namibia-8.jpg|Cheetah ku Namibia.
File:Acinonyx jubatus jubatus range IUCN 2015.png|Mapu gha malo agho mtundu wa cheetah uyu ukusangikamo.
</gallery>
== Wonaniso ==
* [[Mphaka]]
* [[Vinyama vya mu Africa]]
* [[Vyamoyo vya kuthengo]]
* [[Malaŵi]]
== Ukaboni ==
<references />
[[Category:Vinyama vya mu Africa]]
[[Category:Felidae]]
[[Category:Vyamoyo vya kuthengo]]
nvl4hbx7mfvedjnwwv7si7o63m7rqhg
Baobab
0
50330
124246
2026-11-09T20:39:32Z
Tumbuka Arch
6863
Created page with "{{Short description|Khuni likuru la mu Africa ilo lili na chitamba chakutuna}} [[File:Baobab Adansonia digitata.jpg|thumb|250px|Khuni la baobab (Adansonia digitata).]] '''Baobab''' ni mtundu wa khuni ilo likumera chomene mu Africa. Zina lake la sayansi la mtundu wakumanyikwa chomene ni ''Adansonia digitata''. Khuni ili likumanyikwa chifukwa cha chitamba chake chikuru na chakutuna, nthambi zake izo kanandi zikuwoneka nga ni misisi, na vipambi ivyo vili na vyakurya. Likuku..."
124246
wikitext
text/x-wiki
{{Short description|Khuni likuru la mu Africa ilo lili na chitamba chakutuna}}
[[File:Baobab Adansonia digitata.jpg|thumb|250px|Khuni la baobab (Adansonia digitata).]]
'''Baobab''' ni mtundu wa khuni ilo likumera chomene mu Africa. Zina lake la sayansi la mtundu wakumanyikwa chomene ni ''Adansonia digitata''. Khuni ili likumanyikwa chifukwa cha chitamba chake chikuru na chakutuna, nthambi zake izo kanandi zikuwoneka nga ni misisi, na vipambi ivyo vili na vyakurya. Likukula mu malo ghakotcha na ghanyake agho ghakuŵa na nyengo ya vula na ya chihanya.<ref>Kew Science, “Adansonia digitata L.”, Plants of the World Online, https://powo.science.kew.org/taxon/558628-1 (likawelerapo pa 9 Novembala 2026).</ref>
== Umo likuwonekera ==
Baobab likuŵa na chitamba chikuru chomene icho chingasunga maji. Khuni ili lingafika pa utali wakujumpha mamita 20, ndipo chitamba chake chingaŵa chakufipiskika chomene kuyana na msinkhu wake na malo agho likumera.
Nthambi zake zikuru zikujandawuka kufuma pa chitamba ndipo kanandi zikuwoneka nga ni misisi iyo yili kukwezeka. Apo nyengo ya chihanya yikufika, khuni ili lingathiska mahamba ghake. Mahamba ghake ghakuŵa na vigawo vinandi ivyo vikusangika pamoza pa phesi limoza.
== Malo agho likumera ==
Baobab likumera mu vyaru vinandi vya mu Africa, kusazgapo [[Malaŵi]], [[Zambia]], [[Mozambique]], [[Zimbabwe]], [[Tanzania]], [[Botswana]] na vyaru vinyake vya ku Africa. Likusangikasofiso ku chigaŵa cha Arabian Peninsula.
Likukura makora mu malo ghakotcha agho ghali na nyengo zakupambana za vula na chihanya. Chitamba chake chakutuna chikovwira kusunga maji agho khuni likugwiliskira ntchito pa nyengo ya chihanya.<ref>Kew Science, “Adansonia digitata L.”, Plants of the World Online, https://powo.science.kew.org/taxon/558628-1 (likawelerapo pa 9 Novembala 2026).</ref>
== Maluŵa na vipambi ==
Baobab likupanga maluŵa ghakuru agho kanandi ghakuŵa ghatuŵa. Maluŵa agha ghakujandawuka pa nthambi, ndipo mu mitundu yakumanyikwa chomene ghakupokera wovwiri wa vyamoyo nga ni mavuwu pakusazga pollen.
Vipambi vyake vikuŵa vyakukoma, vikukoleka na chigoba chakukhora, ndipo mukati muli vinthu vyatuŵa vya ufa, masumbi na vipande vinyake. Chigaŵa chakuryeka cha chipambi ichi chili na vyakurya ivyo ŵanthu ŵanyake ŵakugwiliskira ntchito pakupanga vyakurya na vyakumwa.
== Ntchito zake kwa ŵanthu ==
Baobab ni khuni lakuzirwa mu umoyo wa ŵanthu ŵanandi ŵa mu Africa. Vipambi vyake vingaryeka, mahamba ghake ghakugwiliskirika ntchito mu vyakurya, ndipo vigaŵa vinyake vya khuni vingagwiliskirika ntchito pa vinthu vya zuŵa na zuŵa.
Mu vigaŵa vinyake ŵanthu ŵakugwiliskira ntchito chitamba chake chakutuna nga ni malo ghakubisamamo panji malo ghakupumulirako. Khuni ili lili na ntchito za pa chikaya, pa chuma na pa mitheto ya ŵanthu.
== Msinkhu na kuvikilirika ==
Baobab lingaŵa na umoyo wa vyaka vinandi chomene. Kafukufuku wa sayansi wa vyakumera wakulongora kuti khuni linyake la mtundu uwu ilo likasangika ku Namibia likaŵa na msinkhu wa pafupifupi vyaka 1,275. Kweni si baobab lose ilo likukhalako nyengo yakuyana; msinkhu wake ukusiyana kuyana na malo na umo liliri.
Kuvikilirika kwa makuni agha nkhwakuzirwa chifukwa ghakovwira vyamoyo vinyake, ndipo ghali na ntchito zikuru pa umoyo wa ŵanthu awo ŵakukhala mu vigaŵa ivyo ghakumeramo.
== Vithuzithuzi ==
<gallery>
File:Baobab Adansonia digitata.jpg|Baobab mu Africa.
File:Adansonia digitata.jpg|Khuni la baobab ku Namibia.
File:Adansonia digitata arbre MHNT.jpg|Baobab ku Botswana.
File:Baobob tree.jpg|Baobab likuwoneka kufuma pa pasi.
</gallery>
== Wonaniso ==
* [[Makuni]]
* [[Malaŵi]]
* [[Africa]]
* [[Vyakumera]]
* [[Vipambi]]
== Ukaboni ==
<references />
[[Category:Makuni]]
[[Category:Vyakumera vya mu Africa]]
[[Category:Malvaceae]]
[[Category:Vyakumera vya ku Malaŵi]]
dre6fs89gpg4vt4tykhxea9x4dda8tq
Chiyuni cha hummingbird
0
50331
124247
2026-11-09T20:40:04Z
Tumbuka Arch
6863
Created page with "{{Short description|Chiyuni zichoko icho chingayima mu mlengalenga apo chikuŵa chikupapira mapapiko}} [[File:Colibri en vol 2.jpg|thumb|250px|Hummingbird iyo yikupapira pafupi na maluŵa.]] '''Chiyuni cha hummingbird''' ni chiyuni chichoko chomene icho chikusangika mu [[North America|Charu cha ku North America]] na [[South America|Charu cha ku South America]]. Viyuni ivi vili mu mbumba ya ''Trochilidae''. Vikumanyikwa chifukwa cha ukuru wawo uchoko, milomo yitali, mitun..."
124247
wikitext
text/x-wiki
{{Short description|Chiyuni zichoko icho chingayima mu mlengalenga apo chikuŵa chikupapira mapapiko}}
[[File:Colibri en vol 2.jpg|thumb|250px|Hummingbird iyo yikupapira pafupi na maluŵa.]]
'''Chiyuni cha hummingbird''' ni chiyuni chichoko chomene icho chikusangika mu [[North America|Charu cha ku North America]] na [[South America|Charu cha ku South America]]. Viyuni ivi vili mu mbumba ya ''Trochilidae''. Vikumanyikwa chifukwa cha ukuru wawo uchoko, milomo yitali, mitundu yakutowa ya nthenga, na umo vingayimiskira thupi mu mlengalenga apo vikuŵa kuti vikupapira mapapiko.<ref>Smithsonian's National Zoo, “Hummingbirds”, https://nationalzoo.si.edu/migratory-birds/hummingbirds (likawelerapo pa 9 Novembala 2026).</ref>
== Umo thupi lake liliri ==
Hummingbird ni chimoza mwa viyuni vichoko chomene pa charu. Ukuru wake ukusiyana kuyana na mtundu wake. Vili na milomo yitali iyo yikovwira kufika mu maluŵa kuti vimwe uchi wa maluŵa. Malilime ghawo ghali na kawonekero ako kakovwira kusonkha uchi wa maluŵa.
Nthenga za hummingbird zingawoneka za mitundu yakupambanapambana, kusazgapo green, blue, red na violet. Mtundu uwo munthu wakuwona ungasintha kuyana na umo ungweru ukukwera pa nthenga.
== Kupapira ==
Chimoza mwa vinthu vyakuzizwiska vya hummingbird nkhupapira kwake. Vingayima pa malo ghamoza mu mlengalenga apo mapapiko ghikupapira mwaluŵiro. Vingawerera kumanyuma ndipo vinyake vingasinthira thupi na kwenda mu nthowa zakupambanapambana.
Smithsonian National Zoo yikulongosora kuti hummingbird ni gulu la viyuni ilo ndilo pekha pakati pa vyamoyo vya msana ilo lingayima mu mlengalenga kwa nyengo yitali apo likupapira. Vingapapira mapapiko mwaluŵiro chomene ndipo vikukhumbikwira nkhongono zinandi.<ref>Smithsonian's National Zoo, “Hummingbirds”, https://nationalzoo.si.edu/migratory-birds/hummingbirds (likawelerapo pa 9 Novembala 2026).</ref>
== Chakurya ==
Hummingbird zinandi zikulyera uchi uwo ukusangika mu maluŵa. Milomo yawo yitali na lilime vikovwira kutora uchi uwu. Apo zikuluta ku maluŵa, zingatora fumbi la maluŵa (pollen) na kulipeleka ku maluŵa ghanyake, ntheura zikovwira kuti vyakumera viswane.
Kweniso zikurya tuminyama tuchoko, kusazgapo tizumizi na tunyama tunyake twakupapira, chomenechomene pa nyengo iyo zikupwelelera ŵana.
== Malo agho vikukhala ==
Hummingbird zikusangika mu malo ghakupambanapambana mu America, kusazgapo mu mapiri, mu nkhorongo, mu minda na mu malo agho muli maluŵa ghanandi. Mitundu yinyake yikukhala mu malo ghakuzizima, ndipo yinyake mu malo ghakotcha gha mu vyaru vya ku tropiki.
== Kuswana ==
Hummingbird zanakazi zikupanga viwangwa vichoko vya chizuzula cha viyuni, ndipo vikugwiliskira ntchito vinthu vyakufuma ku vyakumera na ulusi wa kangaude. Kanandi vikuyikira masumbi ghaŵiri. Pa mitundu yinandi, mwanakazi ndiyo wakulera ŵana pambere ŵandafike pakujiyimira paŵekha.
== Vithuzithuzi ==
<gallery>
File:Colibri en vol 2.jpg|Hummingbird yikupapira mu mlengalenga.
File:Amazilia saucerrottei (Medellin, Colombia).jpg|Amazilia saucerrottei.
File:Anna's Hummingbird Vancouver Island.jpg|Anna's hummingbird.
File:Colibri en vol 3.jpg|Hummingbird apo yikupapira.
File:Colibríes 2.JPG|Hummingbird izo zili pafupi na maluŵa.
</gallery>
== Wonaniso ==
* [[Viyuni]]
* [[Maluŵa]]
* [[Vyamoyo]]
* [[Kuswana kwa viyuni]]
== Ukaboni ==
<references />
[[Category:Viyuni]]
[[Category:Vyamoyo vya ku America]]
[[Category:Trochilidae]]
sp45cir2cnwp377c5dwmq5p4r0zy168
Phiri la Everest
0
50332
124248
2026-11-09T20:40:30Z
Tumbuka Arch
6863
Created page with "{{Short description|Phiri litali chomene pa charu chapasi}} [[File:Mount-Everest.jpg|thumb|250px|Phiri la Everest likuwoneka kufuma ku chigaŵa cha Tibet.]] '''Phiri la Everest''' ni phiri litali chomene pa charu chapasi kuyana na utali kufuma pa usange wa nyanja. Phiri ili lili mu mapiri gha [[Himalaya]], pa mphaka pakati pa [[Nepal]] na chigaŵa cha Tibet icho chili pasi pa [[China]]. Utali wake ukupimika pafupifupi mamita 8,849 kufuma pa usange wa nyanja.<ref>National..."
124248
wikitext
text/x-wiki
{{Short description|Phiri litali chomene pa charu chapasi}}
[[File:Mount-Everest.jpg|thumb|250px|Phiri la Everest likuwoneka kufuma ku chigaŵa cha Tibet.]]
'''Phiri la Everest''' ni phiri litali chomene pa charu chapasi kuyana na utali kufuma pa usange wa nyanja. Phiri ili lili mu mapiri gha [[Himalaya]], pa mphaka pakati pa [[Nepal]] na chigaŵa cha Tibet icho chili pasi pa [[China]]. Utali wake ukupimika pafupifupi mamita 8,849 kufuma pa usange wa nyanja.<ref>National Geographic, “Mount Everest”, https://education.nationalgeographic.org/resource/mount-everest/ (likawelerapo pa 9 Novembala 2026).</ref>
Mu chiyowoyero cha ku Nepal phiri ili likumanyikwa kuti ''Sagarmatha'', ndipo mu Chitibeti likumanyikwa kuti ''Chomolungma''. Zina lakuti Everest likaperekeka chifukwa cha George Everest, uyo wakateŵeteranga pa ntchito yakupima malo mu India mu vyaka vya m'ma 1800.
== Malo agho lili ==
Everest lili mu chigaŵa cha Mahalangur Himal, mu mapiri gha Himalaya. Malo agha ghali na mathanthwe, chipale chofeŵa, madzi ghakuzizima na mazaya gha mu mapiri. Chifukwa cha utali wake, mphepo na nyengo yake vikupambana chomene na ivyo vikusangika mu malo gha pasi.
Kuzingilizga phiri ili kuli mapiri ghanyake ghatali, madambo gha mazaya, na malo agho ŵanthu ŵa mu chigaŵa ichi ŵakukhala. Ŵanthu ŵa mtundu wa Sherpa ŵali na mbiri yitali ya kukhala mu chigaŵa cha Himalaya na kovwira ŵanthu awo ŵakuluta kukwera mapiri.
== Zina na kupima utali ==
Mu vyaka vya m'ma 1800, ŵanthu awo ŵakapimanga malo ŵakamba kupima phiri ili na kulisanga kuti ndilo litali chomene pa charu chapasi. Mu 1856, ŵakapharazga kuti phiri ilo pa nyengo iyo likachemekanga Peak XV ndilo likaŵa litali chomene kuluska mapiri ghanyake agho ŵakagaŵa mu ndondomeko yawo ya kupima malo.
Utali wa Everest wapimika mwakupambanapambana mu nyengo zakupambana. Mu 2020, Nepal na China zikapharazga limoza kuti utali wake ni mamita 8,848.86.
== Ŵanthu ŵakwamba kukwera mpaka pachanya ==
Pa 29 Meyi 1953, Edmund Hillary wa ku New Zealand na Tenzing Norgay, munthu wa mtundu wa Sherpa, ŵakafika pa pachanya pa phiri ili. Iwo ndiwo ŵakumanyikwa kuti ŵanthu ŵakwamba awo ŵakafika pa pachanya pa Everest na kulembeka mu mbiri ya maulendo ghakukwera mapiri.<ref>Guinness World Records, “First ascent of Everest”, https://www.guinnessworldrecords.com/world-records/first-ascent-of-mount-everest (likawelerapo pa 9 Novembala 2026).</ref>
Kufika pachanya pa phiri ili nkhwakusuzga chifukwa mphepo yikuŵa yichoko, kuzizima kukuru, ndipo malo ghanyake ghali na mathanthwe na mazaya. Ŵanthu awo ŵakukwera ŵakwenera kunozgekera mwapadera ndipo ŵakukumana na masuzgo ghakuru gha nyengo.
== Umoyo wa vyamoyo na chilengiwa ==
Mu malo ghapasi gha Everest muli vyakumera na vinyama ivyo vingakhalako mu nyengo yakuzizima. Kweni apo munthu wakukwera kufika pachanya, vyakumera vikupungulika ndipo mphepo yikuŵa yichoko chomene.
Malo agha ghali na vyakumera na vyamoyo vya mu mapiri gha Himalaya. Chifukwa cha kusintha kwa nyengo na maulendo gha ŵalendo, ŵakusambira vya chilengiwa ŵakuwoneseska umo malo agha ghakukhwaskikira na vinthu ivyo ŵanthu ŵakuchita.
== Ulendo wa ŵalendo ==
Everest ni malo agho ŵanthu ŵanandi ŵakukhumba kukawonapo panji kukwera. Ŵalendo ŵakuluta ku malo gha ku Nepal na ku Tibet kuti ŵawone phiri ili. Kweni kukwera mpaka pachanya ni ntchito yakusuzga chomene, ndipo ŵanthu ŵanandi ŵakukondwa waka kuluta ku malo ghakuwonera phiri ili kwambura kukwera mpaka pachanya.
== Vithuzithuzi ==
<gallery>
File:Mount-Everest.jpg|Everest likuwoneka kufuma ku Tibet.
File:Mount everest.jpg|Everest kufuma ku malo ghakukwelera.
File:Mount Everest, Himalayas.jpg|Everest mu mapiri gha Himalaya.
File:Mount Everest scene.jpg|Phiri la Everest na malo agho ghali kuli.
</gallery>
== Wonaniso ==
* [[Himalaya]]
* [[Nepal]]
* [[Tibet]]
* [[China]]
* [[Mapiri]]
== Ukaboni ==
<references />
[[Category:Mapiri gha Himalaya]]
[[Category:Mapiri gha ku Nepal]]
[[Category:Mapiri gha ku China]]
62c1py16a6rs0zg778okjeo1ntk0p4k
Octopus
0
50333
124249
2026-11-09T20:40:59Z
Tumbuka Arch
6863
Created page with "{{Short description|Chinyama cha mu nyanja icho chili na mawoko 8}} [[File:Octopus Vulgaris.jpg|thumb|250px|Octopus vulgaris, mtundu umoza wa octopus.]] '''Octopus''' ni chinyama cha mu nyanja icho chili mu gulu la vyamoyo vyakuzirwa ivyo vili na mawoko ghanandi, ndipo chikuŵa mu gulu la ''Cephalopoda''. Chili na mawoko 8 agho ghali na vimakapu vyakukamira. Octopus zilije viwangwa vikuru vya mu thupi, ntheura zingaŵa na thupi lakulowoloka mu malo ghatheghathegha.<ref>S..."
124249
wikitext
text/x-wiki
{{Short description|Chinyama cha mu nyanja icho chili na mawoko 8}}
[[File:Octopus Vulgaris.jpg|thumb|250px|Octopus vulgaris, mtundu umoza wa octopus.]]
'''Octopus''' ni chinyama cha mu nyanja icho chili mu gulu la vyamoyo vyakuzirwa ivyo vili na mawoko ghanandi, ndipo chikuŵa mu gulu la ''Cephalopoda''. Chili na mawoko 8 agho ghali na vimakapu vyakukamira. Octopus zilije viwangwa vikuru vya mu thupi, ntheura zingaŵa na thupi lakulowoloka mu malo ghatheghathegha.<ref>Smithsonian Ocean, “Cephalopods: Octopus, Squid, Cuttlefish, and Nautilus”, https://ocean.si.edu/ocean-life/invertebrates/octopuses-squids-and-relatives (likawelerapo pa 9 Novembala 2026).</ref>
Octopus zikusangika mu nyanja zakupambanapambana pa charu chose. Mitundu yake yikusiyana pa ukuru, mtundu, umo yikukhalira na malo agho yikusangikamo.
== Umo thupi lake liliri ==
Thupi la octopus lili na mutu, maso ghaŵiri, chikwama cha thupi icho chili na viŵaro vyakuzirwa vya mkati, na mawoko 8. Mawoko agha ghalikuzura vimakapu ivyo vikovwira kukamira pa vinthu, kugwira chakurya na kusamuka.
Octopus zilije chigoba chakuwonekera kuwaro nga umo viliri na vyamoyo vinyake vya mu nyanja. Chifukwa cha ichi, zingalowoka mu tumanjoka na mu malo ghanyake ghakubisamamo agho vingamanyikwa kuti ni madoko ghawo.
== Umo zikukhalira ==
Mitundu yinandi ya octopus yikukhala pasi pa nyanja. Yikubisama mu vimayala, mu mphako za malibwe panji mu malo ghanyake ghakubisamamo. Mitundu yinandi yikukhumba kukhala yeka, nangauli pali mitundu iyo yikusangika pamoza na yinyake mu malo ghamoza.
Octopus zinandi zikurya nkhanu, nkhonyo, somba zichoko na vyamoyo vinyake vya mu nyanja. Zikugwiliskira ntchito mawoko ghake kugwira chakurya na kuchisazgula.
== Uchenjeri na kujibisa ==
Octopus zikumanyikwa chifukwa cha uchenjeri wawo. Zingasambira umo zingazugulira vinthu vyakusuzga, kupeza nthowa zakufumira mu malo agho zili kukakikamo, na kumanya malo agho zikukhalamo.
Zinyake zingasintha mtundu na kawonekero ka khumba lawo kuti zifanane na malo agho zili. Masinthiro agha ghakuzomerezga kuti zibisame ku vyamoyo ivyo vingazikoma panji kuti zibhisame apo zikupenja chakurya. Masinthiro gha mtundu ghakuchitika chifukwa cha maselo gha mu khumba agho ghali na mitundu yakupambanapambana.<ref>Smithsonian Ocean, “How Octopuses and Squids Change Color”, https://ocean.si.edu/ocean-life/invertebrates/how-octopuses-and-squids-change-color (likawelerapo pa 9 Novembala 2026).</ref>
== Kuwanda ==
Octopus zikuswana kwizira mu kubapatana kwa mwanalume na mwanakazi. Mwanakazi wakuyikira masumbi, ndipo mu mitundu yinandi wakughaghasunga na kughalinda mpaka apo ghakufumira. Umo masumbi ghakukulira na nyengo iyo octopus yikumalira na umoyo vikusiyana kuyana na mtundu wake.
== Mitundu ya octopus ==
Pali mitundu yinandi ya octopus. Yimoza yakumanyikwa chomene ni ''Octopus vulgaris'', iyo yikusangika mu nyanja ya Atlantic na mu vigaŵa vinyake vya nyanja ya Mediterranean. Pali mitundu yinyake iyo yikukhala mu maji ghakuzika chomene, ndipo yinyake yikusangika mu maji ghapafupi na mphepete mwa nyanja.
== Vithuzithuzi ==
<gallery>
File:Octopus Vulgaris.jpg|Octopus vulgaris.
File:Octopus vulgaris 01 by-dpc.jpg|Octopus mu maji.
File:Common octopus (Octopus vulgaris), Pedra de Deu, Medes Islands, Spain.jpg|Octopus mu nyanja ya ku Spain.
File:Octopus vulgaris close up.jpg|Kuwoneka kwa thupi la octopus pafupi.
File:Babyoctopus.jpg|Octopus yichoko.
</gallery>
== Wonaniso ==
* [[Vyamoyo vya mu nyanja]]
* [[Nkhanu]]
* [[Somba]]
* [[Nyanja]]
== Ukaboni ==
<references />
[[Category:Octopus]]
[[Category:Vyamoyo vya mu nyanja]]
[[Category:Cephalopoda]]
55w103wocfbbklgcko2ctp05j16ctr2
Khoma Likuru la China
0
50334
124250
2026-11-09T20:42:08Z
Tumbuka Arch
6863
Redirected page to [[Chiliŵa chikulu cha China]]
124250
wikitext
text/x-wiki
#REDIRECT [[Chiliŵa chikulu cha China]]
jjt93vomfwojkxr3bjcuhkiy58brypt
Mphalizgano ukuru wa Ŵana wa Toronto
0
50335
124251
2026-11-09T20:42:53Z
Tumbuka Arch
6863
Created page with "{{Short description|Mphalizgano wa Khisimasi wa ku Toronto, Canada}} [[File:Santa Claus Parade Toronto 2009 (2).jpg|thumb|250px|Santa Claus pa Mphalizgano wa ku Toronto.]] '''Mphalizgano ukuru wa Ŵana wa Toronto''' ni mphalizgano wa pa chaka wa nyengo ya Khisimasi uwo ukuchitikira mu msumba wa [[Toronto]], ku [[Canada]]. Mu Chingelezi ukuchemeka ''Toronto Santa Claus Parade''. Pa mphalizgano uwu, Santa Claus wakulongozga gulu la ŵanthu awo ŵakwenda mu misewu, magulu g..."
124251
wikitext
text/x-wiki
{{Short description|Mphalizgano wa Khisimasi wa ku Toronto, Canada}}
[[File:Santa Claus Parade Toronto 2009 (2).jpg|thumb|250px|Santa Claus pa Mphalizgano wa ku Toronto.]]
'''Mphalizgano ukuru wa Ŵana wa Toronto''' ni mphalizgano wa pa chaka wa nyengo ya Khisimasi uwo ukuchitikira mu msumba wa [[Toronto]], ku [[Canada]]. Mu Chingelezi ukuchemeka ''Toronto Santa Claus Parade''. Pa mphalizgano uwu, Santa Claus wakulongozga gulu la ŵanthu awo ŵakwenda mu misewu, magulu gha sumu, ŵanthu awo ŵavwara vyakuvwara vyakusekeska, na magalimoto ghakutowa agho ghakupangika mwapadera.
Mphalizgano uwu ngumoza mwa yakale chomene pa mtundu uwu wa vyakuchitika, ndipo wakopa ŵana na ŵalara kufuma ku Toronto na ku malo ghanyake. Kanandi ŵanthu ŵanandi ŵakuwonelera pa misewu, ndipo ŵanji ŵakuwonelera pa wayilesi ya kanema.
== Kwamba kwa mphalizgano ==
Mbiri ya mphalizgano uwu yikamba mu 1904, apo Santa Claus wakafika pa siteshoni ya masitima gha pa njanji ya Union Station ku Toronto ndipo wakenda na ŵanthu ŵa banja la Eaton kuluta ku sitolo yawo. Ichi chikaŵa chigaŵa cha ntchito yakupharazga sitolo ya Eaton's.
Mphalizgano wakwamba uwo ukachitika nga ni parade yakujiyimira pawekha ukachitika pa 2 Disembala 1905. Ukanozgeka na sitolo ya Eaton's, ndipo Santa Claus wakatoleka pa galimoto yimoza yakukwezgera vinthu kufuma ku Union Station kuya ku sitolo ya Eaton's mu tawuni ya Toronto. Mu vyaka vyakulondezgapo, mphalizgano ukakura ndipo ukaŵa na ŵanthu ŵanandi, magalimoto ghakupangika mwaluso na magulu gha sumu.<ref>''The Original Santa Claus Parade'', “History”, https://www.thesantaclausparade.com/history (likawelerapo pa 9 Novembala 2026).</ref>
== Kukura kwa mphalizgano ==
Mu 1913, ŵanthu awo ŵakanozganga mphalizgano ŵakiza na mphoyo za mphalizgano za Santa Claus, ndipo Santa wakakwera pa galimoto yakukwezgekera na mphoyo izi. Mu 1917, mphalizgano ukaŵa kale na magalimoto ghakupangika mwapadera agho ghakaŵa na ŵanthu ŵakuvwara nga ni ŵanthu ŵa mu nthano za ŵana.
Mu 1919, Santa Claus wakafika ku Toronto pa ndege. Mu 1952, mphalizgano uwu ukayamba kuwoneskeka pa wayilesi ya kanema ya CBC, ndipo ŵanthu ŵanandi awo ŵakakhalanga kutali na Toronto ŵakamba kuwuwonelera.
Sitolo ya Eaton's yikalutilira kunozga mphalizgano uwu mpaka mu 1982, apo yikafumamo pa ntchito iyi. Pamanyuma pake, gulu la ŵanthu awo ŵakajipeleka na awo ŵakakolerananga na mphalizgano likawovwira kuti uleke kumara.<ref>Radio Canada International, “History: Dec 02, 1904—longest running children’s parade begins in Toronto”, https://www.rcinet.ca/en/2015/12/02/history-dec-02-1904-longest-running-childrens-parade-begins-in-toronto/ (likawelerapo pa 9 Novembala 2026).</ref>
== Ivyo vikuchitika pa mphalizgano ==
Mphalizgano wa mazuŵa ghano kanandi ukuŵa na:
* Magalimoto ghakutowa agho ghakupangika mwapadera.
* Santa Claus na ŵanthu ŵanyake ŵa mu nkhani za Khisimasi.
* Magulu gha sumu agho ghakwenda uku ghakuŵa na sumu.
* Ŵanthu awo ŵavwara vyakuvwara vya ŵanthu ŵa mu nthano na vinyama.
* Ŵana na ŵanthu ŵalara awo ŵakutora nawo chigaŵa.
* Ŵanthu ŵanandi awo ŵakuwonelera mumphepete mwa msewu.
Mphalizgano uwu kanandi ukuchitika pambere zuŵa la Khisimasi lindafike, ndipo ukuŵa chigaŵa cha kukumbukira nyengo ya Khisimasi mu Toronto.
== Kufunika kwake ==
Mphalizgano uwu ngwakuzirwa pa mitheto ya ku Toronto chifukwa wawunganiska mbumba, ŵana, ŵanthu ŵakujipereka na ŵalendo. Wawovwiraso kupanga mbiri ya vyakuchitika vya pa Khisimasi mu Canada. Chifukwa cha kuwoneskeka kwake pa wayilesi ya kanema, ŵanthu ŵa mu vyaru vinyake nawo ŵakumanya za mphalizgano uwu.
== Vithuzithuzi ==
<gallery>
File:1918eatonssantaclausparade.jpg|Santa Claus pa mphalizgano wa mu 1918.
File:Eaton's Santa Claus Parade (10966948984).jpg|Mphalizgano wa Santa Claus.
File:Eaton's Santa Claus Parade, Mother Goose (10967017103).jpg|Galimoto yakupangika mwapadera ya Mother Goose.
File:Eatons Parade, Santa on platform at store (10966763045).jpg|Santa Claus pa malo ghakukwezgekera pa sitolo ya Eaton's.
File:Santa Claus Parade Toronto 2009 (2).jpg|Mphalizgano wa mu 2009.
File:Santa Claus Parade- Mounted Police.jpg|Ŵapolisi ŵakwenda pa mahachi pa mphalizgano.
</gallery>
== Wonaniso ==
* [[Toronto]]
* [[Canada]]
* [[Khisimasi]]
* [[Santa Claus]]
== Ukaboni ==
<references />
[[Category:Vyakuchitika mu Canada]]
[[Category:Toronto]]
[[Category:Mbiri ya Canada]]
rnhoj00khuwqb7v95fs4wxiud1nq3ik
Maseŵera gha Olimpiki gha 1964
0
50336
124252
2026-11-09T20:43:44Z
Tumbuka Arch
6863
Created page with "{{Short description|Maseŵera gha Olimpiki agho ghakachitikira ku Tokyo mu 1964}} [[File:TokyoOlympics1964Opening.jpg|thumb|250px|Mwambo wa kujura Maseŵera gha Olimpiki gha 1964 ku Tokyo pa 10 Okutobala 1964.]] '''Maseŵera gha Olimpiki gha 1964''' ghakaŵa maseŵera gha Olimpiki gha chihanya agho ghakachitikira ku [[Tokyo]], [[Japan]], kwamba pa 10 mpaka 24 Okutobala 1964. Iyi yikaŵa nyengo yakwamba kuti maseŵera gha Olimpiki gha chihanya ghachitikirenge mu charu cha..."
124252
wikitext
text/x-wiki
{{Short description|Maseŵera gha Olimpiki agho ghakachitikira ku Tokyo mu 1964}}
[[File:TokyoOlympics1964Opening.jpg|thumb|250px|Mwambo wa kujura Maseŵera gha Olimpiki gha 1964 ku Tokyo pa 10 Okutobala 1964.]]
'''Maseŵera gha Olimpiki gha 1964''' ghakaŵa maseŵera gha Olimpiki gha chihanya agho ghakachitikira ku [[Tokyo]], [[Japan]], kwamba pa 10 mpaka 24 Okutobala 1964. Iyi yikaŵa nyengo yakwamba kuti maseŵera gha Olimpiki gha chihanya ghachitikirenge mu charu cha ku Asia. Ghakaŵa maseŵera gha nambara 18 kufuma apo maseŵera agha ghakambira mu 1896.<ref>{{Cite web |url=https://www.joc.or.jp/english/historyjapan/tokyo1964.html |title=Tokyo 1964 Olympic Games |publisher=Japanese Olympic Committee |access-date=9 November 2026}}</ref>
== Kukonzekera maseŵera ==
Tokyo yikasankhika kuti yichite maseŵera agha mu 1959. Japan yikagwiliskira ntchito maseŵera agha kulongora kuti yikawelera ku umoyo wakukhazikika pamanyuma pa kuparanyika kwa Nkhondo Yachiŵiri ya Charu Chose.
Boma na ŵanthu ŵa ku Japan ŵakazenga na kunozga malo gha maseŵero, misewu, nyumba za ŵanthu awo ŵakiza ku maseŵera, na vinthu vinyake vyakukhumbikwa. Maseŵera agha ghakawovwira kuti Tokyo yinozgeke makora kuwona ŵalendo na kuchitira vyakuchitika vikuru.
== Maseŵera agha ==
Maseŵera ghakachitika pakati pa 10 na 24 Okutobala 1964. Ŵanthu ŵakukwana 5,151 awo ŵakachitanga maseŵero, kufuma mu vyaru na vigaŵa 93, ŵakanjira mu maseŵero agha. Pakachitika maseŵero 163 mu mitundu 20 ya maseŵero.
Vinthu vinyake ivyo vikachitika ni ivi:
* Kuthamanga na maseŵero ghanyake gha pa malo ghakuthamangirako.
* Kusambira.
* Maseŵero gha mpira.
* Maseŵero gha volleyball.
* Maseŵero gha judo.
* Maseŵero gha gymnastics.
* Maseŵero gha nkhonya na kulimbana.
Judo na volleyball vikaŵa pakati pa mitundu ya maseŵero agho ghakanjira mu Olimpiki kakwamba pa maseŵera agha.<ref>{{Cite web |url=https://www.joc.or.jp/english/historyjapan/tokyo1964.html |title=Tokyo 1964 Olympic Games |publisher=Japanese Olympic Committee |access-date=9 November 2026}}</ref>
== Mwambo wa kujura ==
Mwambo wa kujura maseŵera ukachitika pa 10 Okutobala 1964 ku National Stadium ku Tokyo. Moto wa Olimpiki ukayakika na Yoshinori Sakai, munthu uyo wakababikira ku Hiroshima pa 6 Ogasiti 1945, zuŵa ilo bomba la nyukiliya likaponyekera pa msumba uwu.
Mwambo uwu ukaŵa wakukumbukika chomene chifukwa ukalongoranga kuti Japan yikawelera ku umoyo wakukhazikika pamanyuma pa nkhondo.
== Ŵanthu awo ŵakatora mendulo ==
Japan ndiyo yikaŵa na mendulo zinandi chomene pa maseŵera agha. Yikasanga mendulo 29: zagolide 16, zasiliva 5 na zamkuwa 8. Yikamalizga pa malo ghatatu pa mndandanda wa vyaru kuyana na unandi wa mendulo.
United States na Soviet Union vikaŵa vyaru viŵiri ivyo vikasanga mendulo zinandi kuluska Japan.
== Kukumbukika kwake ==
Maseŵera gha Olimpiki gha 1964 ghakaŵa ghakuzirwa pa mbiri ya Japan na ya maseŵero pa charu chose. Ghakaŵa maseŵera gha Olimpiki gha chihanya ghakwamba kuchitikira ku Asia ndipo ghakawovwira kuti maseŵero gha Olimpiki ghamanyikwe chomene mu chigaŵa ichi.
== Vithuzithuzi ==
<gallery>
File:1964 Summer Olympics medal map.svg|Mapu ghakulongora umo vyaru vikatorera mendulo.
File:A Commemorative Ticket of Tokyo Olympicgames.jpg|Tikiti yakukumbukirako maseŵera gha Olimpiki gha Tokyo.
File:Watch the Tokyo Olympics on the street TV.jpg|Ŵanthu ŵakuwonelera maseŵera gha Olimpiki pa wayilesi ya kanema mu msewu.
File:Yoshinori Sakai 1964.jpg|Yoshinori Sakai, uyo wakayakiska moto wa Olimpiki.
</gallery>
== Wonaniso ==
* [[Maseŵera gha Olimpiki]]
* [[Tokyo]]
* [[Japan]]
* [[Nkhondo Yachiŵiri ya Charu Chose]]
== Ukaboni ==
<references />
[[Category:Maseŵera gha Olimpiki]]
[[Category:1964 mu maseŵero]]
[[Category:Mbiri ya Japan]]
[[Category:Maseŵero mu Japan]]
n41683pl55aspozt21pfdbmeeqaf6rp
Nkhondo Yachiŵiri ya Charu Chose
0
50337
124253
2026-11-09T20:44:05Z
Tumbuka Arch
6863
Created page with "{{Short description|Nkhondo yapacharu chose iyo yikachitika pakati pa 1939 na 1945}} [[File:Invasion of Poland-1939.png|thumb|250px|Mapu ghakulongora kuwukira kwa Poland mu 1939, icho kanandi chikupimika kuti ndicho chikamba Nkhondo Yachiŵiri ya Charu Chose mu Europe.]] '''Nkhondo Yachiŵiri ya Charu Chose''' yikaŵa nkhondo yikuru iyo yikachitika pakati pa 1939 na 1945. Yikakolerana na vyaru vinandi chomene pa charu chose ndipo yikachitika mu Europe, Asia, Africa na mu..."
124253
wikitext
text/x-wiki
{{Short description|Nkhondo yapacharu chose iyo yikachitika pakati pa 1939 na 1945}}
[[File:Invasion of Poland-1939.png|thumb|250px|Mapu ghakulongora kuwukira kwa Poland mu 1939, icho kanandi chikupimika kuti ndicho chikamba Nkhondo Yachiŵiri ya Charu Chose mu Europe.]]
'''Nkhondo Yachiŵiri ya Charu Chose''' yikaŵa nkhondo yikuru iyo yikachitika pakati pa 1939 na 1945. Yikakolerana na vyaru vinandi chomene pa charu chose ndipo yikachitika mu Europe, Asia, Africa na mu nyanja za Pacific na Atlantic. Yikaŵa nkhondo yakofya chomene mu mbiri ya ŵanthu, ndipo ŵanthu ŵakukwana mamiliyoni ghanandi ŵakafwa.<ref>{{Cite web |url=https://www.nam.ac.uk/explore/second-world-war |title=Second World War |publisher=National Army Museum |access-date=9 November 2026}}</ref>
Nkhondo iyi yikaŵa pakati pa magulu ghaŵiri ghakuru: gulu la Allies na gulu la Axis. Nkhondo iyi yikasintha mapu gha charu, maboma, umoyo wa ŵanthu, na ndyali za charu chose.
== Ivyo vikapangiska nkhondo ==
Pambere nkhondo yindambe, vyaru vinandi vikaŵa na masuzgo gha ndyali na chuma. Pamanyuma pa [[Nkhondo Yakwamba ya Charu Chose]], Germany yikakumana na masuzgo ghakuru gha chuma na kukwiya chifukwa cha phangano la Versailles. Mu vyaka vya m'ma 1930, maboma gha nkhongono ghakakura mu Germany, Italy na Japan.
Germany, pasi pa mulongozgi Adolf Hitler, yikakhumbanga kupoka malo ghanyake gha ku Europe. Italy nayo yikakhumbanga kukura kwa ufumu wake, apo Japan yikakhumbanga kupoka malo mu Asia na Pacific.
Japan yikawukira Manchuria mu 1931 ndipo yikamba nkhondo yikuru na China mu 1937. Mu Europe, nkhondo yikuru yikamba pa 1 Seputembala 1939 apo Germany yikawukira Poland. Pamanyuma France na Britain vikapharazga kuti vili mu nkhondo na Germany.<ref>{{Cite web |url=https://encyclopedia.ushmm.org/content/en/article/world-war-ii-key-dates |title=World War II Dates and Timeline |publisher=United States Holocaust Memorial Museum |access-date=9 November 2026}}</ref>
== Magulu gha vyaru ==
=== Gulu la Axis ===
Vyaru vikuru ivyo vikaŵa mu gulu ili ni:
* Germany ya Nazi.
* Italy ya Fascist.
* Ufumu wa Japan.
Vyaru vinyake vikakolerana na gulu ili pa nyengo zakupambanapambana.
=== Gulu la Allies ===
Vyaru vikuru ivyo vikaŵa mu gulu ili ni:
* Britain.
* France.
* Soviet Union.
* United States.
* China.
Vyaru na magulu ghanyake ghanandi ghakakolerananga na Allies pa nyengo ya nkhondo.
== Nkhondo mu Europe ==
Pamanyuma pa kuwukira kwa Poland mu 1939, Germany yikawukira vyaru vinandi vya ku Europe. Mu 1940, Germany yikapoka France, Norway, Denmark, Belgium na Netherlands. Mu 1941, Germany yikawukira Soviet Union, ndipo nkhondo yikuru yikachitika mu vigaŵa vinandi vya kumafumiro gha dazi kwa Europe.
Mu 1944, ŵasilikari ŵa Allies ŵakafika ku Normandy, ku France, pa 6 Juni. Chochitika ichi chikamanyikwa kuti D-Day ndipo chikawovwira kuti ŵasilikari ŵa Allies ŵambe kusunthira ku Germany kufuma kumanjiliro gha dazi.
Mu Meyi 1945, Germany yikajipeleka, ndipo nkhondo yikuru mu Europe yikamara pa 8 Meyi 1945.<ref>{{Cite web |url=https://www.ushmm.org/learn/timeline-of-events/1933-1945 |title=Holocaust Timeline |publisher=United States Holocaust Memorial Museum |access-date=9 November 2026}}</ref>
== Nkhondo mu Asia na Pacific ==
Japan yikakura mu nkhondo za ku Asia pambere 1939 wandafike. Pa 7 Disembala 1941, ŵasilikari ŵa Japan ŵakawukira malo gha ŵasilikari ŵa United States ku Pearl Harbor, ku Hawaii. Chifukwa cha kuwukira uku, United States yikanjira mu nkhondo.
Nkhondo zikuru zikachitika mu Pacific, ku China, Philippines, Burma, Malaysia na ku visumbu vinandi vya m'nyanja ya Pacific. Mu Juni 1942, ŵasilikari ŵa United States ŵakathereska ŵasilikari ŵa Japan pa Nkhondo ya Midway, ndipo ichi chikasintha umo nkhondo yikendeleranga mu Pacific.
Mu Ogasiti 1945, United States yikaponya mabomba gha nyukiliya pa misumba ya Hiroshima na Nagasaki ku Japan. Soviet Union nayo yikapharazga nkhondo na Japan na kuwukira malo agho Japan yikalamuliranga. Japan yikazomera kupeleka nkhondo, ndipo pa 2 Seputembala 1945 ŵalara ŵake ŵakasayina phangano la kupeleka nkhondo pa sitima ya USS Missouri mu nyanja ya Tokyo.<ref>{{Cite web |url=https://www.archives.gov/college-park/highlights/japanese-surrender |title=Japanese Instrument of Surrender |publisher=U.S. National Archives |access-date=9 November 2026}}</ref>
== Holokausti na masuzgo gha ŵanthu ==
Mu nyengo ya nkhondo, boma la Nazi likachita Holokausti, uko Ŵayuda pafupifupi mamiliyoni 6 ŵakakomeka. Ŵanthu ŵanyake ŵanandi nawo ŵakasuzgika, kusuzgika mu misasa, panji kukomeka chifukwa cha mtundu wawo, chisopa chawo, kulwara panji maghanoghano gha ndyali.
Ŵanthu ŵambura kunjira mu nkhondo nawo ŵakasuzgika chomene. Misumba yinandi yikaparanyika, ŵanthu ŵanandi ŵakachimbira mu nyumba zawo, ndipo vyaru vinandi vikakumana na njara na kusoŵerwa kwa vinthu vyakukhumbikwa.
== Ivyo vikachitika pamanyuma pa nkhondo ==
Nkhondo iyi yikamara mu 1945, kweni yikasinta chomene charu. Vyaru vinandi vya ku Europe na Asia vikaŵa vyaparanyika ndipo vikakhumbikwiranga kuzengaso.
Mu 1945, vyaru vikuru vikakumana ku San Francisco na kukhazikiska [[United Nations]] kuti yiwovwire kusunga mtende pa charu chose. Pamanyuma pa nkhondo, United States na Soviet Union vikazgoka vyaru viŵiri vyankhongono chomene, ndipo mpikisano wawo ukapangiska nyengo ya [[Nkhondo ya Kuzizima]].
== Vithuzithuzi ==
<gallery>
File:Pearl Harbor Attack, 7 December 1941 - 80-G-19942.jpg|Kuwukira kwa Pearl Harbor mu Disembala 1941.
File:Normandy Invasion June 1944.jpg|Ŵasilikari ŵa Allies ŵakufika ku Normandy mu Juni 1944.
File:Europe 1942.svg|Mapu gha Europe mu 1942.
File:Surrender of Japan - USS Missouri.jpg|Ŵalara ŵa Japan ŵakusayina phangano la kupeleka nkhondo mu 1945.
</gallery>
== Wonaniso ==
* [[Nkhondo Yakwamba ya Charu Chose]]
* [[Holokausti]]
* [[United Nations]]
* [[Nkhondo ya Kuzizima]]
* [[Japan]]
* [[Germany]]
== Ukaboni ==
<references />
[[Category:Nkhondo]]
[[Category:Nkhondo za mu vyaka vya m'ma 1900]]
[[Category:1939]]
[[Category:1945]]
09gykmsalw6p2t8q8o4tzcjbxby5vd6
Shōgun
0
50338
124254
2026-11-09T20:44:27Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi wa ŵasilikari uyo wakaŵa na mazaza pa Japan}} [[File:Tokugawa Ieyasu.jpg|thumb|200px|Chithuzithuzi cha Tokugawa Ieyasu, uyo wakakhazikiska boma la Tokugawa.]] '''Shōgun''' (mu Chijapanizi: 将軍) ukaŵa udindo wa mulongozgi mukuru wa ŵasilikari mu [[Japan]]. Mu nyengo zinandi za mbiri ya Japan, shōgun wakaŵa mulongozgi wa boma uyo wakaŵa na mazaza ghakuru pa charu, nangauli fumu ya Japan ndiyo yikaŵa na udindo wa ufumu.<ref>{{Cite..."
124254
wikitext
text/x-wiki
{{Short description|Mulongozgi wa ŵasilikari uyo wakaŵa na mazaza pa Japan}}
[[File:Tokugawa Ieyasu.jpg|thumb|200px|Chithuzithuzi cha Tokugawa Ieyasu, uyo wakakhazikiska boma la Tokugawa.]]
'''Shōgun''' (mu Chijapanizi: 将軍) ukaŵa udindo wa mulongozgi mukuru wa ŵasilikari mu [[Japan]]. Mu nyengo zinandi za mbiri ya Japan, shōgun wakaŵa mulongozgi wa boma uyo wakaŵa na mazaza ghakuru pa charu, nangauli fumu ya Japan ndiyo yikaŵa na udindo wa ufumu.<ref>{{Cite web |url=https://www.city.kamakura.kanagawa.jp/sekaiisan/documents/jh_booklet_e02.pdf |title=The Kamakura Period (1185–1333) |publisher=City of Kamakura |access-date=9 November 2026}}</ref>
Shōgun wakendeskanga boma la ŵasilikari ilo mu Chijapanizi likachemekanga ''bakufu''. Boma la mtundu uwu likachemekanga ''shogunate'' mu Chingelezi.
== Kwamba kwa udindo uwu ==
Lizgu lakuti shōgun likafuma ku mazgu gha Chijapanizi agho ghakung'anamura mulongozgi wa ŵasilikari. Udindo wakale uwu ukaperekekanga kwa ŵalongozgi ŵa ŵasilikari awo ŵakatumikikanga kukachita milimo ya nkhondo.
Mu chaka cha 1185, [[Minamoto no Yoritomo]] wakathereska mbumba ya Taira na kujikhazikiska nga ni mulongozgi mukuru wa boma la ŵasilikari. Mu 1192 wakapokera udindo wa Seii Taishōgun kufuma kwa fumu ya Japan. Ichi chikawovwira kukhazikiska boma la Kamakura.<ref>{{Cite web |url=https://www.city.kamakura.kanagawa.jp/sekaiisan/documents/jh_booklet_e02.pdf |title=The Kamakura Period (1185–1333) |publisher=City of Kamakura |access-date=9 November 2026}}</ref>
== Maboma gha maShōgun ==
Mu mbiri ya Japan mukaŵa maboma ghatatu ghakuru agho ghakalongozgekanga na maShōgun:
=== Boma la Kamakura ===
Boma ili likakhazikiskika na Minamoto no Yoritomo, ndipo likawusa kwamba mu nyengo ya m'ma 1190 mpaka 1333. Kamakura likaŵa likuru la boma ili.
=== Boma la Ashikaga ===
Boma la Ashikaga likakhazikiskika mu 1336 na Ashikaga Takauji. Likawusa mu nyengo ya Muromachi mpaka mu 1573.
=== Boma la Tokugawa ===
Boma la Tokugawa likakhazikiskika na [[Tokugawa Ieyasu]] mu 1603. Likaŵa na likuru lake ku Edo, uko lero kukumanyikwa kuti [[Tokyo]]. Boma ili likawusa mpaka mu 1868, apo masinthiro gha Meiji ghakasintha ndondomeko ya ufumu.
== Umo shōgun wakawusiranga ==
Shōgun wakaŵa na mazaza pa ŵasilikari na pa vinthu vinandi vya boma. Boma lake likendeskanga ŵalara ŵa vigaŵa, ŵalongozgi ŵa mbumba, na ŵanthu ŵanyake awo ŵakateŵeteranga boma.
Fumu ya Japan yikalutilira kuŵapo, kweni mu nyengo zinandi shōgun ndiyo wakaŵa na mazaza ghanandi pa nkhani za boma. Ichi chikapangiska kuti mu Japan muŵe mitundu yiŵiri ya ulongozgi: ufumu wa fumu na boma la shōgun.
== Kumara kwa udindo wa shōgun ==
Boma la Tokugawa likamara mu 1868 pa nyengo ya Masinthiro gha Meiji. Tokugawa Yoshinobu wakaleka mazaza ghake, ndipo ndondomeko ya boma yikasintha. Nangauli lizgu lakuti shōgun likulutilira kumanyikwa mu mbiri na mitheto ya Japan, udindo uwu ulije ntchito ya boma mu Japan yasono.
== Vithuzithuzi ==
<gallery>
File:Shogun-Tokugawa-Ieyasu.png|Tokugawa Ieyasu, uyo wakazenga boma la Tokugawa.
File:Minamoto no Yoritomo.jpg|Chithuzithuzi icho chikulongora Minamoto no Yoritomo.
File:MinamotoYoritomo.jpg|Chithuzithuzi chinyake cha Yoritomo.
</gallery>
== Wonaniso ==
* [[Minamoto no Yoritomo]]
* [[Japan]]
* [[Masinthiro gha Meiji]]
* [[Mbiri ya Japan]]
* [[Ŵasilikari ŵa Samurai]]
== Ukaboni ==
<references />
[[Category:Mbiri ya Japan]]
[[Category:Udindo wa boma]]
[[Category:Ŵalongozgi ŵa ŵasilikari]]
0vf161wp932dh9u2pgni15ryfeehxc9
Taika Reform
0
50339
124255
2026-11-09T20:45:00Z
Tumbuka Arch
6863
Redirected page to [[Masinthiro gha Taika]]
124255
wikitext
text/x-wiki
#REDIRECT [[Masinthiro gha Taika]]
9pf3q5ofyooofemipnhc5ad4ut0edhw
Masinthiro gha Taika
0
50340
124256
2026-11-09T20:45:10Z
Tumbuka Arch
6863
Created page with "{{Short description|Masinthiro gha boma la Japan agho ghakamba mu 645}} [[File:Emperor Kotoku.jpg|thumb|200px|Chithuzithuzi cha Fumu Kōtoku, uyo wakawusa mu nyengo iyo masinthiro gha Taika ghakambira.]] '''Masinthiro gha Taika''' (mu Chijapanizi: 大化の改新, ''Taika no Kaishin'') ghakaŵa masinthiro gha ndyali na kawusiro gha boma la [[Japan]] agho ghakamba mu chaka cha 645 C.E. Chilato chake chikaŵa kusintha kawusiro ka charu kuti boma la fumu liŵe na mazaza gha..."
124256
wikitext
text/x-wiki
{{Short description|Masinthiro gha boma la Japan agho ghakamba mu 645}}
[[File:Emperor Kotoku.jpg|thumb|200px|Chithuzithuzi cha Fumu Kōtoku, uyo wakawusa mu nyengo iyo masinthiro gha Taika ghakambira.]]
'''Masinthiro gha Taika''' (mu Chijapanizi: 大化の改新, ''Taika no Kaishin'') ghakaŵa masinthiro gha ndyali na kawusiro gha boma la [[Japan]] agho ghakamba mu chaka cha 645 C.E. Chilato chake chikaŵa kusintha kawusiro ka charu kuti boma la fumu liŵe na mazaza ghakuru kuluska mbumba zankhongono izo zikawusanga vigaŵa vinandi vya charu.<ref>{{Cite web |url=https://afe.easia.columbia.edu/main_pop/ps/ps_japan-taika.htm |title=The Reform Edict of Taika |website=Asia for Educators, Columbia University |access-date=9 November 2026}}</ref>
Lizgu lakuti ''Taika'' likung'anamura kusintha kukuru. Masinthiro agha ghakaŵa ghanandi, ndipo ghakawovwira kupanga boma la ufumu ilo likawusanga Japan mu nyengo zakulondezgapo.
== Ivyo vikachitika pambere masinthiro ghandambe ==
Pambere chaka cha 645 chindafike, mbumba zinyake za ku Japan zikaŵa na nkhongono zikuru pa ndyali. Mbumba ya Soga yikaŵa yimoza mwa mbumba izo zikaŵa na mazaza ghanandi pa nyumba ya ufumu.
Ŵalongozgi ŵanyake ŵakakhumbanga kuti boma la fumu liŵe na mazaza pa charu chose. Pa 645, ŵanthu awo ŵakakhumbanga kusintha kawusiro ŵakachita chinthu chakuzgoka boma icho chikumanyikwa kuti Isshi Incident. Chifukwa cha ichi, mazaza gha mbumba ya Soga ghakapunguka, ndipo Emperor Kōtoku wakakwera pa chitengo.<ref>{{Cite web |url=https://afe.easia.columbia.edu/ps/japan/taika.pdf |title=Excerpts from the Reform Edict of Taika |website=Asia for Educators, Columbia University |access-date=9 November 2026}}</ref>
== Ŵanthu awo ŵakawovwira pa masinthiro ==
Ŵanthu ŵaŵiri awo ŵakuzunulika chomene pa masinthiro agha ni:
* '''[[Naka no Ōe]]''' – mwana wa fumu uyo pamanyuma wakaŵa Fumu Tenji. Wakawovwira kupanga masinthiro gha boma.
* '''[[Nakatomi no Kamatari]]''' – munthu wa mu mbumba ya Nakatomi uyo wakakolerana na Naka no Ōe pa kusintha kawusiro.
Fumu Kōtoku ndiyo yikaŵa pa chitengo apo masinthiro agha ghakakhazikiskikanga.
== Vinthu ivyo vikasintha ==
Masinthiro gha Taika ghakaŵa na vilato vinandi:
* Kuti mazaza gha charu ghawovwire boma la fumu kuluska mbumba zaŵekha.
* Kukhazikiska maofesi gha boma na ŵalara ŵakuwusika.
* Kulemba mazina gha ŵanthu na malo agho ŵakakhalanga.
* Kukhazikiska ndondomeko ya kugawa malo na kulipira msonkho.
* Kusintha umo vigaŵa vya charu vikawusikiranga.
Masinthiro agha ghakatolera vinthu vinyake ku ndondomeko ya boma la China, chomenechomene umo ufumu wa China ukapangikira maofesi gha boma na kugaŵa charu mu vigaŵa.
== Ivyo vikachitika pamanyuma ==
Masinthiro agha ghakaŵa kwamba kwa kusintha kukuru kwa boma la Japan. Ndondomeko zinyake zikazengeka na kulongosoreka mu vyaka vyakulondezgapo. Mu chaka cha 701, boma likakhazikiska malango ghanyake ghakumanyikwa kuti Taihō Code, agho ghakawovwira kukhozga ndondomeko ya boma.
Masinthiro gha Taika ghakaŵa ghakuzirwa chifukwa ghakawovwira kusintha Japan kufuma ku kawusiro ka mbumba zakujiyimira pawekha kuya ku boma ilo likaŵa na ndondomeko yimoza ya charu chose.
== Vithuzithuzi ==
<gallery>
File:Emperor Kotoku.jpg|Chithuzithuzi cha Fumu Kōtoku.
File:Portrait of Fujiwara no Kamatari.jpg|Chithuzithuzi cha Nakatomi no Kamatari, uyo wakamanyikwaso kuti Fujiwara no Kamatari.
File:Taishokkan portrait of Fujiwara no Kamatari, Kamakura period.jpg|Chithuzithuzi chinyake cha Kamatari.
</gallery>
== Wonaniso ==
* [[Mbiri ya Japan]]
* [[Japan]]
* [[Shōgun]]
* [[Ufumu wa Japan]]
== Ukaboni ==
<references />
[[Category:Mbiri ya Japan]]
[[Category:Masinthiro gha boma]]
[[Category:645]]
eu89orregfnhoext00vlc6hdkx1vldh
Jimmu
0
50341
124257
2026-11-09T20:45:53Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu wakwamba wa ku Japan uyo wakulongosoreka mu nthano}} [[File:Emperor Jimmu.jpg|thumb|200px|Chithuzithuzi cha Jimmu icho chikapangika mu nyengo ya Meiji.]] '''Jimmu''' (mu Chijapanizi: 神武天皇, ''Jinmu Tennō'') ni munthu uyo malemba gha kale gha ku Japan ghakulongosora kuti wakaŵa fumu yakwamba ya charu cha [[Japan]]. Malinga na nthano za ku Japan, wakawusa kwamba mu chaka cha 660 B.C.E. Ndipouli, ŵanthu ŵakusambira mbiri ŵanandi ŵakuwon..."
124257
wikitext
text/x-wiki
{{Short description|Fumu wakwamba wa ku Japan uyo wakulongosoreka mu nthano}}
[[File:Emperor Jimmu.jpg|thumb|200px|Chithuzithuzi cha Jimmu icho chikapangika mu nyengo ya Meiji.]]
'''Jimmu''' (mu Chijapanizi: 神武天皇, ''Jinmu Tennō'') ni munthu uyo malemba gha kale gha ku Japan ghakulongosora kuti wakaŵa fumu yakwamba ya charu cha [[Japan]]. Malinga na nthano za ku Japan, wakawusa kwamba mu chaka cha 660 B.C.E. Ndipouli, ŵanthu ŵakusambira mbiri ŵanandi ŵakuwona Jimmu kuti ni munthu wa mu nthano, chifukwa palije ukaboni wakukwana wakulongora kuti wakaŵako nadi.<ref>{{Cite web |url=https://artsandculture.google.com/entity/emperor-jimmu/m02rhz?hl=en |title=Emperor Jimmu |website=Google Arts & Culture |access-date=9 November 2026}}</ref>
== Mu nthano za ku Japan ==
Mbiri ya Jimmu yikusangika mu mabuku ghaŵiri ghakale chomene gha ku Japan, agho ni ''[[Kojiki]]'' (712 C.E.) na ''[[Nihon Shoki]]'' (720 C.E.). Mabuku agha ghakulongosora kuti Jimmu wakafuma ku banja la ŵafumu awo ŵakababikira ku ŵachiuta ŵa mu chisopa cha Chishinto.
Malinga na nthano iyi, Jimmu wakaŵa mphapu ya [[Amaterasu]], chiuta mwanakazi wa dazi, kwizira mwa Nimigi (Ninigi). Wakamba ulendo kufuma ku chigaŵa cha Hyūga, pa chisumbu cha Kyūshū, kuluta kumafumiro gha dazi. Pamanyuma wakafika ku chigaŵa cha Yamato, uko wakakhazikiska malo gha kuwusa.
Nthano yikulongosoraso kuti Jimmu wakawina nkhondo zakupambanapambana pambere wandakhazikiske ufumu wake. Vinthu ivi vili kulembeka mu mabuku gha kale, kweni palije ukaboni wakujiyimira pawekha wakuti vyose vikachitika nga umo malembi agha ghakuyowoyera.<ref>{{Cite web |url=https://publications.dainst.org/books/dai/catalog/view/2056/2305/5049 |title=Jimmu, Founder of Japan |website=German Archaeological Institute |access-date=9 November 2026}}</ref>
== Zuŵa ilo wakakwera pa chitengo ==
Malinga na kalendala ya nthano za ku Japan, Jimmu wakakwera pa chitengo pa 11 Febuluwale 660 B.C.E. Mu Japan, zuŵa ili likukumbukika pa 11 Febuluwale, ndipo likumanyikwa kuti National Foundation Day. Zuŵa ili likukumbuskana na nthano ya kukhazikiskika kwa charu cha Japan.
== Ukaboni wa mbiri ==
Nangauli Jimmu wakuzunulika mu mabuku ghakale gha ku Japan, ŵanthu ŵakusambira mbiri ŵanandi ŵakuwona kuti nkhani yake njakulongosora umo ŵanthu ŵa mu nyengo zakale ŵakaghanaghaniranga za kukhazikiskika kwa ufumu wa Japan. Palije ukaboni wakukwana wakuti Jimmu wakaŵako nadi panji kuti wakawusa mu chaka cha 660 B.C.E.
Chifukwa cha ichi, Jimmu wakulongosoreka chomene nga ni fumu ya mu nthano, ndipo vyakuchitika ivyo vikulongosoreka mu nkhani yake vikwenera kupatulika ku vinthu ivyo ŵanthu ŵakumanya kuti vikachitika nadi.
== Vithuzithuzi ==
<gallery>
File:Emperor Jimmu 01.jpg|Chithuzithuzi cha Jimmu.
File:Emperor-Jinmu-from-series-Mirror-of-Famous-Generals-of-Great-Japan.png|Jimmu mu chithuzithuzi cha mu nyengo ya kale.
File:Tennō Jimmu image 01.jpg|Chithuzithuzi chinyake cha Jimmu.
</gallery>
== Wonaniso ==
* [[Japan]]
* [[Amaterasu]]
* [[Kojiki]]
* [[Nihon Shoki]]
* [[Mbiri ya Japan]]
== Ukaboni ==
<references />
[[Category:Mbiri ya Japan]]
[[Category:Ŵafumu ŵa ku Japan]]
[[Category:Ŵanthu ŵa mu nthano za ku Japan]]
7z731eq0v5t0estzhnl05qynjw10svl
World War II
0
50342
124258
2026-11-09T20:47:35Z
Tumbuka Arch
6863
Redirected page to [[Nkhondo Yachiŵiri ya Charu Chose]]
124258
wikitext
text/x-wiki
#REDIRECT [[ Nkhondo Yachiŵiri ya Charu Chose]]
2r4fyatu94arnaluamn0e6f6abpqx4s
Amaterasu
0
50343
124259
2026-11-09T20:49:36Z
Tumbuka Arch
6863
Created page with "{{Short description|Chiuta mwanakazi wa dazi mu chisopa cha Chishinto cha ku Japan}} [[File:Amaterasu cave.JPG|thumb|250px|Amaterasu wakufuma mu mphanga, nga umo wakulongosolekera mu nthano za ku Japan.]] '''Amaterasu''' (mu Chijapanizi: 天照大神, ''Amaterasu Ōmikami'') ni chiuta mwanakazi wa dazi mu chisopa cha [[Chishinto]] cha ku [[Japan]]. Ni yumoza mwa ŵachiuta ŵakuzirwa chomene mu nthano za Chijapanizi. Mu mabuku ghakale gha ku Japan, Amaterasu wakulongosore..."
124259
wikitext
text/x-wiki
{{Short description|Chiuta mwanakazi wa dazi mu chisopa cha Chishinto cha ku Japan}}
[[File:Amaterasu cave.JPG|thumb|250px|Amaterasu wakufuma mu mphanga, nga umo wakulongosolekera mu nthano za ku Japan.]]
'''Amaterasu''' (mu Chijapanizi: 天照大神, ''Amaterasu Ōmikami'') ni chiuta mwanakazi wa dazi mu chisopa cha [[Chishinto]] cha ku [[Japan]]. Ni yumoza mwa ŵachiuta ŵakuzirwa chomene mu nthano za Chijapanizi. Mu mabuku ghakale gha ku Japan, Amaterasu wakulongosoreka nga ni chiuta uyo wakuwusa malo gha kuchanya agho ghakumanyikwa kuti Takamagahara.<ref>[https://d-museum.kokugakuin.ac.jp/eos/detail/?id=9440 Amaterasu], Encyclopedia of Shinto, Kokugakuin University.</ref>
Amaterasu wakuzunulika chomene mu mabuku gha ''[[Kojiki]]'' na ''[[Nihon Shoki]]''. Mu mitheto ya nyumba ya ufumu ya Japan, wakuwoneka nga ni mzimu wa mu banja la ŵafumu ŵa Japan.
== Kwamba kwake mu nthano ==
Malinga na ''Kojiki'', Amaterasu wakababika apo chiuta Izanagi wakasuka jiso lake lamazere pa nyengo iyo wakajitozganga pamanyuma pa kufuma ku charu cha ŵakufwa. Mu nthano iyi, Izanagi wakababiskaso ŵachiuta ŵanyake ŵaŵiri: Tsukuyomi na Susanoo.
Izanagi wakapeleka kwa Amaterasu udindo wa kulamulira malo gha kuchanya. Amaterasu wakazgoka mulongozgi wa ŵachiuta ŵanyake awo ŵakakhalanga ku Takamagahara.<ref>[https://d-museum.kokugakuin.ac.jp/eos/detail/?id=9440 Amaterasu], Encyclopedia of Shinto, Kokugakuin University.</ref>
== Nkhani ya Amaterasu na mphanga ==
Yimoza mwa nthano zakumanyikwa chomene za Amaterasu yikulongosora umo wakabisamira mu mphanga. Nkhani iyi yikuyowoya kuti pamanyuma pa kususkana na mudumbu wake Susanoo, Amaterasu wakaluta kukabisama mu mphanga yakuchemeka Ama-no-Iwato.
Chifukwa chakuti Amaterasu wakabisama, charu chikakhala mu mdima. Ŵachiuta ŵanyake ŵakawungana kuti ŵasange nthowa yakumufumiskira mu mphanga. Ŵakanozga mwambo wa sumu na kuvina, ndipo chiuta mwanakazi Ama-no-Uzume wakasekeskanga ŵanyake. Amaterasu wakafumiska mutu wake kuti wawone ivyo vikuchitika, ndipo ŵachiuta ŵanyake ŵakamovwira kufuma mu mphanga.
Nthano iyi yikulongosora umo ungweru na umoyo vikaweleraso pa charu. Nkhani iyi yikuzunulika mu malemba ghakale gha Chishinto, kweni yikwenera kupulikikwa nga ni nthano ya chisopa, yayi nga ni chochitika icho chili na ukaboni wa mbiri.<ref>[https://www.kokugakuin.ac.jp/en/article/82153 For whom was the Kojiki made?], Kokugakuin University.</ref>
== Amaterasu na nyumba ya ufumu ==
Mu mitheto ya ku Japan, Amaterasu wakuwoneka nga ni mzukuru wa ŵafumu ŵa Japan. Nthano zikulongosora kuti Ninigi, uyo wakafuma ku Amaterasu, wakatumika ku charu kuti wakawuse. Mphapu yake yikulongosoreka kuti yikafika kwa Fumu Jimmu.
Nthano iyi yikazgoka yimoza mwa vinthu ivyo vikawovwira nyumba ya ufumu ya Japan kujilongosora kuti yili na chiyambi chakufuma kwa ŵachiuta. Kweni nkhani iyi njachisopa na ya mu nthano, ndipo yikukhumbikwira kupatulika ku ukaboni wa mbiri.
== Malo ghakusopera Amaterasu ==
Amaterasu wakusoperwa chomene pa Ise Grand Shrine, iyo yikumanyikwaso kuti Ise Jingū, mu chigaŵa cha Mie ku Japan. Malo ghakuzirwa chomene mu shrine iyi ghakuchemeka Naikū, ndipo ghakupatulika kwa Amaterasu.
Chimanyikwiro cha Amaterasu ni gilasi lakupatulika ilo lili mu vinthu vitatu vyakuzirwa vya nyumba ya ufumu ya Japan. Mu chisopa cha Chishinto, Ise Grand Shrine ni malo ghakuzirwa chomene gha kusopera Amaterasu.<ref>[https://d-museum.kokugakuin.ac.jp/bts/detail/?id=3747 Ise no Jingū], Kokugakuin University Digital Museum.</ref>
== Kufunika kwake ==
Amaterasu wakukondwelereka nga ni chiuta wa ungweru, dazi na umoyo. Nthano zake zili na malo ghakuzirwa mu mabuku, vyajambuliro, mitheto na chisopa cha ku Japan.
== Vithuzithuzi ==
<gallery>
File:Amaterasu cave.JPG|Amaterasu wakufuma mu mphanga mu chithuzithuzi cha mu 1887.
File:Amaterasu cave - large - 1856.jpeg|Chithuzithuzi cha Amaterasu icho chikapangika na Utagawa Kunisada mu 1856.
File:Amaterasu cave edit2.jpg|Amaterasu na nthano ya mphanga.
File:Installation of the Sun Goddess (Amaterasu) c1870 after Kawanabe Kyosai.jpg|Chithuzithuzi cha Amaterasu na ŵachiuta ŵanyake.
File:Amaterasu shinbutsu-zue.jpg|Chithuzithuzi cha Amaterasu cha pambere chaka cha 1868 chindafike.
File:MET DP-12232-265.jpg|Chithuzithuzi cha mu nthano ya kufumiska Amaterasu mu mphanga.
</gallery>
== Wonaniso ==
* [[Kojiki]]
* [[Nihon Shoki]]
* [[Chishinto]]
* [[Japan]]
* [[Mbiri ya Japan]]
* [[Fumu Jimmu]]
== Ukaboni ==
<references />
[[Category:Ŵachiuta ŵa Chijapanizi]]
[[Category:Chishinto]]
[[Category:Mbiri ya Japan]]
93lyj8zpcmy4mbzy7jov3f9i5ftbzwu
Kojiki
0
50344
124260
2026-11-09T20:50:12Z
Tumbuka Arch
6863
Created page with "{{Short description|Buku lakale chomene la mbiri na nthano za ku Japan}} [[File:Kojiki Shinpukuji.jpg|thumb|200px|Buku la Kojiki la Shinpukuji, ilo lili na malemba agho ghakalembeka mu 1371–1372.]] '''Kojiki''' (mu Chijapanizi: 古事記), ilo lizgu lake lingang'anamura kuti ''Mbiri ya Vinthu Vyakale'', ni buku lakale chomene la ku Japan ilo licalipo. Likamalizgika mu chaka cha 712 C.E., mu nyengo ya Fumukazi Genmei. Buku ili likulongosora nthano za ŵachiuta, chiyambi..."
124260
wikitext
text/x-wiki
{{Short description|Buku lakale chomene la mbiri na nthano za ku Japan}}
[[File:Kojiki Shinpukuji.jpg|thumb|200px|Buku la Kojiki la Shinpukuji, ilo lili na malemba agho ghakalembeka mu 1371–1372.]]
'''Kojiki''' (mu Chijapanizi: 古事記), ilo lizgu lake lingang'anamura kuti ''Mbiri ya Vinthu Vyakale'', ni buku lakale chomene la ku Japan ilo licalipo. Likamalizgika mu chaka cha 712 C.E., mu nyengo ya Fumukazi Genmei. Buku ili likulongosora nthano za ŵachiuta, chiyambi cha charu cha Japan, na mbiri ya mafumu gha mu Japan kufuma mu nyengo zakale.<ref>[https://jpsearch.go.jp/en/gallery/ndl-xxj8rzqBPk Kojiki and Nihon Shoki], Japan Search.</ref>
Kojiki ni buku lakuzirwa pa kusambira mbiri, chisopa, viyowoyero na mitheto ya ku Japan. Pamoza na [[Nihon Shoki]], ni limoza mwa mabuku ghakale chomene agho ghakulongosora umo ŵanthu ŵa ku Japan ŵakaghanaghaniranga vya chiyambi cha charu chawo.
== Kwamba kwake ==
Malinga na nkhani iyo yili mu chiyambi cha buku ili, Fumu Tenmu yikakhumba kuti malemba ghakale gha banja la ufumu na nthano za charu zilembeke mwakupwelelera. Hieda no Are wakakumbukira na kuyowoya nkhani izo zikaŵa mu malemba ghakale, ndipo Ō no Yasumaro wakalemba na kunozga nkhani izo.
Buku ili likapelekeka kwa Fumukazi Genmei mu chaka cha 712. Ŵakusambira mbiri ŵakugwiliskira ntchito Kojiki pakusambira za Japan wakale, kweni ŵakupima nkhani zake mwakupambana chifukwa zinyake ni nthano, ndipo zinyake zikulongora vinthu vya mu mbiri.<ref>[https://www.kokugakuin.ac.jp/en/article/82153 For whom was the Kojiki made?], Kokugakuin University.</ref>
== Umo buku ili liliri ==
Kojiki lili na chiyambi icho chikulongosora umo buku ili likalembekera, ndipo lili na vigaŵa vitatu vikuru:
* '''Kamitsumaki''' – chigaŵa ichi chikulongosora nthano za ŵachiuta, chiyambi cha kuchanya na charu, kweniso nkhani za Amaterasu, Izanagi, Izanami na ŵachiuta ŵanyake.
* '''Nakatsumaki''' – chigaŵa ichi chikulongosora vya mafumu ghakale, kwamba na Fumu Jimmu.
* '''Shimotsumaki''' – chigaŵa ichi chikulutilira na nkhani za mafumu mpaka mu nyengo ya Fumukazi Suiko.
== Nkhani za ŵachiuta ==
Chigaŵa chakwamba cha Kojiki chili na nthano za umo kuchanya na charu vikambira. Chikulongosora vya ŵachiuta ŵakwamba, Izanagi na Izanami, awo mu nthano za ku Japan ŵakulongosoreka kuti ŵakawovwira kupanga visumbu vya Japan.
Buku ili likulongosoraso vya Amaterasu, chiuta mwanakazi wa dazi, na ŵakuru ŵake nga ni Susanoo na Tsukuyomi. Nthano ya Amaterasu kubisama mu mphanga yikusangikaso mu buku ili.
== Mafumu gha Japan ==
Kojiki likulongosora za chiyambi cha nyumba ya ufumu ya Japan kwizira mu nthano za Ninigi na mphapu yake. Likulongosoraso za Fumu Jimmu, uyo mu nthano za ku Japan wakumanyikwa kuti ndiyo wakaŵa fumu wakwamba.
Nkhani izi zili na ntchito yakuzirwa pa kupulikiska umo nyumba ya ufumu ya Japan yikajipulikiskiranga na umo ŵanthu ŵa mu nyengo zakale ŵakulongosoleranga mazaza gha ufumu. Kweni nkhani za mafumu ghakwambilira zikusazgana na nthano ndipo zose zingapimika yayi nga ni mbiri yakusimikizgika.
== Viyowoyero na mabuku ==
Kojiki likalembeka na kulemba kwa Chichina chakale, kweni lili na mazgu na sumu za Chijapanizi chakale. Likusazgapo nkhani, ndakatulo na mazgu agho ghakovwira ŵakusambira viyowoyero kumanya umo Chijapanizi chikayowoyekeranga mu nyengo zakale.
Buku ili ndakuzirwa chomene pa kafukufuku wa mbiri ya mabuku gha ku Japan na kukula kwa chisopa cha Chishinto.<ref>[https://academic.oup.com/book/11088/chapter-abstract/159493458 Myth and history in the Kojiki, Nihon shoki, and related works], Cambridge History of Japanese Literature.</ref>
== Kupambana kwake na Nihon Shoki ==
Kojiki na Nihon Shoki ghali na nkhani zinandi zakuyana, kweni ghali na umo ghakulembekera zakupambana. Kojiki kanandi likulongosora nkhani mu ndondomeko yimoza yakulutilira, apo Nihon Shoki lili na nkhani zikuru kweniso mitundu yinyake ya nkhani izo zikulongosora chochitika chimoza.
Kojiki lili na vigaŵa vitatu vikuru, apo Nihon Shoki lili na mabuku 30. Nihon Shoki likalembeka chomene mu Chichina chakale ndipo likagwira ntchito nga ni buku la mbiri la boma la Japan.
== Makope agho ghacalipo ==
Buku lakwamba la Kojiki likaleka kuŵapo. Makope ghakale agho ghacalipo ghakafuma mu vyaka vya m'ma 1300 na m'ma 1400. Limoza mwa makope ghakuzirwa ni la Shinpukuji ilo likalembeka mu 1371 na 1372. Makope agha ghakovwira ŵakusambira kumanya umo malemba ghakale ghakakhalira na umo ghakajandulikiranga.<ref>[https://www.kokugakuin.ac.jp/en/article/82153 For whom was the Kojiki made?], Kokugakuin University.</ref>
== Vithuzithuzi ==
<gallery>
File:Kojiki Shinpukuji.jpg|Kopi lakale la Kojiki la Shinpukuji.
File:NDL1185383 古事記 巻中.pdf|Kopi la Kojiki ilo lili mu National Diet Library ya Japan.
File:WUL-bunko31 e1154 古事記.pdf|Buku la Kojiki ilo likasindikizgika mu 1799.
File:NDL1119662 古事記 上巻.pdf|Kopi la chigaŵa chakwamba cha Kojiki.
File:Amaterasu cave.JPG|Amaterasu, yumoza mwa ŵachiuta awo ŵakuzunulika mu Kojiki.
</gallery>
== Wonaniso ==
* [[Amaterasu]]
* [[Nihon Shoki]]
* [[Mbiri ya Japan]]
* [[Japan]]
* [[Chishinto]]
== Ukaboni ==
<references />
[[Category:Mabuku gha ku Japan]]
[[Category:Mbiri ya Japan]]
[[Category:Mabuku gha vyaka vya m'ma 700]]
5q8tw6r9hjxco6bewxvn5djsexvzmgq
Nihon Shoki
0
50345
124261
2026-11-09T20:50:38Z
Tumbuka Arch
6863
Created page with "{{Short description|Buku lakale la mbiri ya ufumu wa Japan ilo likamalizgika mu 720}} [[File:NDL772283 日本書紀 巻第1.pdf|thumb|250px|Kopi lakale la Nihon Shoki.]] '''Nihon Shoki''' (mu Chijapanizi: 日本書紀), ilo likumanyikwaso kuti ''Nihongi'', ni buku lakale la mbiri ya [[Japan]] ilo likamalizgika mu chaka cha 720 C.E. Ni limoza mwa mabuku ghakale chomene gha ku Japan, ndipo likumanyikwa kuti ndilo buku lakwamba la mbiri ya Japan ilo likalembeka mwakudangi..."
124261
wikitext
text/x-wiki
{{Short description|Buku lakale la mbiri ya ufumu wa Japan ilo likamalizgika mu 720}}
[[File:NDL772283 日本書紀 巻第1.pdf|thumb|250px|Kopi lakale la Nihon Shoki.]]
'''Nihon Shoki''' (mu Chijapanizi: 日本書紀), ilo likumanyikwaso kuti ''Nihongi'', ni buku lakale la mbiri ya [[Japan]] ilo likamalizgika mu chaka cha 720 C.E. Ni limoza mwa mabuku ghakale chomene gha ku Japan, ndipo likumanyikwa kuti ndilo buku lakwamba la mbiri ya Japan ilo likalembeka mwakudangizga na boma la ufumu.<ref>[https://www.narahaku.go.jp/english/collection/v-1190-0.html Nihon Shoki], Nara National Museum.</ref>
Buku ili lili na nkhani za mu nthano za ŵachiuta, chiyambi cha nyumba ya ufumu ya Japan, na vinthu ivyo vikachitika mpaka mu nyengo ya Fumukazi Jitō.
== Mbiri ya kulembeka kwake ==
Nihon Shoki likalembeka mu nyengo ya Nara. Ntchito yakunozga malemba gha mbiri yikamba mu nyengo ya Fumu Tenmu, ndipo buku ili likamalizgika mu 720, mu nyengo ya Fumukazi Genshō.
Ŵanthu awo ŵakazunulika kuti ŵakawovwira pa kulemba kwake ŵakasazgapo mwana wa ufumu Toneri na ŵanthu ŵanyake ŵakusambira. Buku ili likaŵa na chilato cha kulemba mbiri ya nyumba ya ufumu na boma la Japan mu ndondomeko yakuyana na mabuku gha mbiri agho ghakalembekanga mu China.<ref>[https://www.loc.gov/item/2021666419/ Chronicle of Japan, Volumes 1 and 2], Library of Congress.</ref>
== Umo buku ili liliri ==
Nihon Shoki lili na mabuku 30. Likulongosora nkhani kufuma mu nyengo ya nthano za ŵachiuta mpaka ku vyaka vya m'ma 600 C.E. Nkhani zake zikuŵikika mu ndondomeko ya nyengo na mafumu agho ghakawusa Japan.
Buku ili likalembeka mu Chichina chakale, chiyowoyero icho pa nyengo iyo chikagwiliskirikanga ntchito pa kulemba mabuku gha boma na mbiri mu vyaru vinandi vya ku East Asia.
== Nkhani za ŵachiuta ==
Mabuku ghakwambilira gha Nihon Shoki ghakulongosora vya chiyambi cha kuchanya na charu, kweniso ŵachiuta awo ŵali na malo ghakuzirwa mu nthano za ku Japan.
Mwa ŵachiuta awo ŵakuzunulika ni Izanagi, Izanami, Amaterasu na Susanoo. Nkhani ya Amaterasu na Susanoo yikusangika mu buku ili. Likulongosoraso mitundu yakupambanapambana ya nkhani za kale, izo zikusiyana pa vinthu vinyake.<ref>[https://www.bunka.go.jp/seisaku/bunkazai/shokai/sekai_isan/suisenchu/pdf/suisensho_2_eng.pdf The Sacred Island of Okinoshima and Associated Sites in the Munakata Region], Agency for Cultural Affairs, Japan.</ref>
== Mbiri ya nyumba ya ufumu ==
Nihon Shoki likulongosora vya mafumu gha Japan na umo ufumu ukakulira. Nkhani zake zikuphatikizga vya Fumu Jimmu, ŵafumu ŵakulondezgana nayo, kweniso vinthu ivyo vikachitika mu nyengo ya mafumu agho ghakaŵako kale.
Buku ili likuzunura vinthu nga ni ubwezi wa Japan na vyaru vinyake vya ku Asia, kusazgapo China na Korea. Ŵakusambira ŵakugwiliskira ntchito buku ili pakupima mbiri ya Japan, chomenechomene ya mu vyaka vya m'ma 600 C.E.
== Kupambana kwake na Kojiki ==
Nihon Shoki na [[Kojiki]] ghakulembeka mu nyengo yakuyana ndipo ghali na nthano zinandi zakuyana. Kweni pali mphambano zikuru pakati pa mabuku agha.
Kojiki likulongosora nkhani mu ndondomeko yakulutilira, ndipo lili na mabuku ghatatu. Nihon Shoki lili na mabuku 30, ndipo kanandi likulongosora nkhani yimoza pamoza na mitundu yinyake ya nkhani yakulongosora chochitika ichocho.
Kojiki likuzunulika chomene pa nkhani za nthano na chiyowoyero cha Chijapanizi chakale, apo Nihon Shoki likuwoneka nga ni buku la mbiri la boma ilo likalembeka mu kalembedwe ka Chichina.<ref>[https://academic.oup.com/book/11088/chapter-abstract/159493458 Myth and history in the Kojiki, Nihon shoki, and related works], Cambridge History of Japanese Literature.</ref>
== Kufunika kwake pa mbiri ==
Nihon Shoki ni ukaboni wakuzirwa wa umo boma la Japan likajipelekera mbiri yake mu nyengo zakale. Likovwira ŵakusambira kumanya vya ndyali, nyumba ya ufumu, chisopa na mitheto ya Japan.
Ndipouli, chifukwa chakuti likusazga nthano na mbiri, ŵakusambira ŵakwenera kupima nkhani zake pamoza na ukaboni unyake nga ni vinthu ivyo vikafukulika pasi, malemba ghanyake na mabuku gha vyaru vinyake.
== Makope agho ghacalipo ==
Buku lakwamba ilo likamalizgika mu 720 lilije. Makope agho ghacalipo ghakafuma mu nyengo zakulondezgapo. National Museum of Nara yikusunga kopi lakale la Nihon Shoki ilo lili na udindo wa National Treasure ya Japan.<ref>[https://www.narahaku.go.jp/english/collection/v-1190-0.html Nihon Shoki], Nara National Museum.</ref>
== Vithuzithuzi ==
<gallery>
File:NDL772283 日本書紀 巻第1.pdf|Kopi lakale la chigaŵa chakwamba cha Nihon Shoki.
File:NDL932618 日本書紀 神代巻.pdf|Malemba gha Nihon Shoki ghakulongosora nyengo ya ŵachiuta.
File:E0070816 玉屋本日本書紀 - 東京国立博物館 画像検索|Kopi la Nihon Shoki ilo lili mu Tokyo National Museum.
File:Amaterasu cave.JPG|Amaterasu, chiuta uyo wakuzunulika mu mabuku agha.
</gallery>
== Wonaniso ==
* [[Kojiki]]
* [[Amaterasu]]
* [[Mbiri ya Japan]]
* [[Japan]]
* [[Chishinto]]
== Ukaboni ==
<references />
[[Category:Mabuku gha ku Japan]]
[[Category:Mbiri ya Japan]]
[[Category:Mabuku gha vyaka vya m'ma 700]]
kv7tedqo8k81460dnac6718gtlk7tgr
Category:Ŵanthu ŵa mu nthano za ku Japan
14
50346
124262
2026-11-09T20:51:10Z
Tumbuka Arch
6863
Created blank page
124262
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Mbiri ya Japan
0
50347
124263
2026-11-09T20:51:37Z
Tumbuka Arch
6863
Created page with "{{Short description|Mbiri ya ŵanthu, boma na chikhalidwe cha Japan}} [[File:Imperial Palace, Tokyo JP.jpg|thumb|250px|Nyumba ya Ufumu wa Japan ku Tokyo.]] '''Mbiri ya Japan''' yikulongosora vya ŵanthu, maboma, nkhondo, chisopa, chuma na chikhalidwe cha charu cha [[Japan]] kufuma mu nyengo zakale mpaka mazuŵa ghano. Japan ni charu cha visumbu icho chili kumafumiro gha dazi kwa Asia, mu nyanja ya Pacific. Mbiri yake yakhwaskika na ubwezi wake na vyaru nga ni [[China]] n..."
124263
wikitext
text/x-wiki
{{Short description|Mbiri ya ŵanthu, boma na chikhalidwe cha Japan}}
[[File:Imperial Palace, Tokyo JP.jpg|thumb|250px|Nyumba ya Ufumu wa Japan ku Tokyo.]]
'''Mbiri ya Japan''' yikulongosora vya ŵanthu, maboma, nkhondo, chisopa, chuma na chikhalidwe cha charu cha [[Japan]] kufuma mu nyengo zakale mpaka mazuŵa ghano. Japan ni charu cha visumbu icho chili kumafumiro gha dazi kwa Asia, mu nyanja ya Pacific. Mbiri yake yakhwaskika na ubwezi wake na vyaru nga ni [[China]] na [[Korea]], kweniso na vyaru vya ku Europe na America mu nyengo zakulondezgapo.<ref>[https://afe.easia.columbia.edu/timelines/japan_timeline.htm Japan—Timeline of Historical Periods], Columbia University.</ref>
== Nyengo zakale ==
=== Nyengo ya Jōmon ===
Nyengo ya Jōmon ni yimoza mwa nyengo zakale chomene mu mbiri ya Japan. Ŵanthu ŵa mu nyengo iyi ŵakakhalanga mwa kusaka vinyama, kukola somba na kuwunjika vipambi. Ŵakapanga viŵiya vya dongo ivyo vikaŵa na vyakudindika vyakuyana na nthambo. Vigaŵa vinyake vya Japan vili na vinthu vyakale ivyo vikulongora umoyo wa ŵanthu ŵa mu nyengo iyi.
=== Nyengo ya Yayoi ===
Mu nyengo ya Yayoi, ulimi wa mpunga ukamba kuthandazgika mu Japan. Ŵanthu ŵakamba kulima mu minda na kukhala mu malo ghakukhazikika. Kugwiliskira ntchito visulo na kupanga vinthu vya mkuwa vikawovwira kuti magulu gha ŵanthu na maboma ghachoko ghakulire.
=== Nyengo ya Kofun ===
Nyengo ya Kofun yikulongosoreka na manda ghakuru gha dongo agho ghakazengekanga kuti ŵalongozgi ŵa nyengo iyo ŵasungikemo. Manda agha ghakuchemeka ''kofun''. Mu nyengo iyi, gulu la Yamato likakura mu mazaza ndipo likaŵa na ntchito yakuzirwa pa kukhazikiska ufumu wa Japan.<ref>[https://afe.easia.columbia.edu/timelines/japan_timeline.htm Japan—Timeline of Historical Periods], Columbia University.</ref>
== Nyengo ya Asuka ==
Nyengo ya Asuka yikaŵa pakati pa vyaka vya m'ma 500 na 700 C.E. Mu nyengo iyi, Buddhism yikathandazgika mu Japan kwizira ku Korea na China. Chisopa ichi chikakhwaska vyakuzenga, vyajambuliro, masambiro na ndyali za charu.
Mu 645, Masinthiro gha Taika ghakamba kusintha kawusiro ka boma. Boma likakhumbanga kuti mazaza ghanandi ghaŵe na fumu na ŵalara ŵake m'malo mwa mbumba izo zikaŵa na mazaza pa vigaŵa vyakupambanapambana.
== Nyengo ya Nara ==
Mu 710, likuru la boma likasamukira ku Nara. Mu nyengo iyi, boma likakhazikiska maofesi na ndondomeko za charu chose. Mu 712, buku la [[Kojiki]] likamalizgika, ndipo mu 720, [[Nihon Shoki]] likamalizgika.
Mu nyengo iyi, Buddhism yikakura chomene ndipo nyumba zikuru za chisopa zikazengeka. Chimoza mwa vyakuzenga vyakumanyikwa chomene ni Tōdai-ji, icho chili na chikozgo chikuru cha Buddha.
== Nyengo ya Heian ==
Mu 794, likuru la boma likasamukira ku Heian-kyō, uko lero kukumanyikwa kuti [[Kyoto]]. Mu nyengo iyi, mabuku, ndakatulo, vyajambuliro na mitheto ya ku nyumba ya ufumu vikakura chomene.
Mbumba ya Fujiwara yikaŵa na mazaza ghanandi pa boma. Mabuku nga ni ''The Tale of Genji'' ghakalembeka mu nyengo iyi ndipo ghakawovwira chomene pa mbiri ya mabuku gha ku Japan.
== Nyengo ya Kamakura na kuwusa kwa ŵasilikari ==
Mu 1185, Minamoto no Yoritomo wakakhazikiska boma la ŵasilikari ku Kamakura. Mu 1192 wakapokera udindo wa [[shōgun]]. Kufuma apo, ŵalongozgi ŵa ŵasilikari ŵakazgoka ŵakuzirwa chomene pa kayendeskero ka boma, nangauli fumu yikalutilira kuŵapo.
Boma la Kamakura likathereskeka mu 1333, ndipo pamanyuma pake boma la Ashikaga likawusa mu nyengo ya Muromachi.
== Nyengo ya Sengoku na kuunganiska charu ==
Mu nyengo ya Sengoku, Japan yikagaŵikana mu vigaŵa ivyo vikawusikanga na ŵalongozgi ŵa ŵasilikari awo ŵakalwananga kuti ŵapoke malo ghanyake. Ŵalongozgi ŵakumanyikwa mu nyengo iyi ŵakaŵa Oda Nobunaga, Toyotomi Hideyoshi na Tokugawa Ieyasu.
Mu vyaka vya m'ma 1500, ŵalongozgi aŵa ŵakawovwira kuunganiska vigaŵa vinandi vya Japan na kukhazikiska boma limoza.
== Nyengo ya Edo ==
Mu 1603, Tokugawa Ieyasu wakakhazikiska boma la Tokugawa ku Edo, uko lero kukumanyikwa kuti [[Tokyo]]. Boma ili likawusa mpaka 1868.
Mu nyengo iyi, Japan yikaŵa na mtende wa nyengo yitali. Maseŵero, mabuku, vyajambuliro, malonda na misumba vikakura. Mitheto nga ni Kabuki na ukiyo-e yikathandazgika. Boma la Tokugawa likalamuliranga chomene umo ŵanthu ŵakendeleranga na vyaru vinyake.
== Masinthiro gha Meiji ==
Mu 1868, Masinthiro gha Meiji ghakasintha ndondomeko ya boma. Mazaza ghakawelera ku nyumba ya ufumu, ndipo boma liphya likamba kusintha masambiro, ŵasilikari, chuma, kayendeskero ka boma na ubwezi wa vyaru.
Mu nyengo iyi, Japan yikakura mwaluŵiro mu mafakitale na sayansi. Edo likapika zina liphya lakuti Tokyo ndipo likazgoka likuru la boma.
== Nyengo ya Taishō na Shōwa ==
Nyengo ya Taishō yikamba mu 1912 ndipo yikamara mu 1926. Mu nyengo iyi, magulu gha ndyali na mabungwe gha ŵanthu ghakakura.
Nyengo ya Shōwa yikamba mu 1926. Mu chigaŵa chake chakwamba, Japan yikakura mu nkhongono za ŵasilikari ndipo yikatora chigaŵa mu nkhondo za ku Asia. Ivi vikafika pachanya pa [[Nkhondo Yachiŵiri ya Charu Chose]], iyo yikamara mu 1945.
== Japan pamanyuma pa nkhondo ==
Pamanyuma pa 1945, Japan yikasintha dango lake na ndondomeko ya boma. Dango liphya likamba kugwira ntchito mu 1947. Mwakuyana na dango ili, fumu yikazgoka chimanyikwiro cha charu ndipo mazaza gha boma ghakakhala na mabungwe agho ghakusankhika na ŵanthu.
Mu vyaka vyakulondezgapo, Japan yikazengaso misumba yake, mafakitale na vinthu vya ntchito. Chuma chake chikakura chomene ndipo yikazgoka chimoza mwa vyaru vikuru pa chuma na sayansi.
== Nyengo ya Heisei na Reiwa ==
Nyengo ya Heisei yikamba mu 1989 apo Akihito wakakwera pa chitengo cha ufumu, ndipo yikamara mu 2019 apo wakaleka udindo wake. Nyengo ya Reiwa yikamba pa 1 Meyi 2019 apo Naruhito wakazgoka fumu.
== Chikhalidwe cha Japan ==
Mbiri ya Japan yikawovwira kupanga mitheto na chikhalidwe chapadera. Vinthu vyakuzirwa vikusazgapo:
* Chisopa cha [[Chishinto]] na Buddhism.
* Sumu na maseŵero gha Nō na Kabuki.
* Vyajambuliro vya ukiyo-e.
* Vyakuŵika na kupanga vyakurya nga ni sushi na ramen.
* Mitheto ya nyumba ya ufumu.
* Nyumba za chisopa, nyumba zikuru na minda.
== Vithuzithuzi ==
<gallery>
File:JomonPottery.JPG|Viŵiya vya dongo vya mu nyengo ya Jōmon.
File:Komyosan Kofun, haniwa.jpg|Chinthu cha dongo cha haniwa cha mu nyengo ya Kofun.
File:Great Buddha at Todaiji, Nara.jpg|Chikozgo chikuru cha Buddha ku Tōdai-ji mu Nara.
File:Todai-ji.jpg|Nyumba ya Tōdai-ji.
File:Himeji castle.jpg|Nyumba yikuru ya Himeji ya mu nyengo za kale.
File:Imperial Palace, Tokyo JP.jpg|Nyumba ya Ufumu wa Japan ku Tokyo.
File:Amaterasu cave.JPG|Nthano ya Amaterasu mu chikhalidwe cha Japan.
</gallery>
== Wonaniso ==
* [[Japan]]
* [[Ufumu wa Japan]]
* [[Amaterasu]]
* [[Kojiki]]
* [[Nihon Shoki]]
* [[Masinthiro gha Taika]]
* [[Masinthiro gha Meiji]]
* [[Shōgun]]
* [[Nkhondo Yachiŵiri ya Charu Chose]]
== Ukaboni ==
<references />
[[Category:Mbiri ya Japan]]
[[Category:Mbiri ya Asia]]
[[Category:Japan]]
9p7d1jra9fy7kpgqnytyiuhnft257iz
Category:Mbiri ya Asia
14
50348
124264
2026-11-09T20:51:55Z
Tumbuka Arch
6863
Created blank page
124264
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Masinthiro gha boma
14
50349
124265
2026-11-09T20:52:17Z
Tumbuka Arch
6863
Created blank page
124265
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:645
14
50350
124266
2026-11-09T20:52:29Z
Tumbuka Arch
6863
Created blank page
124266
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Sukulu yaumalilo ya Oxford
0
50351
124267
2026-11-09T20:53:27Z
Tumbuka Arch
6863
Created page with "{{Short description|Sukulu yaumalilo yakale chomene ya Chingelezi iyo yili ku Oxford, England}} [[File:Radcliffe Camera, Oxford.jpg|thumb|250px|Radcliffe Camera, chimoza mwa nyumba zakumanyikwa za pa University of Oxford.]] '''Sukulu yaumalilo ya Oxford''' (mu Chingelezi: ''University of Oxford'') ni sukulu yaumalilo iyo yili mu msumba wa [[Oxford]], mu charu cha [[England]], [[United Kingdom]]. Ni sukulu yaumalilo yakale chomene mu vyaru ivyo vikuyowoya Chingelezi, ndip..."
124267
wikitext
text/x-wiki
{{Short description|Sukulu yaumalilo yakale chomene ya Chingelezi iyo yili ku Oxford, England}}
[[File:Radcliffe Camera, Oxford.jpg|thumb|250px|Radcliffe Camera, chimoza mwa nyumba zakumanyikwa za pa University of Oxford.]]
'''Sukulu yaumalilo ya Oxford''' (mu Chingelezi: ''University of Oxford'') ni sukulu yaumalilo iyo yili mu msumba wa [[Oxford]], mu charu cha [[England]], [[United Kingdom]]. Ni sukulu yaumalilo yakale chomene mu vyaru ivyo vikuyowoya Chingelezi, ndipo masambiro ghakamba kuchitika ku Oxford kufika mu chaka cha 1096.<ref>{{Cite web |url=https://www.ox.ac.uk/about/the-university/history |title=Our history |publisher=University of Oxford |access-date=9 November 2026}}</ref>
University of Oxford yikumanyikwa pa charu chose chifukwa cha masambiro, kafukufuku wa sayansi, mabuku, ndyali, na ŵanthu ŵakumanyikwa awo ŵakasambirako.
== Mbiri ==
Palije zuŵa limoza ilo likumanyikwa kuti ndilo sukulu iyi yikakhazikiskikira, kweni ukaboni ukulongora kuti masambiro ghakaŵako ku Oxford mu 1096. Sukulu iyi yikakura chomene pamanyuma pa 1167, apo Fumu Henry II ya ku England yikakanizga ŵana ŵa ku England kuluta kukasambira ku University of Paris. Chifukwa cha ichi, ŵasambiri ŵanandi ŵakamba kuluta ku Oxford.<ref>{{Cite web |url=https://www.ox.ac.uk/about/the-university/history |title=Our history |publisher=University of Oxford |access-date=9 November 2026}}</ref>
Mu 1201, University ya Oxford yikaŵa kale na mulongozgi uyo wakachemekanga ''magister scholarum''. Mu 1214, udindo wa Chancellor ukaperekeka kwa mulongozgi wa sukulu. Mu 1231, ŵasambiri na ŵasambizgi ŵakazomerezgeka nga ni bungwe la masambiro.
Mu nyengo za m'ma 1200 na m'ma 1300, masukulu ghakupambanapambana agho lero ghali mu University iyi ghakamba kukhazikiskika. University yikakulira mu nyengo zakulondezgapo ndipo yikazgoka likuru la masambiro na kafukufuku.
== Umo yili kupangikira ==
University of Oxford ni sukulu yaumalilo iyo yili na makoleji ghanandi. Makoleji agha ghali na nyumba, malo ghakusambiliramo, malo ghakukhalamo ŵasambiri na maofesi ghawo. Ŵasambiri ŵakasambira pa koleji yimoza, kweni masambiro ghawo ghakovwilika na maofesi na madipatimenti gha University yose.
University iyi yili na madipatimenti ghakusambizga nkhani zakupambanapambana nga ni:
* Sayansi ya viŵaro vya munthu na vya umoyo.
* Sayansi ya physics na chemistry.
* Mbiri na mabuku.
* Masambiro gha vya ndyali na ubwezi wa vyaru.
* Masambiro gha vya chuma.
* Masambiro gha viyowoyero.
* Sayansi ya makompyuta na vya tekinoloje.
== Makoleji na nyumba zakumanyikwa ==
University of Oxford yili na makoleji ghanandi agho ghali na mbiri yakale. Ghanyake mwa agha ni Balliol College, Merton College, University College, Christ Church, Magdalen College na All Souls College.
Nyumba zakumanyikwa chomene ni izi:
=== Radcliffe Camera ===
Radcliffe Camera ni nyumba yakuzingilizga iyo yili pakati pa msumba wa Oxford. Yikuzirwa pa ntchito ya mabuku na kusunga mabuku, ndipo yili mu gulu la Bodleian Libraries.
=== Bodleian Library ===
Bodleian Library ni layibulare likuru la University of Oxford. Likujumpha vyaka vinandi kufuma apo Thomas Bodley wakayambiraso kulinozga mu 1598, ndipo likajulika mu 1602. Lili na mabuku na malemba ghakale ghanandi agho ŵakusambira ŵakugwiliskira ntchito pa kafukufuku.
=== Sheldonian Theatre ===
Sheldonian Theatre ni nyumba iyo yikugwiliskirika ntchito pa miwambo ya University, kusazgapo vyakuchitika vya masambiro na vyakupokera masatifiketi.
== Ŵanthu ŵakumanyikwa awo ŵakasambirako ==
Ŵanthu ŵanandi ŵakumanyikwa pa charu chose ŵakasambirako panji kugwira ntchito pa University of Oxford. Ŵanthu aŵa ŵakusazgapo ŵalembi, ŵanthu ŵa sayansi, ŵalongozgi ŵa boma na ŵanthu ŵa chisopa.
University iyi yili na mbiri yakukhala na ubwezi na vyaru vinandi, ndipo ŵasambiri ŵakufuma mu vyaru vyakupambanapambana ŵakusambira kwenekuko. Mfumukazi ya Japan [[Masako]] nayo wakasambira ku Balliol College kufuma mu 1988 mpaka 1990, apo wakaŵa wakusambira ku Oxford.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== University of Oxford mazuŵa ghano ==
Mazuŵa ghano University of Oxford yikupitirizga kusambizga ŵasambiri na kuchita kafukufuku mu nkhani zakupambanapambana. Yili pakati pa masukulu ghakumanyikwa chomene pa charu chose. Yikupokera ŵasambiri kufuma mu vyaru vinandi, ndipo ŵasambiri ŵake ŵakuchita masambiro gha digiri zakwamba na zakunthazi.
== Vithuzithuzi ==
<gallery>
File:Radcliffe Camera, Oxford.jpg|Radcliffe Camera.
File:The Radcliffe Camera Oxford University.jpg|Radcliffe Camera kuwoneka kufupi.
File:Radcliffe Camera revised, Oxford.jpg|Radcliffe Camera mu malo gha Oxford.
File:The Bodleian Library, Oxford.jpg|Chithuzithuzi chakale cha Bodleian Library.
File:Bodleian Library Oxford.jpg|Bodleian Library.
File:Bodleian oxford.jpg|Nyumba ya Bodleian Library na Radcliffe Camera.
File:Sheldonian Theatre, Oxford.jpg|Sheldonian Theatre.
File:Sheldonian theatre.jpg|Sheldonian Theatre iyo yili mu msumba wa Oxford.
File:Coat of arms of the University of Oxford.svg|Chimanyikwiro cha University of Oxford.
</gallery>
== Wonaniso ==
* [[Oxford]]
* [[England]]
* [[United Kingdom]]
* [[Masako]]
* [[Naruhito]]
* [[Sukulu zaumalilo]]
== Ukaboni ==
<references />
[[Category:Masukulu ghaumalilo]]
[[Category:Oxford]]
[[Category:Masambiro mu England]]
[[Category:University of Oxford]]
266xc4lwjzodpaceafrvtbuch6ad0wv
Masako
0
50352
124268
2026-11-09T20:54:11Z
Tumbuka Arch
6863
Created page with "{{Short description|Mfumukazi ya ku Japan na muwoli wa Fumu Naruhito}} [[File:Crown Princess Masako of Japan.jpg|thumb|200px|Masako apo wakaŵa mwana wa fumu uyo wakeneranga kulondezgapo chitengo.]] '''Masako''' (mu Chijapanizi: 雅子; wakababika pa 9 Disembala 1963) ni mfumukazi ya Japan ndipo ni muwoli wa Fumu [[Naruhito]]. Wakazgoka Mfumukazi ya Japan pa 1 Meyi 2019, apo mfumu wake wakakwera pa chitengo. Pambere wandatore Naruhito, Masako wakaŵa wakugwira ntchito ya..."
124268
wikitext
text/x-wiki
{{Short description|Mfumukazi ya ku Japan na muwoli wa Fumu Naruhito}}
[[File:Crown Princess Masako of Japan.jpg|thumb|200px|Masako apo wakaŵa mwana wa fumu uyo wakeneranga kulondezgapo chitengo.]]
'''Masako''' (mu Chijapanizi: 雅子; wakababika pa 9 Disembala 1963) ni mfumukazi ya Japan ndipo ni muwoli wa Fumu [[Naruhito]]. Wakazgoka Mfumukazi ya Japan pa 1 Meyi 2019, apo mfumu wake wakakwera pa chitengo. Pambere wandatore Naruhito, Masako wakaŵa wakugwira ntchito ya ubwezi wa vyaru ku Unduna wa vya Kuwaro wa Japan.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Masako wakababika pa 9 Disembala 1963. Awiske ŵakaŵa Hisashi Owada, munthu uyo wakagwiranga ntchito za boma na za ubwezi wa vyaru. Masako wakakulira mu mbumba iyo yikaŵa na ubwezi na vinthu vya masambiro na ntchito za pa charu chose.
Mu nyengo ya ubwana wake, wakakhalako ku vyaru vyakupambanapambana chifukwa cha ntchito ya awiske. Ivi vikamovwira kusambira viyowoyero na kumanya mitheto ya vyaru vinyake.
== Masambiro ==
Masako wakasambira ku vyaru vyakupambanapambana. Mu 1985, wakamalizga masambiro gha pa Harvard University ku United States, uko wakasambira vya chuma.
Mu 1986 wakamba masambiro pa University of Tokyo. Mu 1987 wakaleka masambiro agha na kwambiska ntchito ku Unduna wa vya Kuwaro wa Japan. Kufuma mu 1988 mpaka 1990, wakasambira ku Balliol College pa [[Sukulu yaumalilo ya Oxford]].<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Ntchito ya boma ==
Mu 1987, Masako wakamba kugwira ntchito ku Unduna wa vya Kuwaro wa Japan. Pa ntchito iyi wakachita vinthu vyakukhwaskana na ubwezi wa Japan na vyaru vinyake. Wakasambira ntchito za ubwezi wa vyaru na kukumana na ŵanthu ŵanandi awo ŵakimiranga maboma gha vyaru vinyake.
Mu 1993, wakaleka ntchito iyi pambere wandatore Naruhito.
== Nthengwa na Naruhito ==
Masako na Naruhito ŵakakumana apo Naruhito wakaŵa mulongozgi uyo wakeneranga kulondezgapo chitengo. Pamanyuma pa nyengo ya ubwezi, ŵakatorana pa 9 Juni 1993 ku Tokyo. Pa nyengo iyo, Naruhito wakaŵa Fumupachanya ndipo Masako wakaŵa Fumukazi yifumupachanya.
Mwana wawo mwanakazi, [[Aiko, Fumukazi ya ku Japan|Aiko]], wakababika pa 1 Disembala 2001.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Kuŵa Mfumukazi ya Japan ==
Pa 1 Meyi 2019, Naruhito wakakwera pa chitengo cha Japan pamanyuma pakuti adada ŵake Akihito ŵaleka ufumu pa 30 Epulero 2019. Masako nayo wakazgoka Mfumukazi ya Japan.
Nga ni Mfumukazi, Masako wakuchita milimo ya nyumba ya ufumu, kusazgapo kulongozga miwambo ya ufumu, kukumana na ŵalongozgi ŵa vyaru vinyake, na kuchita milimo yakovwira ŵanthu. Kweniso ni pulezidenti wa ulemu wa gulu la Japan Red Cross Society.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/about/history/history01.html |title=Their Majesties the Emperor and Empress |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Umoyo wa banja ==
Masako na Naruhito ŵali na mwana yumoza mwanakazi, Aiko. Aiko wakababika pa 1 Disembala 2001, ndipo zina lake la mu nyumba ya ufumu ni Toshi-no-Miya.
== Vithuzithuzi ==
<gallery>
File:Crown Princess Masako of Japan.jpg|Masako apo wakaŵa Fumukazi yifumupachanya.
File:Emperor Naruhito and Empress Masako.jpg|Masako na mfumu wake Naruhito.
File:Princess Masako, the present Empress of Japan.jpg|Chithuzithuzi cha Masako icho chikagwiliskirika ntchito na kazembe wa Japan.
File:Japanese Imperial Family Tree December 2024.jpg|Masako na ŵanthu ŵanyake ŵa mu nyumba ya ufumu ya Japan.
</gallery>
== Wonaniso ==
* [[Naruhito]]
* [[Akihito]]
* [[Ufumu wa Japan]]
* [[Mbiri ya Japan]]
* [[Sukulu yaumalilo ya Oxford]]
== Ukaboni ==
<references />
[[Category:Ŵanthu ŵamoyo]]
[[Category:Ŵakubabika mu 1963]]
[[Category:Ŵanthu ŵa ku Japan]]
[[Category:Mfumukazi za ku Japan]]
3svtg6taldtfif8a3eaxehs290zyxb4
Ufumu wa Japan
0
50353
124269
2026-11-09T20:54:42Z
Tumbuka Arch
6863
Created page with "{{Short description|Ndondomeko ya ufumu wa fumu ya Japan}} [[File:Imperial Palace, Tokyo JP.jpg|thumb|250px|Nyumba ya Ufumu wa Japan ku Tokyo.]] '''Ufumu wa Japan''' ni ndondomeko ya ufumu iyo yikulongozgeka na fumu ya Japan. Nyumba ya ufumu iyi yili na mbiri yitali chomene, ndipo mazuŵa ghano fumu ya Japan yikuŵa chimanyikwiro cha boma na umoza wa ŵanthu. Fumu ya sono ni [[Naruhito]], uyo wakakwera pa chitengo pa 1 Meyi 2019.<ref>{{Cite web |url=https://www.kunaicho...."
124269
wikitext
text/x-wiki
{{Short description|Ndondomeko ya ufumu wa fumu ya Japan}}
[[File:Imperial Palace, Tokyo JP.jpg|thumb|250px|Nyumba ya Ufumu wa Japan ku Tokyo.]]
'''Ufumu wa Japan''' ni ndondomeko ya ufumu iyo yikulongozgeka na fumu ya Japan. Nyumba ya ufumu iyi yili na mbiri yitali chomene, ndipo mazuŵa ghano fumu ya Japan yikuŵa chimanyikwiro cha boma na umoza wa ŵanthu. Fumu ya sono ni [[Naruhito]], uyo wakakwera pa chitengo pa 1 Meyi 2019.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/institution/seido/seido01.html |title=The Emperor |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
Mu nyengo zakale, ŵafumu ŵa Japan ŵakaŵa na mazaza ghakupambanapambana pa boma. Kweni mu nyengo zinandi za mbiri, ŵalongozgi ŵa ŵasilikari awo ŵakachemekanga [[shōgun]] ndiwo ŵakaŵa na mazaza ghakuru pa kayendeskero ka charu.
== Kwamba kwa ufumu ==
Malinga na nthano za ku Japan, ufumu wa charu ichi ukamba na Fumu Jimmu mu 660 B.C.E. Jimmu wakulongosoreka mu mabuku ghakale gha ku Japan nga ni fumu yakwamba. Kweni ŵakusambira mbiri ŵanandi ŵakuwona kuti nkhani ya Jimmu yili na vinthu vya mu nthano, ndipo palije ukaboni wakukwana wakuti wakaŵako nadi.
Mbiri iyo yili na ukaboni wakukwana chomene ya nyumba ya ufumu yikwamba mu vyaka vya m'ma 500 C.E. Mu nyengo iyi, ŵalongozgi ŵa mbumba ya Yamato ŵakaŵa na mazaza pa vigaŵa vikuruvikuru vya Japan.
== Ufumu mu nyengo zakale ==
Mu nyengo ya Nara na Heian, nyumba ya ufumu yikaŵa likuru la ndyali na mitheto ya Japan. Fumu na ŵalara ŵa ku nyumba ya ufumu ŵakendeskanga boma, ndipo ŵanthu ŵa mu nyumba ya ufumu ŵakawovwira kukura kwa mabuku, sumu, visambizgo na mitheto ya Chijapanizi.
Mu nyengo ya Kamakura, shōgun wakazgoka mulongozgi wa ŵasilikari na wa boma. Nangauli fumu yikalutilira kuŵapo ku Kyoto, shōgun ndiyo wakaŵa na mazaza ghanandi pa vinthu vya boma. Ndondomeko iyi yikalutilira mu maboma gha Ashikaga na Tokugawa.
== Masinthiro gha Meiji ==
Mu 1868, Masinthiro gha Meiji ghakasintha kayendeskero ka Japan. Mazaza gha boma ghakawelera ku nyumba ya ufumu, ndipo boma liphya likamba kusintha ndondomeko za chuma, masambiro, ŵasilikari na boma.
Mu 1889, Japan yikapoka dango liphya la nyumba ya ufumu na dango la charu. Mu nyengo iyi, fumu yikaŵa na udindo ukuru chomene mu ndondomeko ya boma. Kweni ndondomeko iyi yikasintha pamanyuma pa [[Nkhondo Yachiŵiri ya Charu Chose]].
== Ufumu wa Japan mazuŵa ghano ==
Dango la sono la Japan likamba kugwira ntchito pa 3 Meyi 1947. Mwakuyana na dango ili, fumu ni chimanyikwiro cha charu na umoza wa ŵanthu, ndipo mazaza gha boma ghakukhala na ŵanthu kwizira mu mabungwe ghawo.
Dango likulongora kuti fumu yilije mazaza gha kuwusa boma. Milimo yake ya boma yikuchitika mwakuyana na dango, ndipo yikukhumbikwira ulongozgi na kuzomerezgeka kwa Kabineti. Milimo iyi yikusazgapo kupokelera mathenga gha vyaru vinyake, kuchita miwambo ya boma na kukhazikiska paudindo nduna yikuru iyo yikusankhika na Nyumba ya Malango.<ref>{{Cite web |url=https://www.kunaicho.go.jp/en/learn/institution/seido/seido01.html |title=The Emperor |publisher=Imperial Household Agency of Japan |access-date=9 November 2026}}</ref>
== Fumu ya sono ==
Fumu ya sono ni [[Naruhito]], uyo wakababika pa 23 Febuluwale 1960. Wakakwera pa chitengo pa 1 Meyi 2019, pamanyuma pakuti adada ŵake [[Akihito]] ŵaleka udindo wa ufumu. Muwoli wake ni [[Masako]], ndipo mwana wawo mwanakazi ni Aiko.
== Nyumba ya ufumu ==
Nyumba ya Ufumu wa Japan yikukhala ku Tokyo. Malo agha ghakumanyikwa kuti Imperial Palace, ndipo ghali mu chigaŵa cha Chiyoda. Kweniso nyumba ya ufumu yili na malo ghanyake agho ghakugwiliskirika ntchito pa miwambo, kulondezga mitheto na milimo ya ŵanthu ŵa mu nyumba ya ufumu.
== Vithuzithuzi ==
<gallery>
File:Imperial Palace, Tokyo JP.jpg|Nyumba ya Ufumu wa Japan.
File:Imperial Palace in the Tokyo.jpg|Malo gha nyumba ya ufumu ku Tokyo.
File:ImperialPalaceTokyo.jpg|Chipata cha nyumba ya ufumu.
File:Emperor Naruhito and Empress Masako.jpg|Fumu Naruhito na Masako.
File:Japanese Imperial Family Tree December 2024.jpg|Mndandanda wa banja la ufumu la Japan.
</gallery>
== Wonaniso ==
* [[Japan]]
* [[Mbiri ya Japan]]
* [[Naruhito]]
* [[Akihito]]
* [[Masako]]
* [[Shōgun]]
* [[Masinthiro gha Meiji]]
== Ukaboni ==
<references />
[[Category:Ufumu wa Japan]]
[[Category:Mbiri ya Japan]]
[[Category:Nyumba za ufumu]]
9nr1343is78dm3hjjs5ys2llwpow5qi
Category:Nyumba za ufumu
14
50354
124270
2026-11-09T20:55:00Z
Tumbuka Arch
6863
Created blank page
124270
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ufumu wa Japan
14
50355
124271
2026-11-09T20:55:03Z
Tumbuka Arch
6863
Created blank page
124271
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Thessaly
0
50356
124272
2026-11-09T20:56:33Z
Tumbuka Arch
6863
Created page with "{{Short description|Chigaŵa cha pakati pa Greece icho chili na mapiri, nyanja na zigwa}} {{Infobox | above = Thessaly | image = Thessalia in Greece.svg | label1 = Charu | data1 = [[Greece]] | label2 = Likuru la boma | data2 = [[Larissa]] | label3 = Malo | data3 = Pakati pa Greece | label4 = Kukura kwa malo | data4 = Makilomita 14,036 pa sikweya | label5 = Chiŵelengero cha ŵanthu | data5 = 678,747 (2024) | label6 = Vigaŵa vya boma | data6 = Larissa, Magnesia, Karditsa..."
124272
wikitext
text/x-wiki
{{Short description|Chigaŵa cha pakati pa Greece icho chili na mapiri, nyanja na zigwa}}
{{Infobox
| above = Thessaly
| image = Thessalia in Greece.svg
| label1 = Charu
| data1 = [[Greece]]
| label2 = Likuru la boma
| data2 = [[Larissa]]
| label3 = Malo
| data3 = Pakati pa Greece
| label4 = Kukura kwa malo
| data4 = Makilomita 14,036 pa sikweya
| label5 = Chiŵelengero cha ŵanthu
| data5 = 678,747 (2024)
| label6 = Vigaŵa vya boma
| data6 = Larissa, Magnesia, Karditsa na Trikala
| label7 = Mapiri ghakuzingilizga
| data7 = [[Mapiri gha Pindus]]
}}
[[File:Thessalia in Greece.svg|thumb|right|Malo gha Thessaly mu mapu gha Greece.]]
[[File:Thessaly Plain.jpg|thumb|right|Chigaŵa cha zigwa gha Thessaly na mlonga wa Pineios.]]
[[File:Meteora -Greece- Kalambaka.jpg|thumb|right|Meteora, malo ghakumanyikwa gha ku Thessaly.]]
[[File:Ancient thessalia.PNG|thumb|right|Mapu ghakulongora Thessaly mu nyengo yakale.]]
'''Thessaly''' ni chigaŵa cha pakati pa [[Greece]]. Chigaŵa ichi chili na mapiri, zigwa, milonga, nyanja na malo gha m'mphepete mwa nyanja. Likuru la boma lake ni [[Larissa]].
Thessaly yikumanyikwa chifukwa cha ulimi, mbiri yakale ya Ŵagiriki, malo gha Meteora na mapiri agho ghali na chilengiwa chapadera.<ref name="Region">{{Cite web|url=https://thessaly.gsto.gr/en/observatory/9/destination|title=Thessaly as a Destination|website=Region of Thessaly|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Thessaly yili pakati pa Greece, pakati pa [[Mapiri gha Pindus]] na [[Nyanja ya Aegean]].
Chigaŵa ichi chili na malo ghakukwana makilomita 14,036 pa sikweya. Ndilo limoza mwa malo ghakuru gha boma la Greece.
Malo agha ghali na maonekedwe ghakupambanapambana, kusazgapo:
* Zigwa zakuzura na dongo liwemi.
* Mapiri gha Pindus.
* Mapiri gha Ossa na Pelion.
* Mlonga wa Pineios.
* Nyanja na malo ghakukhala maji.
* Mumphepete mwa nyanja ya Aegean.<ref name="Region"/>
== Vigaŵa vya boma ==
Thessaly yili na vigaŵa vinayi vikuru vya boma:
* '''Larissa''' – chigaŵa icho chili na msumba wa Larissa, likuru la Thessaly.
* '''Magnesia na Sporades''' – chigaŵa icho chili na malo gha m'mphepete mwa nyanja na visumbu vya Sporades.
* '''Karditsa''' – chigaŵa icho chili na minda na malo gha kumwera kwa Thessaly.
* '''Trikala''' – chigaŵa icho chili na msumba wa Trikala kweniso Kalabaka na Meteora.
Mwakuyana na boma la Thessaly, chigaŵa ichi chili na misumba 14 ya boma ndipo chiŵelengero cha ŵanthu ŵake chikakwana 678,747 mu 2024.<ref name="Region"/>
== Mlonga wa Pineios na zigwa ==
Mlonga wa Pineios ni mlonga wakuzirwa chomene mu Thessaly. Ukufuma mu mapiri gha Pindus na kuyenda mu chigaŵa cha zigwa, pambere undafike ku Nyanja ya Aegean.
Zigwa za Thessaly ni malo ghakuzirwa pa ulimi chifukwa dongo lake ndakwenelera kukulira vyakurya.
Ŵalimi ŵakugwiliskira ntchito malo agha kulima:
* [[Tirigu]].
* [[Chimanga]].
* [[Thonje]].
* [[Vyakumera vyamumunda]].
* [[Vipambi]].
* [[Mpunga]] mu malo ghanyake agho ngakwenelera.
Ulimi ni chimoza mwa vinthu vikuru ivyo vikovwira pa chuma cha chigaŵa ichi.<ref name="Region"/>
== Mbiri ya Thessaly ==
Thessaly yili na mbiri yakale chomene mu charu cha Greece. Mu nyengo yakale, yikaŵa chigaŵa chakuzirwa chomene pa ulimi na umo maufumu gha Ŵagiriki ghakakhaliranga.
Mu nthano za Ŵagiriki, Thessaly yikukolerana na nkhani za ŵanthu ŵakumanyikwa nga ni Achilles, Jason na ŵanthu ŵanyake awo ŵakuzunulika mu mabuku gha kale.
Mu nyengo ya Greece wakale, chigaŵa ichi chikaŵa na misumba yinandi na magulu gha ŵanthu awo ŵakaŵa na ndondomeko zawo za boma.
Pamanyuma Thessaly yikazgoka chigaŵa cha Ufumu wa Roma, ndipo yikakhalilira kuŵa yakuzirwa mu nyengo za Ufumu wa Byzantine na kuwusa kwa ŴaOttoman.
Mu 1881, chigaŵa chikuru cha Thessaly chikasazgikira mu charu cha Greece chamazuŵa ghano.<ref name="Britannica">{{Cite web|url=https://www.britannica.com/place/Thessaly|title=Thessaly|website=Encyclopaedia Britannica|access-date=9 November 2026}}</ref>
== Meteora ==
Meteora ni malo ghakumanyikwa chomene gha ku Thessaly, kufupi na [[Kalabaka]].
Malo agha ghali na malibwe ghakuru gha sandstone agho ghakuwoneka nga ni minara yakukwera kuchanya. Panyengo yakale, ŵamonke ŵakazenga nyumba za kusoperamo pa malibwe agha.
Mu 1988, Meteora yikasankhika kuŵa malo gha chiharo cha pa charu chose gha UNESCO chifukwa cha kukhumbikwa kwake pa vyaluso, visopa na chilengiwa.<ref name="UNESCO">{{Cite web|url=https://whc.unesco.org/en/list/455/|title=Meteora|website=UNESCO World Heritage Centre|access-date=9 November 2026}}</ref>
== Mapiri gha Thessaly ==
Thessaly yili na mapiri ghakupambanapambana agho ghakupangiska kuti yiŵe na chilengiwa chapadera.
[[Mapiri gha Pindus]] ghali kumanjiliro gha dazi kwa chigaŵa ichi. Mapiri gha Pelion ghali kumafumiro gha dazi, kufupi na nyanja ya Aegean.
Mapiri agha ghakupangiska kuti chigaŵa ichi chiŵe na nkhorongo, malo ghakuzirwa gha vyakumera na vinyama, kweniso malo ghakukopa ŵalendo.<ref name="Region"/>
== Chuma ==
Chuma cha Thessaly chikukolerana na ulimi, malonda, mafakitale, usodzi na ulendo wa ŵanthu.
Vyaru vya vyakumera ivyo vikukulira mu zigwa vikovwira kuti Thessaly yiŵe chigaŵa chakuzirwa pa kupanga chakulya mu Greece.
Ntchito za ulendo wa ŵanthu zikuphatikizapo kuluta ku Meteora, mapiri gha Pelion, magombe na malo ghanyake gha mbiri.<ref name="Region"/>
== Wonaniso ==
* [[Greece]]
* [[Kalabaka]]
* [[Meteora]]
* [[Larissa]]
* [[Mlonga wa Pineios]]
* [[Mapiri gha Pindus]]
* [[Nyanja ya Aegean]]
* [[Mbiri ya Greece]]
* [[Ufumu wa Roma]]
* [[Ufumu wa Byzantine]]
* [[Chilengedwe cha ku Europe]]
* [[Ulimi]]
== Ukaboni ==
<references/>
[[Category:Vigaŵa vya Greece]]
[[Category:Kakhalilo ka malo]]
[[Category:Mbiri ya Greece]]
[[Category:Vinthu vya ku Europe]]
[[Category:Vyaru vya chilengiwa]]
6gbfuprp29teovayntvfuej3ct22109
Kalabaka
0
50357
124273
2026-11-09T20:56:52Z
Tumbuka Arch
6863
Created page with "{{Short description|Mzinda wa ku Greece uwo uli musi mwa malibwe gha Meteora}} {{Infobox | above = Kalabaka | image = Meteora -Greece- Kalambaka.jpg | label1 = Charu | data1 = [[Greece]] | label2 = Chigaŵa cha boma | data2 = [[Thessaly]] | label3 = Chigaŵa chichoko | data3 = Trikala | label4 = Mlonga | data4 = [[Mlonga wa Pineios]] | label5 = Malo ghakumanyikwa pafupi | data5 = [[Meteora]] | label6 = Zina linyake | data6 = Kalambaka | label7 = Makonzedwe gha malo | dat..."
124273
wikitext
text/x-wiki
{{Short description|Mzinda wa ku Greece uwo uli musi mwa malibwe gha Meteora}}
{{Infobox
| above = Kalabaka
| image = Meteora -Greece- Kalambaka.jpg
| label1 = Charu
| data1 = [[Greece]]
| label2 = Chigaŵa cha boma
| data2 = [[Thessaly]]
| label3 = Chigaŵa chichoko
| data3 = Trikala
| label4 = Mlonga
| data4 = [[Mlonga wa Pineios]]
| label5 = Malo ghakumanyikwa pafupi
| data5 = [[Meteora]]
| label6 = Zina linyake
| data6 = Kalambaka
| label7 = Makonzedwe gha malo
| data7 = {{Coord|39|42|N|21|38|E|display=inline}}
}}
[[File:Meteora -Greece- Kalambaka.jpg|thumb|right|Mzinda wa Kalabaka pasi pa malibwe gha Meteora.]]
[[File:Meteora - Kalambaka - Greece.jpg|thumb|right|Malibwe gha Meteora agho ghakuwoneka kufupi na Kalabaka.]]
'''Kalabaka''' (panji '''Kalambaka''') ni msumba uwo uli mu chigaŵa cha [[Thessaly]] pakati pa [[Greece]]. Msumba uwu uli musi mwa malibwe ghakuru gha [[Meteora]], agho ghakumanyikwa chifukwa cha mawonekedwe ghake ghapadera na nyumba za ŵamonke izo zikazengeka pachanya pa malibwe agha.
Kalabaka ni malo ghakuzirwa gha ulendo wa ŵanthu awo ŵakuluta kukawona Meteora na kusambira vya mdauko wa Ŵagiriki.<ref name="VisitGreece">{{Cite web|url=https://www.visitgreece.gr/en/islands/thessaly/kalabaka|title=Kalabaka|website=Visit Greece|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
Kalabaka yili kumwera kwa mapiri gha Pindus, kufupi na mlonga wa Pineios. Msumba uwu uli mu chigaŵa cha Trikala, mu chigaŵa chikuru cha boma la Thessaly.
Malo agha ghali pakati pa zigwa na mapiri, ndipo malibwe ghakuru gha Meteora ghakuwoneka kufupi na msumba uwu.<ref name="VisitThessaly">{{Cite web|url=https://visitthessaly.gr/en/destinations/kalambaka-kastraki-secular-guardians-sacred-rocks|title=Kalambaka–Kastraki|website=Visit Thessaly|access-date=9 November 2026}}</ref>
== Mbiri ==
Kalabaka yili na mbiri yakale chomene. Mwakuyana na Visit Greece, malo agha ghakaŵa na msumba wakale wa Aeginion, ndipo mu nyengo za pakati pa vyaka vya m'ma 500 na 1500, malo agha ghakamanyikwanga kuti Stagi.<ref name="VisitGreece"/>
Chifukwa cha malo ghake, msumba uwu ukaŵa na ubwezi ukuru na malonda, ulendo wa ŵanthu na ntchito za ulimi.
Msumba uwu ukasinthasinthanga kuyana na ndondomeko za boma na vyakuchitika vya mu charu cha Greece mu nyengo zakupambanapambana.
== Meteora ==
Chinthu icho chikupangiska Kalabaka kuŵa yakumanyikwa chomene ni Meteora, malo agho ghali na malibwe ghakuru gha sandstone na conglomerate agho ghakuwoneka nga ghakukwera kufuma pasi.
Malibwe agha ghakapangika mu nyengo yitali kwizira mu ntchito ya maji, mphepo na kukulika kwa malibwe.
Mu vyaka vya m'ma 11, ŵanthu awo ŵakakhumbanga kukhala paŵekha kuti ŵasope ŵakamba kukhala mu mapanga na pa malibwe gha Meteora.<ref name="UNESCO">{{Cite web|url=https://whc.unesco.org/en/list/455/|title=Meteora|website=UNESCO World Heritage Centre|access-date=9 November 2026}}</ref>
== Nyumba za ŵamonke ==
Meteora yikumanyikwa chifukwa cha nyumba za ŵamonke izo zikazengeka pachanya pa malibwe.
Mu vyaka vya m'ma 14 na 15, nyumba za ŵamonke zinandi zikazengeka kuti ŵanthu ŵa visopa vya Eastern Orthodox ŵasope, kusambira na kukhala kutali na vyakuchitika vya kunja.
UNESCO yikulongosora kuti nyumba za ŵamonke 24 zikazengeka mu chigaŵa ichi. Mazuŵa ghano, zinandi zili kuleka kugwira ntchito, kweni zinyake zicali na ŵamonke awo ŵakukhala mwenemumo.<ref name="UNESCO"/>
== Chuma na ntchito za ŵanthu ==
Chuma cha Kalabaka chikukolerana chomene na ulendo wa ŵanthu awo ŵakuluta ku Meteora.
Ntchito zinyake izo zikovwira pa chuma cha msumba uwu ni:
* [[Ulendo wa ŵanthu]].
* [[Ulimi]].
* Malonda.
* Mahotela na malo ghakuguliskirako vyakurya.
* Ntchito za mayendedwe.
* Ntchito zakukolerana na nyumba za ŵamonke.
== Kalabaka mazuŵa ghano ==
Mazuŵa ghano Kalabaka yikulutilira kuŵa malo ghakuzirwa kwa ŵalendo awo ŵakufika ku Meteora. Msumba uwu uli na mahotela, malo ghakulyerako, masitolo na nthowa zakuluta ku nyumba za ŵamonke.
Malo agha ngakuzirwa pa mbiri, visopa na chilengiwa cha ku Greece.<ref name="VisitGreece"/><ref name="UNESCO"/>
== Wonaniso ==
* [[Thessaly]]
* [[Greece]]
* [[Meteora]]
* [[Mlonga wa Pineios]]
* [[Mapiri gha Pindus]]
* [[Trikala]]
* [[Visopa vya Eastern Orthodox]]
* [[Ulendo wa ŵanthu]]
== Ukaboni ==
<references/>
[[Category:Misumba ya ku Greece]]
[[Category:Vinthu vya ku Thessaly]]
[[Category:Mbiri ya Greece]]
[[Category:Malo gha chiharo cha pa charu chose]]
[[Category:Malo gha ulendo wa ŵanthu]]
6a9cq6oxwld3d85vv12ibnpg13tnnrd
Everest
0
50358
124274
2026-11-09T20:59:13Z
Tumbuka Arch
6863
Redirected page to [[Phiri la Everest]]
124274
wikitext
text/x-wiki
#REDIRECT [[Phiri la Everest]]
j13vhyz3wlth7mu5b0bzbnser8xp33z
Hummingbird
0
50359
124275
2026-11-09T20:59:43Z
Tumbuka Arch
6863
Redirected page to [[Chiyuni cha hummingbird]]
124275
wikitext
text/x-wiki
#REDIRECT [[chiyuni cha hummingbird]]
mxw1flf6ly10ty3utr884o2ik4prdhg
Pedro I of Brazil
0
50360
124276
2026-11-09T21:00:33Z
Tumbuka Arch
6863
Redirected page to [[Pedro I wa ku Brazil]]
124276
wikitext
text/x-wiki
#REDIRECT [[Pedro I wa ku Brazil]]
mr275c94vzsli90tlis8fobpvee8hir
Pedro I wa ku Brazil
0
50361
124277
2026-11-09T21:00:44Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu yakwamba ya Brazil na mulongozgi wa wanangwa wa charu ichi}} {{Infobox | above = Pedro I wa ku Brazil | image = DpedroI-brasil-full.jpg | label1 = Kubabika | data1 = 12 Okutobala 1798, Queluz, Portugal | label2 = Kufwa | data2 = 24 Seputembala 1834, Queluz, Portugal | label3 = Awiske | data3 = João VI wa ku Portugal | label4 = Amama ŵake | data4 = Carlota Joaquina wa Spain | label5 = Udindo | data5 = Fumu yakwamba ya Brazil | label6 = Nyengo ya..."
124277
wikitext
text/x-wiki
{{Short description|Fumu yakwamba ya Brazil na mulongozgi wa wanangwa wa charu ichi}}
{{Infobox
| above = Pedro I wa ku Brazil
| image = DpedroI-brasil-full.jpg
| label1 = Kubabika
| data1 = 12 Okutobala 1798, Queluz, Portugal
| label2 = Kufwa
| data2 = 24 Seputembala 1834, Queluz, Portugal
| label3 = Awiske
| data3 = João VI wa ku Portugal
| label4 = Amama ŵake
| data4 = Carlota Joaquina wa Spain
| label5 = Udindo
| data5 = Fumu yakwamba ya Brazil
| label6 = Nyengo ya kuwusa
| data6 = 1822–1831
| label7 = Charu
| data7 = [[Brazil]]
| label8 = Mbumba
| data8 = Mbumba ya Braganza
}}
[[File:DpedroI-brasil-full.jpg|thumb|right|Pedro I wa ku Brazil.]]
[[File:Pedro I of Brazil 1833.jpg|thumb|right|Chithuzithuzi cha Pedro I mu 1833.]]
[[File:Retrato de Dom Pedro I por Pedro Américo.png|thumb|right|Chithuzithuzi cha fumu Pedro I icho chikapendeka na Pedro Américo.]]
'''Pedro I wa ku Brazil''' (12 Okutobala 1798 – 24 Seputembala 1834), zina lake lose likaŵa Pedro de Alcântara Francisco António João Carlos Xavier de Paula Miguel Rafael Joaquim José Gonzaga Pascoal Cipriano Serafim, wakaŵa fumu yakwamba ya [[Brazil]] na mulongozgi wakuzirwa pa nkhani ya wanangwa wa charu ichi kufuma ku Portugal.
Wakawusa nga ni fumu ya Brazil kufuma mu 1822 mpaka mu 1831. Wakamanyikwanga so nga ni Pedro IV wa ku Portugal mu nyengo yichoko.<ref name="Senate">{{Cite web|url=https://tainacan.senado.leg.br/personalidades/d-pedro-i/|title=D. Pedro I|website=Museu do Senado Federal|access-date=9 November 2026}}</ref>
== Kubabika na umoyo wa kukwamba ==
Pedro I wakababikira mu Queluz, Portugal, pa 12 Okutobala 1798. Wakaŵa mwana wa Fumu João VI na Carlota Joaquina wa ku Spain.
Mu 1808, mbumba ya ufumu wa Portugal yikasamukira ku Brazil chifukwa cha kuwukira kwa ŵasilikari ŵa France awo ŵakalongozgekanga na [[Napoleon Bonaparte]].
Pedro wakakulira mu Brazil ndipo wakasambira vya kuwusa na milimo ya ŵasilikari.<ref name="Senate"/>
== Kukhala mu Brazil na ndyali za wanangwa ==
Mu 1821, Fumu João VI yikawelera ku Portugal ndipo Pedro wakasala mu Brazil nga ni mulongozgi wa boma.
Pa nyengo iyi, ŵanthu ŵanandi ŵa mu Brazil ŵakakhumbanga kuti charu chawo chiŵe na mazaza ghakujilamulira m'malo mwakulongozgeka na Portugal.
Boma la Portugal likakhumbanga kuti Pedro wawelere ku Portugal, kweni ŵanthu ŵanandi mu Brazil ŵakakhumbanga kuti walutilire kukhala mu charu ichi.
Mu Janyuwale 1822, Pedro wakakana kudumura ubwezi wake na Brazil na kwamba kukhazikiska ndondomeko za kujilamulira.<ref name="Senate"/>
== Kujiyimira paŵekha kwa Brazil ==
Pa 7 Seputembala 1822, Pedro wakapharazga kuti Brazil yajiyimira paŵekha kufuma ku Portugal.
Chochitika ichi chikachitika kufupi na mlonga wa Ipiranga, mu chigaŵa icho sono chili mu São Paulo.
Pamanyuma, pa 12 Okutobala 1822, wakapharazgika kuŵa Fumu ya Brazil. Wakavwalika korona pa 1 Disembala 1822.<ref name="Senate"/>
== Kuwusa nga ni fumu ==
Mu nyengo ya kuwusa kwake, Pedro I wakazenga ndondomeko ya boma la ufumu wa Brazil.
Mu 1824, dango likuru la charu likazomerezgeka, ndipo likapeleka mazaza ghanandi ku fumu.
Ndondomeko iyi yikakumananga na kususkika kufuma ku ŵanthu ŵanyake awo ŵakakhumbanga kuti vigaŵa vya charu viŵe na mazaza ghanandi.
Mu 1824, kukachitika chiwukirano cha Confederation of the Equator mu chigaŵa cha Pernambuco na vigaŵa vinyake vya kumpoto kwa Brazil.<ref name="SenateHistory">{{Cite web|url=https://www.senado.leg.br/senado/hotsites/histsf/Abdicacao-de-DPedro-I.asp|title=Abdicação de D. Pedro I e Período Regencial|website=Senado Federal|access-date=9 November 2026}}</ref>
== Kusuzgika kwa ndyali na kuleka ufumu ==
Mu nyengo yaumaliro ya kuwusa kwake, Brazil yikakumana na masuzgo gha chuma na mphindano za ndyali.
Vinthu ivi vikapangiska kuti ŵanthu ŵanandi ŵambe kususka umo Pedro I wakulongozgera charu.
Pa 7 Epulelo 1831, Pedro I wakaleka ufumu wa Brazil na kuleka udindo wake kwa mwana wake, Pedro II, uyo wakaŵa na vyaka vinkhondi pera.<ref name="SenateHistory"/>
Pamanyuma Pedro I wakawelera ku Portugal kuti wakawovwire mwana wake Maria II mu nkhondo ya ndyali ya ku Portugal.
== Kufwa ==
Pedro I wakafwira mu Queluz, Portugal, pa 24 Seputembala 1834. Wakafwa na vyaka 35.<ref name="Senate"/>
== Mbiri yake ==
Pedro I wakumbukika chomene chifukwa cha mulimo wake pa kujiyimira paŵekha kwa Brazil.
Ndipouli, nyengo yake ya kuwusa yikaŵaso na kususkika chifukwa cha umo wakalongozgeranga boma na mphindano za ndyali izo zikachitika mu charu.
== Wonaniso ==
* [[Brazil]]
* [[Portugal]]
* [[Pedro II wa ku Brazil]]
* [[João VI wa ku Portugal]]
* [[Maria Leopoldina]]
* [[Napoleon Bonaparte]]
* [[Kujiyimira paŵekha kwa Brazil]]
* [[Mbiri ya Brazil]]
* [[Ufumu wa Brazil]]
* [[Mbumba ya Braganza]]
== Ukaboni ==
<references/>
[[Category:Mafumu gha Brazil]]
[[Category:Ŵalongozgi ŵa Brazil]]
[[Category:Mbiri ya Brazil]]
[[Category:Ŵanthu ŵa m'ma 18]]
[[Category:Ŵanthu ŵa m'ma 19]]
m7gm5e8cds3fuiv32yqougmz1uuethd
Pedro II of Brazil
0
50362
124278
2026-11-09T21:01:04Z
Tumbuka Arch
6863
Redirected page to [[Pedro II wa ku Brazil]]
124278
wikitext
text/x-wiki
#REDIRECT [[Pedro II wa ku Brazil]]
5ryo1fkynw59nsqp2trmer44ml8v08t
Pedro II wa ku Brazil
0
50363
124279
2026-11-09T21:01:19Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu yachiŵiri na yaumaliro ya Ufumu wa Brazil}} {{Infobox | above = Pedro II wa ku Brazil | image = Dom Pedro II do Brasil.jpg | label1 = Kubabika | data1 = 2 Disembala 1825, Rio de Janeiro | label2 = Kufwa | data2 = 5 Disembala 1891, Paris, France | label3 = Awiske | data3 = [[Pedro I wa ku Brazil]] | label4 = Amama ŵake | data4 = Maria Leopoldina wa ku Austria | label5 = Udindo | data5 = Fumu ya Brazil | label6 = Nyengo ya kuwusa | data6 = 1831..."
124279
wikitext
text/x-wiki
{{Short description|Fumu yachiŵiri na yaumaliro ya Ufumu wa Brazil}}
{{Infobox
| above = Pedro II wa ku Brazil
| image = Dom Pedro II do Brasil.jpg
| label1 = Kubabika
| data1 = 2 Disembala 1825, Rio de Janeiro
| label2 = Kufwa
| data2 = 5 Disembala 1891, Paris, France
| label3 = Awiske
| data3 = [[Pedro I wa ku Brazil]]
| label4 = Amama ŵake
| data4 = Maria Leopoldina wa ku Austria
| label5 = Udindo
| data5 = Fumu ya Brazil
| label6 = Nyengo ya kuwusa
| data6 = 1831–1889
| label7 = Mbumba
| data7 = Mbumba ya Braganza
| label8 = Wakumutorana
| data8 = Teresa Cristina wa ku ŴaBourbon
}}
[[File:Dom Pedro II do Brasil.jpg|thumb|right|Chithuzithuzi cha Pedro II, Fumu ya Brazil.]]
[[File:Pedro II of Brazil circa 1851.jpg|thumb|right|Pedro II mu vyaka vyake vyakwambilira vya kuwusa.]]
[[File:Retrato do Imperador Dom Pedro II.jpg|thumb|right|Chithuzithuzi cha Fumu Pedro II.]]
'''Pedro II''' (2 Disembala 1825 – 5 Disembala 1891) wakaŵa fumu yachiŵiri na yaumaliro ya [[Brazil]]. Wakawusa charu ichi kufuma mu 1831 mpaka mu 1889, ndipo wakaŵa mwana wa Fumu [[Pedro I wa ku Brazil]] na Fumukazi Maria Leopoldina wa ku Austria.
Wakumanyikwa chifukwa cha nyengo yake yitali ya kuwusa, kukhozga masambiro, sayansi na vyaluso, kweniso kusintha kukuru kwa ndyali na umoyo wa ŵanthu mu Brazil.<ref name="Senate">{{Cite web|url=https://tainacan.senado.leg.br/personalidades/d-pedro-ii/|title=D. Pedro II|website=Museu do Senado Federal|access-date=9 November 2026}}</ref>
== Kubabika na ubwana ==
Pedro II wakababikira mu Rio de Janeiro pa 2 Disembala 1825. Wakaŵa mwana wa Pedro I, fumu yakwamba ya Brazil, na Maria Leopoldina.
Apo wakaŵa na vyaka vinkhondi, awiske ŵakaleka ufumu wa Brazil na kuwelelera ku Portugal. Pedro II wakasoleka kuŵa fumu ya Brazil pa 7 Epulelo 1831, kweni chifukwa cha uchoko wake, boma likalongozgekanga na ŵeruzgi awo ŵakapika mulimo wa regency.<ref name="Senate"/>
== Kwamba kuwusa yekha ==
Mu 1840, apo wakaŵa na vyaka 14, ŵanthu ŵa mu ndyali ŵakazomerezga kuti Pedro II wayambe kuwusa yekha.
Mu 1841, wakachita mwambo wa kuŵikika pa ufumu. Ivi vikamba nyengo yiphya mu mbiri ya Ufumu wa Brazil.<ref name="Imperial">{{Cite web|url=https://dami.museuimperial.museus.gov.br/handle/acervo/10142|title=D. Pedro II na kuvya kwake pa nyumba ya malango|website=Museu Imperial|access-date=9 November 2026}}</ref>
== Nyengo ya kuwusa ==
Pedro II wakawusa kwa vyaka 58, ndipo nyengo yake yikaŵa yitali chomene kuluska ya fumu yiliyose ya Brazil.
Mu nyengo iyi, Brazil yikakumana na kusintha kwa chuma, ulimi, malonda, masambiro na vyakuzenga. Nthowa za njanji zikakura, ndipo ŵanthu ŵakamba kugwiliskira ntchito matekinoloje ghaphya.
Fumu iyi yikakhozga masambiro na kafukufuku wa sayansi. Wakakondwanga chomene na mabuku, viyowoyero, sayansi na vyaluso.<ref name="Imperial"/>
== Nkhondo ya ku Paraguay ==
Mu nyengo ya kuwusa kwa Pedro II, Brazil yikanjira mu Nkhondo ya ku Paraguay, iyo yikachitika pakati pa 1864 na 1870.
Brazil yikalwa pamoza na Argentina na Uruguay kulimbana na Paraguay. Nkhondo iyi yikaŵa nkhondo yikuru chomene mu mdauko wa South America, ndipo yikakhwaska chomene chuma na umoyo wa ŵanthu ŵa mu vyaru ivyo vikachitako nkhondo.<ref name="Imperial"/>
== Kumazga wuzga ==
Mu nyengo ya Pedro II, nkhani ya kumazga wuzga yikakura chomene mu ndyali za Brazil.
Mu vyaka vya m'ma 1800, ŵanthu ŵanandi ŵakamba kulimbikira kuti wuzga umare. Boma likakhazikiska malango ghanyake ghakachepeskera wuzga.
Mu 1888, Fumukazi Isabel, mwana wa Pedro II, wakasaina Lei Áurea iyo yikamazga wuzga mu Brazil.<ref name="Lei">{{Cite web|url=https://www.gov.br/arquivonacional/pt-br/canais_atendimento/imprensa/noticias/lei-aurea-faz-parte-do-acervo-do-arquivo-nacional|title=Lei Áurea|website=Arquivo Nacional|access-date=9 November 2026}}</ref>
== Kugwa kwa ufumu ==
Mu nyengo yake yaumaliro, ufumu wa Pedro II ukakumana na suzgo la ndyali.
Mu 1889, ŵasilikari ŵakachita kusintha kwa boma uko kukamazga ufumu na kukhazikiska boma la Republic. Pa nyengo iyi, Pedro II wakachichizgika kuleka ufumu.
Pamanyuma wakaluta ku Europe ndipo wakakhala ku France mpaka apo wakafwira mu 1891.<ref name="Imperial"/>
== Mbiri yake ==
Pedro II wakumbukika nga ni fumu iyo yikawusa kwa nyengo yitali ndipo yikakhozga masambiro, sayansi na vyaluso.
Ndipouli, nyengo yake ya kuwusa yikaŵa na masuzgo ghakupambanapambana, kusazgapo wuzga, mphindano za ndyali na nkhondo.
== Wonaniso ==
* [[Brazil]]
* [[Pedro I wa ku Brazil]]
* [[Fumukazi Isabel]]
* [[Maria Leopoldina]]
* [[Nkhondo ya ku Paraguay]]
* [[Lei Áurea]]
* [[Ufumu wa Brazil]]
* [[Republic ya Brazil]]
* [[Mbiri ya Brazil]]
* [[Mbumba ya Braganza]]
== Ukaboni ==
<references/>
[[Category:Mafumu gha Brazil]]
[[Category:Ŵalongozgi ŵa Brazil]]
[[Category:Mbiri ya Brazil]]
[[Category:Ŵanthu ŵa m'ma 19]]
nvz2lmse5jifdg5fmp4792gbc3brruw
Luiz Inácio Lula da Silva
0
50364
124280
2026-11-09T21:02:05Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi wa ndyali wa Brazil uyo wasankhikaso kuŵa pulezidenti mu 2026}} {{Infobox | above = Luiz Inácio Lula da Silva | image = 30.06.2026 - Fotografia oficial.jpg | label1 = Kubabika | data1 = 27 Okutobala 1945, Garanhuns, Pernambuco, Brazil | label2 = Charu | data2 = [[Brazil]] | label3 = Ntchito | data3 = Mulongozgi wa ndyali na pulezidenti | label4 = Gulu la ndyali | data4 = Partido dos Trabalhadores | label5 = Nyengo yakwamba ya kuwusa | dat..."
124280
wikitext
text/x-wiki
{{Short description|Mulongozgi wa ndyali wa Brazil uyo wasankhikaso kuŵa pulezidenti mu 2026}}
{{Infobox
| above = Luiz Inácio Lula da Silva
| image = 30.06.2026 - Fotografia oficial.jpg
| label1 = Kubabika
| data1 = 27 Okutobala 1945, Garanhuns, Pernambuco, Brazil
| label2 = Charu
| data2 = [[Brazil]]
| label3 = Ntchito
| data3 = Mulongozgi wa ndyali na pulezidenti
| label4 = Gulu la ndyali
| data4 = Partido dos Trabalhadores
| label5 = Nyengo yakwamba ya kuwusa
| data5 = 2003–2011
| label6 = Nyengo yachiŵiri ya kuwusa
| data6 = 2023–2027
| label7 = Nyengo yachitatu yakusankhika
| data7 = 2027–2031
| label8 = Mbumba
| data8 = Ŵana ŵankhondi
}}
[[File:30.06.2026 - Fotografia oficial.jpg|thumb|right|Chithuzithuzi cha boma cha Luiz Inácio Lula da Silva mu 2026.]]
'''Luiz Inácio Lula da Silva''' (wakababika pa 27 Okutobala 1945), wakumanyikwa chomene kuti '''Lula''', ni mulongozgi wa ndyali wa ku [[Brazil]] ndipo wakateŵetera nga ni pulezidenti wa charu ichi kufuma mu 2003 mpaka 2011, kweniso kufuma mu 2023.
Mu chisankho cha pulezidenti cha pa 25 Okutobala 2026, wakasankhika so kuŵa pulezidenti pa nyengo yake ya chinayi, iyo yikwamba pa 5 Janyuwale 2027.<ref name="TSE">{{Cite web|url=https://www.tse.jus.br/comunicacao/noticias/2026/Outubro/presidente-do-tse-anuncia-reeleicao-de-lula-e-faz-balanco-do-2o-turno-das-eleicoes-2026|title=Presidente do TSE anuncia reeleição de Lula|website=Tribunal Superior Eleitoral|date=26 October 2026|access-date=9 November 2026}}</ref>
== Umoyo wa kukwamba ==
Lula wakababikira mu msumba wa Garanhuns, mu chigaŵa cha Pernambuco, pa 27 Okutobala 1945.
Wakakulira mu mbumba yakavu ndipo wali na ŵabali ŵanandi. Mu 1952, mbumba yake yikasamira ku chigaŵa cha Santos mu chigaŵa cha São Paulo kuti yipenjeso umoyo uwemi.
Apo wakaŵa mwana, wakagwirapo ntchito zakupambanapambana kuti wawovwire mbumba yake. Mu vyaka vyake vya uwukirano, wakamba kusambira ntchito ya kutembenuzga visulo na kugwira ntchito mu mafakitale.<ref name="Archive">{{Cite web|url=https://presidentes.an.gov.br/index.php/centro-de-referencia-de-acervos-presidenciais/assuntos/biografias/204-luiz-inacio-lula-da-silva|title=Luiz Inácio Lula da Silva|website=Arquivo Nacional do Brasil|access-date=9 November 2026}}</ref>
== Ntchito ya ŵantchito na kwenjira mu ndyali ==
Lula wakamba kugwira ntchito mu mafakitale gha visulo ndipo pamanyuma wakazgoka mulongozgi wa gulu la ŵantchito awo ŵakagwiranga ntchito ya visulo.
Mu 1975, wakasankhika kuŵa mulongozgi wa gulu la ŵantchito la ŵakugwira ntchito ya visulo mu São Bernardo do Campo na Diadema.
Mu vyaka vya m'ma 1970, wakalongozga ŵantchito awo ŵakakhumbanga malipiro ghawemi na malo ghawemi ghakugwirirako ntchito. Nkhondo za ŵantchito izi zikawovwira kuti wazgoke munthu wakumanyikwa mu ndyali za Brazil.<ref name="Archive"/>
== Kukhazikiska gulu la Workers' Party ==
Mu 1980, Lula wakaŵa pakati pa ŵanthu awo ŵakakhazikiska gulu la ndyali la Partido dos Trabalhadores (PT).
Gulu ili likalutilira kukura ndipo likazgoka gulu likuru la ndyali mu Brazil.
Lula wakaluta ku chisankho cha pulezidenti kanandi pambere wandapambane mu 2002.<ref name="Archive"/>
== Nyengo yakwamba ya kuwusa ==
Lula wakamba kuwusa pa 1 Janyuwale 2003. Mu nyengo yake yakwamba, boma lake likakhazikiska ndondomeko zakupambana pa nkhani ya kuchepeska ukavu, kusazgirako mwaŵi wa masambiro na kuwovwira mbumba zakavu.
Ndondomeko yakumanyikwa chomene yikaŵa Bolsa Família, iyo yikapelekanga chovwiro cha ndalama ku mbumba zakavu izo zikakwaniriskanga fundo zakukhwaskana na masambiro na umoyo wa ŵana.
Wakasankhikaso mu 2006 ndipo wakalutilira kuwusa m'paka pa 1 Janyuwale 2011.<ref name="Archive"/>
== Kuwelelanso ku boma mu 2023 ==
Pamanyuma pa nyengo iyo wakaleka kuwusa, Lula wakalutilira kuŵa mulongozgi wa ndyali.
Mu 2022, wakathereska chisankho cha pulezidenti ndipo wakamba nyengo yake yachiŵiri ya kuwusa pa 1 Janyuwale 2023.
Boma lake likalutilira kulimbikira pa nkhani za chuma, ntchito, masambiro, chivikiliro cha chilengiwa, na ubwezi wa Brazil na vyaru vinyake.<ref name="Archive"/>
== Chisankho cha 2026 ==
Mu chisankho cha pulezidenti cha mu Okutobala 2026, Lula wakasangananga na Flávio Bolsonaro mu chigaŵa chachiŵiri cha chisankho.
Pa 25 Okutobala 2026, Tribunal Superior Eleitoral yikapharazga kuti Lula wathereska chisankho na mavoti 64,256,232, agho ghakaŵa 51.79 peresenti ya mavoti ghakuzomerezgeka. Flávio Bolsonaro wakapokera mavoti 59,826,041.<ref name="TSE"/>
Lula wasankhika kuŵa pulezidenti pa nyengo yake ya chinayi, iyo yikwamba pa 5 Janyuwale 2027.<ref>{{Cite web|url=https://www12.senado.leg.br/noticias/materias/2026/10/25/lula-e-reeleito-para-quarto-mandato-de-presidente|title=Lula é reeleito para quarto mandato de presidente|website=Senado Federal|date=25 October 2026|access-date=9 November 2026}}</ref>
== Mbiri yake mu ndyali ==
Lula ni yumoza wa ŵalongozgi ŵakumanyikwa chomene mu mdauko wa Brazil. Wakafuma mu ntchito ya mafakitale na kuŵa mulongozgi wa gulu la ŵantchito, ndipo pamanyuma wakazgoka pulezidenti wa charu.
Nyengo zake za kuwusa zikakolerana na kusintha kwa chuma, ndondomeko za kuchepeska ukavu, kusintha kwa maboma na mphindano za ndyali.
== Wonaniso ==
* [[Brazil]]
* [[Mbiri ya Brazil]]
* [[Getúlio Vargas]]
* [[Partido dos Trabalhadores]]
* [[Ŵapulezidenti ŵa Brazil]]
* [[Ndondomeko za ŵantchito]]
* [[Bolsa Família]]
* [[Demokilase]]
* [[Chisankho cha pulezidenti wa Brazil cha 2026]]
* [[Flávio Bolsonaro]]
* [[São Paulo]]
== Ukaboni ==
<references/>
[[Category:Ŵapulezidenti ŵa Brazil]]
[[Category:Ŵanthu ŵa ndyali]]
[[Category:Mbiri ya Brazil]]
[[Category:Ŵanthu ŵa m'ma 20]]
[[Category:Ŵanthu ŵa m'ma 21]]
rs2ewygscsjnx7cwo1ky41a75uqztkj
Getúlio Vargas
0
50365
124281
2026-11-09T21:02:25Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi wa Brazil uyo wakawusa mu nyengo ziŵiri pakati pa 1930 na 1954}} {{Infobox | above = Getúlio Vargas | image = Getúlio Vargas - retrato oficial de 1930.JPG | label1 = Kubabika | data1 = 19 Epulelo 1882, São Borja, Brazil | label2 = Kufwa | data2 = 24 Ogasiti 1954, Rio de Janeiro | label3 = Charu | data3 = [[Brazil]] | label4 = Ntchito | data4 = Mulongozgi wa ndyali na pulezidenti | label5 = Nyengo yakwamba ya kuwusa | data5 = 1930–1945..."
124281
wikitext
text/x-wiki
{{Short description|Mulongozgi wa Brazil uyo wakawusa mu nyengo ziŵiri pakati pa 1930 na 1954}}
{{Infobox
| above = Getúlio Vargas
| image = Getúlio Vargas - retrato oficial de 1930.JPG
| label1 = Kubabika
| data1 = 19 Epulelo 1882, São Borja, Brazil
| label2 = Kufwa
| data2 = 24 Ogasiti 1954, Rio de Janeiro
| label3 = Charu
| data3 = [[Brazil]]
| label4 = Ntchito
| data4 = Mulongozgi wa ndyali na pulezidenti
| label5 = Nyengo yakwamba ya kuwusa
| data5 = 1930–1945
| label6 = Nyengo yachiŵiri
| data6 = 1951–1954
| label7 = Gulu la ndyali
| data7 = Partido Trabalhista Brasileiro
}}
[[File:Getúlio Vargas - retrato oficial de 1930.JPG|thumb|right|Getúlio Vargas mu 1930.]]
[[File:Getúlio Vargas.jpg|thumb|right|Getúlio Vargas mu nyengo yake ya kuwusa ya mu 1951.]]
'''Getúlio Dornelles Vargas''' (19 Epulelo 1882 – 24 Ogasiti 1954) wakaŵa mulongozgi wa ndyali na pulezidenti wa [[Brazil]]. Wakawusa charu ichi kufuma mu 1930 m'paka 1945, kweniso kufuma mu 1951 m'paka 1954.
Vargas wakaŵa munthu wakuzirwa chomene mu mdauko wa ndyali za Brazil mu vyaka vya m'ma 1900. Wakakhazikiska kusintha kukuru pa ntchito, mafakitale na ndondomeko za boma, kweniso wakalongozga boma la mazaza gha munthu yumoza mu nyengo ya Estado Novo.<ref name="FGV">{{Cite web|url=https://cpdoc.fgv.br/biografias/getulio-vargas|title=Getúlio Vargas|website=Fundação Getulio Vargas – CPDOC|access-date=9 November 2026}}</ref>
== Umoyo wa kukwamba ==
Vargas wakababikira mu msumba wa São Borja, mu chigaŵa cha Rio Grande do Sul ku Brazil, pa 19 Epulelo 1882.
Wakasambira vya malango na kwamba ntchito yake mu ndyali. Wakaŵa wa gulu la ndyali la Partido Republicano Rio-Grandense, ndipo wakasankhika kuŵa membala wa nyumba yakwimira ŵanthu ya chigaŵa chake.
Mu nyengo yakulondezgapo wakateŵetera mu maofesi gha boma na kuzgoka minisita wa vya ndalama mu boma la Washington Luís.<ref name="Arquivo">{{Cite web|url=https://presidentes.an.gov.br/index.php/centro-de-referencia-de-acervos-presidenciais/assuntos/biografias/179-getulio-dorneles-vargas|title=Getúlio Dornelles Vargas|website=Arquivo Nacional do Brasil|access-date=9 November 2026}}</ref>
== Kwenjira mu mazaza mu 1930 ==
Mu 1929, Vargas wakasankhika kuŵa wakimirira wa gulu la Aliança Liberal pa chisankho cha pulezidenti wa Brazil.
Wakataya chisankho ichi, kweni wakalongozga kusintha kwa boma mu 1930 uko kukamazga boma la Washington Luís.
Pa 3 Novembala 1930, Vargas wakatora udindo wa mulongozgi wa boma lakale. Wakamba kusintha ndondomeko za boma ndipo wakasankha ŵanthu ŵake kulongozga vigaŵa vya boma.<ref name="Arquivo"/>
== Boma lake lakwamba ==
Mu nyengo yakwamba ya kuwusa kwake, Vargas wakakhazikiska maofesi ghaphya na kusintha malango gha ntchito.
Mu 1934, wakasankhika kuŵa pulezidenti mwakuyana na dango liphya la charu.
Kweni ndyali za mu Brazil zikalutilira kuŵa na mphindano pakati pa magulu ghakupambanapambana. Mu 1935, kukachitika chiwukirano cha ŵanthu ŵa gulu la Communist ku vigaŵa vinyake vya charu.<ref name="FGV"/>
== Estado Novo ==
Pa 10 Novembala 1937, Vargas wakakhazikiska boma ilo likamanyikwanga kuti Estado Novo.
Boma ili likapeleka mazaza ghanandi kwa pulezidenti, likazgora nyumba ya malango kuti yigwire ntchito yayi, ndipo likakanizga magulu gha ndyali.
Mu nyengo iyi, boma likakhazikiska mabungwe gha mafakitale, kusazgapo Companhia Siderúrgica Nacional na maofesi ghanyake gha ntchito za vyuma.
Vargas wakakhozga fundo ya kuti boma liŵe na udindo ukuru pa kukura kwa mafakitale na chuma cha charu.<ref name="FGV"/>
== Brazil mu Nkhondo Yachiŵiri ya pa Charu Chose ==
Mu nyengo yakwamba ya [[Nkhondo Yachiŵiri ya pa Charu Chose]], Brazil yikalutilira kuŵa pa mbali ya vyaru ivyo vikayezganga kuleka kunjizgika mu nkhondo.
Kweni pamanyuma pa 1942, Brazil yikayowoya kuti yili pa nkhondo na vyaru vya gulu la Axis, ivyo vikasazgapo Germany, Italy na Japan.
Boma la Vargas likatuma ŵasilikari ŵa Brazil kukachita nkhondo ku Italy. Ŵasilikari aŵa ŵakamanyikwanga kuti Força Expedicionária Brasileira.<ref name="FGV"/>
== Kuleka mazaza mu 1945 ==
Mu 1945, ŵanthu ŵanandi ŵakamba kupempha kuti boma liwelere ku ndondomeko ya demokilase.
Vargas wakachichizgika kuleka mazaza pa 29 Okutobala 1945. Pamanyuma wakalutilira kugwira ntchito mu ndyali ndipo wakasankhika kuŵa seneta.
== Kuwelelanso mu udindo wa pulezidenti ==
Mu 1950, Vargas wakaluta ku chisankho cha pulezidenti ndipo wakathereska ŵalwani ŵake.
Wakamba nyengo yake yachiŵiri pa 31 Janyuwale 1951. Pa nyengo iyi wakakhozga fundo za chuma cha boma na kusunga mazaza gha charu pa vinthu vyakuzirwa.
Chinthu chakuzirwa icho chikachitika mu nyengo iyi chikaŵa kukhazikiskika kwa Petrobras mu 1953, kampani ya mafuta ya boma.<ref name="FGV"/>
== Umaliro wa kuwusa kwake ==
Mu 1954, boma la Vargas likakumana na suzgo likuru la ndyali. Ŵalwani ŵake ŵakamukakamizga kuti waleke udindo wa pulezidenti.
Pa 24 Ogasiti 1954, Vargas wakafwira mu Rio de Janeiro apo wakaŵa kuti wachali pulezidenti.<ref name="Arquivo"/>
== Mbiri yake ==
Vargas wakakhwaska chomene mbiri ya Brazil. Wakasintha ndondomeko za ntchito, mafakitale, chuma na umo boma likulongozgekera.
Kweni nyengo yake ya kuwusa yikaŵaso na kuŵa kwa boma lakusuzga ŵalwani ŵake, kujalika kwa mabungwe gha ndyali na kuchepeska wanangwa wa kuyowoya.
Ntheura, mbiri yake yikusazgapo kusintha kwa chuma na ntchito kweniso masuzgo gha demokilase.<ref name="FGV"/>
== Wonaniso ==
* [[Brazil]]
* [[Mbiri ya Brazil]]
* [[Estado Novo]]
* [[Nkhondo Yachiŵiri ya pa Charu Chose]]
* [[Petrobras]]
* [[Demokilase]]
* [[Ndondomeko za ntchito]]
* [[Ŵalongozgi ŵa Brazil]]
* [[Ndyali za ku South America]]
== Ukaboni ==
<references/>
[[Category:Ŵapulezidenti ŵa Brazil]]
[[Category:Ŵanthu ŵa ndyali]]
[[Category:Mbiri ya Brazil]]
[[Category:Ŵanthu ŵa m'ma 20]]
ndhxhw27ywx92vhj1uxks808koxc28t
Nkhondo Yachiŵiri ya pa Charu Chose
0
50366
124282
2026-11-09T21:07:38Z
Tumbuka Arch
6863
Redirected page to [[Nkhondo Yachiŵiri ya Charu Chose]]
124282
wikitext
text/x-wiki
#REDIRECT [[Nkhondo Yachiŵiri ya Charu Chose]]
ibu95hfl1twauma0bw6t5pl8lhoc2g8
Category:Ŵanthu ŵa ndyali
14
50367
124283
2026-11-09T21:08:47Z
Tumbuka Arch
6863
Created blank page
124283
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵapulezidenti ŵa Brazil
14
50368
124284
2026-11-09T21:08:51Z
Tumbuka Arch
6863
Created blank page
124284
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya Brazil
14
50369
124285
2026-11-09T21:08:55Z
Tumbuka Arch
6863
Created blank page
124285
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Lei Áurea
0
50370
124286
2026-11-09T21:09:59Z
Tumbuka Arch
6863
Created page with "{{Short description|Dango la mu 1888 ilo likamazga wuzga mu Brazil}} {{Infobox | above = Lei Áurea | image = Lei Áurea.jpg | label1 = Zina la dango | data1 = Dango nambala 3,353 | label2 = Zuŵa ilo likasayinika | data2 = 13 Meyi 1888 | label3 = Charu | data3 = [[Brazil]] | label4 = Uyo wakasaina | data4 = Fumukazi Isabel | label5 = Fumu pa nyengo iyi | data5 = [[Pedro II wa ku Brazil]] | label6 = Mulimo | data6 = Kumazga wuzga | label7 = Malo ghakusungirako chikalata..."
124286
wikitext
text/x-wiki
{{Short description|Dango la mu 1888 ilo likamazga wuzga mu Brazil}}
{{Infobox
| above = Lei Áurea
| image = Lei Áurea.jpg
| label1 = Zina la dango
| data1 = Dango nambala 3,353
| label2 = Zuŵa ilo likasayinika
| data2 = 13 Meyi 1888
| label3 = Charu
| data3 = [[Brazil]]
| label4 = Uyo wakasaina
| data4 = Fumukazi Isabel
| label5 = Fumu pa nyengo iyi
| data5 = [[Pedro II wa ku Brazil]]
| label6 = Mulimo
| data6 = Kumazga wuzga
| label7 = Malo ghakusungirako chikalata
| data7 = Arquivo Nacional do Brasil
}}
[[File:Lei Áurea.jpg|thumb|right|Chikalata cha Lei Áurea icho chikasayinika pa 13 Meyi 1888.]]
[[File:Pintura sobre a primeira missa no Brasil.jpg|thumb|right|Chithuzithuzi cha mbiri ya ŵanthu ŵa ku Brazil; ni chakale kuluska nyengo ya Lei Áurea ndipo chikulongora nkhani ya kukhazikiskika kwa Chikhristu mu charu ichi.]]
'''Lei Áurea''' (Dango la Golide) ni dango ilo likamazga wuzga mu [[Brazil]]. Dango ili likasayinika pa 13 Meyi 1888 na Fumukazi Isabel, uyo pa nyengo iyo wakateŵetanga nga ni mulongozgi wa charu m'malo mwa awiske, Fumu [[Pedro II wa ku Brazil]].
Dango ili likaŵa na nambala 3,353 ndipo likamazga mwakuzomerezgeka wuzga uwo ukachitikanga mu Brazil. Brazil yikaŵa charu chaumaliro chakujiyimira paŵekha mu America kukamazga mwakuzomerezgeka wuzga.<ref name="Arquivo">{{Cite web|url=https://www.gov.br/arquivonacional/pt-br/canais_atendimento/imprensa/noticias/lei-aurea-faz-parte-do-acervo-do-arquivo-nacional|title=Lei Áurea faz parte do acervo do Arquivo Nacional|website=Arquivo Nacional|access-date=9 November 2026}}</ref>
== Mbiri ya wuzga mu Brazil ==
Wuzga mu Brazil ukamba mu nyengo ya kuwusa kwa Portugal. Ŵanthu ŵanandi ŵakakoleka mu vyaru vya ku Africa ndipo ŵakazengeka kukatumizgika ku America kuti ŵakagwire ntchito mwakuchichizgika.
Ŵanthu awo ŵakatolekera ku Brazil ŵakagwira ntchito mu minda ya [[shuga]], migodi ya golide, minda ya [[khofi]] na ntchito zinyake.
Wuzga uwu ukalutilira kwa vyaka vinandi ndipo ukakhwaska chomene umoyo wa ŵanthu ŵa ku Brazil na mbiri ya charu ichi.<ref name="Arquivo"/>
== Kulimbana na wuzga ==
Mu vyaka vya m'ma 1800, gulu la ŵanthu awo ŵakakhumbanga kumazga wuzga likakura chomene mu Brazil.
Ŵanthu ŵa magulu ghakupambanapambana ŵakamba kukhozgera wanangwa wa ŵanthu awo ŵakaŵa mu wuzga. Ŵanyake ŵakachitanga ntchito ya kuphalira ŵanthu, kulemba mu manyuzipepara, kunozga vyakuchitika na kovwira ŵanthu awo ŵakafumanga mu wuzga.
Pa nyengo iyi, boma likakhazikiska malango ghanyake agho ghakachepeskanga wuzga:
* '''Dango la Eusébio de Queirós (1850)''' – likakanizga malonda gha ŵanthu ŵakukoleka ku Brazil.
* '''Dango la Free Womb (1871)''' – likayowoya vya wana awo ŵakababikanga kwa ŵanakazi ŵa mu wuzga.
* '''Dango la Ŵanthu Ŵakukota (1885)''' – likapeleka wanangwa ku ŵanthu ŵanyake ŵa mu wuzga awo ŵakaŵa na vyaka vinandi.<ref name="Arquivo"/>
== Kusayinika kwa Lei Áurea ==
Pa 13 Meyi 1888, Fumukazi Isabel wakasaina dango nambala 3,353 mu Rio de Janeiro.
Dango ili likaŵa na fundo ziŵiri zikuru. Fundo yakwamba yikati wuzga wamara mu Brazil kufuma pa zuŵa ilo dango ili likasainikira. Fundo yachiŵiri yikamazga malango ghose agho ghakasuskanga dango ili.<ref name="Legislation">{{Cite web|url=https://www2.camara.leg.br/legin/fed/leimp/1824-1899/lei-3353-13-maio-1888-533138-publicacaooriginal-16269-pl.html|title=Lei n.º 3.353, de 13 de maio de 1888|website=Câmara dos Deputados|access-date=9 November 2026}}</ref>
== Ivyo vikachitika pamanyuma ==
Kumara kwa wuzga kukasintha umoyo wa ŵanthu ŵanandi. Ŵanthu awo ŵakaŵa mu wuzga ŵakazgoka na wanangwa wakukhala nga ni ŵanthu ŵambura kukakika na malango gha wuzga.
Kweni dango ili likapeleka yayi ndondomeko zakukwana za malo, nyumba, ntchito, masambiro na katundu ku ŵanthu awo ŵakafumanga mu wuzga.
Ntheura, nangauli wuzga ukamara pa dango, ŵanthu ŵanandi awo ŵakafumanga mu wuzga ŵakalutilira kukumana na kusankhana, ukavu na masuzgo ghanyake mu charu cha Brazil.
== Kukhumbikwa kwa dango ==
Lei Áurea ni chimoza mwa vyakuchitika vyakuzirwa chomene mu mdauko wa Brazil. Dango ili likamalizga ndondomeko ya kuwusa ŵanthu nga ni katundu mwakuzomerezgeka na boma.
Chikalata cheneko cha dango ili chikusungika mu National Archives ya Brazil. Mu 2008, chikalata ichi chikasazgikira mu ndondomeko ya UNESCO ya kusungilira vyikalata vyakuzirwa pa mdauko wa ŵanthu.<ref name="Arquivo"/>
== Wonaniso ==
* [[Wuzga]]
* [[Brazil]]
* [[Fumukazi Isabel]]
* [[Pedro II wa ku Brazil]]
* [[Gulu la kumazga wuzga]]
* [[Mbiri ya Brazil]]
* [[Ŵanthu ŵa ku Africa awo ŵakatolekera ku America]]
* [[Dango]]
* [[Wanangwa wa ŵanthu]]
* [[UNESCO]]
== Ukaboni ==
<references/>
[[Category:Mbiri ya Brazil]]
[[Category:Malango gha Brazil]]
[[Category:Wuzga]]
[[Category:1888]]
[[Category:Kumazga wuzga]]
8kxtcw31j2ivvnrt3pb1udg96yypc7k
Napoleon Bonaparte
0
50371
124287
2026-11-09T21:10:22Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi wa ŵasilikari na fumu ya ku France pakati pa 1804 na 1814}} {{Infobox | above = Napoleon Bonaparte | image = Napoleon Bonaparte.jpg | label1 = Kubabika | data1 = 15 Ogasiti 1769, Ajaccio, Corsica | label2 = Kufwa | data2 = 5 Meyi 1821, Saint Helena | label3 = Charu | data3 = [[France]] | label4 = Udindo | data4 = Fumu ya ŴaFrance | label5 = Nyengo ya kuwusa | data5 = 1804–1814 na 1815 | label6 = Wakutorana nayo | data6 = Joséphine de B..."
124287
wikitext
text/x-wiki
{{Short description|Mulongozgi wa ŵasilikari na fumu ya ku France pakati pa 1804 na 1814}}
{{Infobox
| above = Napoleon Bonaparte
| image = Napoleon Bonaparte.jpg
| label1 = Kubabika
| data1 = 15 Ogasiti 1769, Ajaccio, Corsica
| label2 = Kufwa
| data2 = 5 Meyi 1821, Saint Helena
| label3 = Charu
| data3 = [[France]]
| label4 = Udindo
| data4 = Fumu ya ŴaFrance
| label5 = Nyengo ya kuwusa
| data5 = 1804–1814 na 1815
| label6 = Wakutorana nayo
| data6 = Joséphine de Beauharnais; Marie Louise
| label7 = Mulimo
| data7 = Mulongozgi wa ŵasilikari na ndyali
}}
[[File:Napoleon Bonaparte.jpg|thumb|right|Chithuzithuzi cha Napoleon Bonaparte icho chikapendeka na Jacques-Louis David.]]
[[File:Napoleon Bonaparte 1812.jpg|thumb|right|Napoleon mu nyengo iyo wakaŵa fumu ya ŴaFrance.]]
'''Napoleon Bonaparte''' (15 Ogasiti 1769 – 5 Meyi 1821) wakaŵa mulongozgi wa ŵasilikari na ndyali wa ku [[France]] uyo wakazgoka fumu ya ŴaFrance pakati pa 1804 na 1814, kweniso mu nyengo yichoko ya 1815.
Wakumanyikwa chifukwa cha nkhondo izo wakalongozga mu vyaru vya ku Europe, kusintha ndondomeko za boma la France na kukhazikiska malango agho ghakaŵa na nkhongono pa mdauko wa vyaru vinandi.<ref name="NapoleonOrg">{{Cite web|url=https://www.napoleon.org/en/young-historians/napodoc/imperial-family-tree/|title=Imperial Family Tree: Napoleon I|website=Fondation Napoléon|access-date=9 November 2026}}</ref>
== Umoyo wa kukwamba ==
Napoleon wakababikira mu msumba wa Ajaccio pa chirwa cha Corsica pa 15 Ogasiti 1769. Pa nyengo iyo wakababikira, Corsica yikaŵa kuti yafuma waka mu kuwusa kwa Republic ya Genoa na kwamba kuŵa pasi pa France.
Wakafuma mu mbumba ya ŵanthu ŵa ku Corsica ndipo wakaŵa na ŵabali ŵanandi. Apo wakaŵa mwana, wakatumizgika ku France kukasambira vya ŵasilikari.
Wakasambira ku masukulu gha ŵasilikari, ndipo wakakhazikika pa vya kugwiliskira ntchito mfuti na ulongozgi wa ŵasilikari.<ref name="NapoleonTimeline">{{Cite web|url=https://www.napoleon.org/en/young-historians/napodoc/timeline-consulate1st-french-empire/|title=Timeline: Consulate and First French Empire|website=Fondation Napoléon|access-date=9 November 2026}}</ref>
== Ntchito ya ŵasilikari ==
Napoleon wakamba kumanyikwa chomene mu nyengo ya [[French Revolution]], iyo yikamba mu 1789.
Wakakwera mwaluŵiro pa udindo wa ŵasilikari chifukwa cha maluso ghake pa nkhondo. Mu vyaka vya m'ma 1790, wakalongozga ŵasilikari ŵa France mu nkhondo za ku Italy na ku Egypt.
Viwiro vyake pa nkhondo vikamovwira kuti wazgoke munthu wakumanyikwa chomene mu ndyali za France.<ref name="NapoleonOrg"/>
== Kukora mazaza mu France ==
Pa 9 Novembala 1799, Napoleon wakalongozga kusintha kwa boma uko kukamazga ndondomeko ya boma lakulongozgeka na ŵanthu ŵakujinikizga na kwamba nyengo ya Consulate.
Wakazgoka First Consul, ndipo wakakura mazaza ghake mu boma.
Mu nyengo iyi, wakakhazikiska kusintha kwa malango, ndalama, masukulu, maofesi gha boma na ndondomeko ya milandu.
Mu 1804, wakajivwalika korona na kuzgoka Napoleon I, Fumu ya ŴaFrance.<ref name="NapoleonTimeline"/>
== Kusintha kwa boma na malango ==
Chinthu chakuzirwa chomene icho chikafuma mu kuwusa kwake chikaŵa kukhazikiskika kwa Civil Code, iyo yikumanyikwakoso kuti Napoleonic Code.
Malango agha ghakanozga umo ŵanthu ŵakeneranga kulongozgekera pa nkhani za katundu, mbumba, mapangano na milandu ya pa charu.
Ndondomeko za Napoleon zikakhwaska chomene vyaru vya ku Europe, ndipo vyaru vinyake vikatora vigaŵa vya malango ghake panji kusintha boma lawo mwakuyana na ndondomeko izo zikakhazikiskika mu nyengo yake.<ref name="NapoleonOrg"/>
== Nkhondo za Napoleon ==
Napoleon wakalongozga nkhondo zinandi izo zikakhwaska vyaru vinandi vya ku Europe. Nkhondo izi zikamanyikwa kuti Nkhondo za Napoleon.
Ŵalwani ŵake ŵakasazgapo:
* [[Great Britain]].
* [[Austria]].
* [[Prussia]].
* [[Russia]].
* [[Spain]].
* [[Portugal]].
Mu 1805, Napoleon wakathereska ŵasilikari ŵa Austria na Russia pa Nkhondo ya Austerlitz.
Mu 1812, wakalongozga ŵasilikari ŵanandi kuluta ku Russia. Ulendo uwu ukamara na kutayika kukuru kwa ŵasilikari ŵake chifukwa cha nkhondo, njara, nyengo yakuzizima na masuzgo gha vyakurya.<ref name="NapoleonOrg"/>
== Kugwa kwa ufumu wake ==
Mu 1814, ŵasilikari ŵakukolerana ŵa vyaru vya ku Europe ŵakathereska Napoleon ndipo wakachichizgika kuleka mazaza. Wakatumizgika ku chirwa cha Elba mu nyanja ya Mediterranean.
Mu Malichi 1815, wakawelera ku France ndipo wakambaso kuwusa. Nyengo iyi yikumanyikwa kuti Masiku 100.
Pa 18 Juni 1815, ŵasilikari ŵake ŵakathereskeka pa Nkhondo ya Waterloo mu Belgium. Pamanyuma pa kuthera uku, wakaleka mazaza ndipo wakatumizgika ku chirwa cha Saint Helena mu nyanja ya Atlantic.<ref name="NapoleonEnd">{{Cite web|url=https://www.napoleon.org/en/young-historians/napodoc/in-the-footsteps-of-napoleon-i/|title=In the footsteps of Napoleon I|website=Fondation Napoléon|access-date=9 November 2026}}</ref>
== Kufwa kwake ==
Napoleon wakakhala ku Saint Helena kufuma mu 1815 m'paka apo wakafwira pa 5 Meyi 1821. Wakabikika mu chirwa ichi, kweni vyakufumapo vyake vikawelereskeka ku France mu 1840.
Mazuŵa ghano mabwinja ghake ghakusungika ku Les Invalides mu Paris.<ref name="NapoleonEnd"/>
== Mbiri yake ==
Napoleon ni munthu uyo wakakhwaska chomene mdauko wa Europe. Ndondomeko zake za boma na malango zikawovwira kusintha vyaru vinandi.
Ndipouli, kuwusa kwake kukakolerana na nkhondo zikuru, kukura kwa ufumu wa France, kuwukira kwa vyaru vinyake na kutayika kwa umoyo wa ŵanthu ŵanandi.
== Wonaniso ==
* [[France]]
* [[French Revolution]]
* [[Nkhondo za Napoleon]]
* [[Nkhondo ya Waterloo]]
* [[Nkhondo ya Austerlitz]]
* [[Napoleonic Code]]
* [[Saint Helena]]
* [[Corsica]]
* [[Mbumba ya Bonaparte]]
* [[Mbiri ya France]]
== Ukaboni ==
<references/>
[[Category:Ŵalongozgi ŵa France]]
[[Category:Ŵasilikari ŵa France]]
[[Category:Mbiri ya France]]
[[Category:Ŵanthu ŵa m'ma 18]]
[[Category:Ŵanthu ŵa m'ma 19]]
lo45dwu2y4qnum6983kglz5yy33j1p1
Category:Ŵalongozgi ŵa France
14
50372
124288
2026-11-09T21:10:49Z
Tumbuka Arch
6863
Created blank page
124288
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵasilikari ŵa France
14
50373
124289
2026-11-09T21:10:53Z
Tumbuka Arch
6863
Created blank page
124289
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya France
14
50374
124290
2026-11-09T21:10:56Z
Tumbuka Arch
6863
Created blank page
124290
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
São Vicente, São Paulo
0
50375
124291
2026-11-09T21:11:27Z
Tumbuka Arch
6863
Created page with "{{Short description|Mzinda wa m'mphepete mwa nyanja mu chigaŵa cha São Paulo ku Brazil}} {{Infobox | above = São Vicente | image = São Vicente.PNG | label1 = Charu | data1 = [[Brazil]] | label2 = Chigaŵa cha boma | data2 = [[São Paulo (chigaŵa)]] | label3 = Malo | data3 = Mumphepete mwa nyanja ya Atlantic | label4 = Kwambiska msumba | data4 = 22 Janyuwale 1532 | label5 = Wakuwona na kukhazikiska msumba | data5 = Martim Afonso de Sousa | label6 = Malo | data6 = Mak..."
124291
wikitext
text/x-wiki
{{Short description|Mzinda wa m'mphepete mwa nyanja mu chigaŵa cha São Paulo ku Brazil}}
{{Infobox
| above = São Vicente
| image = São Vicente.PNG
| label1 = Charu
| data1 = [[Brazil]]
| label2 = Chigaŵa cha boma
| data2 = [[São Paulo (chigaŵa)]]
| label3 = Malo
| data3 = Mumphepete mwa nyanja ya Atlantic
| label4 = Kwambiska msumba
| data4 = 22 Janyuwale 1532
| label5 = Wakuwona na kukhazikiska msumba
| data5 = Martim Afonso de Sousa
| label6 = Malo
| data6 = Makilomita 147.774 pa sikweya
| label7 = Chiŵelengero cha ŵanthu
| data7 = 329,911 (2022)
| label8 = Makonzedwe gha malo
| data8 = {{Coord|23|57|46|S|46|23|31|W|display=inline}}
}}
[[File:São Vicente.PNG|thumb|right|Chimanyikwiro cha boma la São Vicente.]]
[[File:Praia de São Vicente - Santos - Brasil.JPG|thumb|right|Gombe la mumphepete mwa nyanja ku São Vicente.]]
[[File:São Vicente - Santos - SP brasil- vista mirante ilha Porchat 24-01-2011 - panoramio.jpg|thumb|right|Kuwona kwa São Vicente kufuma ku chirwa cha Porchat.]]
'''São Vicente''' ni msumba uwo uli mu chigaŵa cha [[São Paulo (chigaŵa)]] ku [[Brazil]]. Msumba uwu uli mumphepete mwa nyanja ya [[Atlantic]], mu chigaŵa cha Baixada Santista. Ukumanyikwa chomene chifukwa cha mdauko wake wa kukhazikiskika kwa boma la ŵanthu ŵa ku Portugal mu Brazil.
São Vicente yikumanyikwa kuti ndiyo yikaŵa ''vila'' yakwamba yakukhazikiskika mwakuzomerezgeka na ŵanthu ŵa ku Portugal mu Brazil. Msumba uwu ukakhazikiskika pa 22 Janyuwale 1532, apo Martim Afonso de Sousa wakalongozga ntchito ya kukhazikiska boma la ŵanthu ŵa ku Portugal mu chigaŵa ichi.<ref name="Prefeitura">{{Cite web|url=https://www.saovicente.sp.gov.br/visite-sao-vicente-1/historia|title=História de São Vicente|website=Prefeitura de São Vicente|access-date=9 November 2026}}</ref>
== Kakhalilo ka malo ==
São Vicente yili mumphepete mwa nyanja ya Atlantic, kumwera kwa msumba wa [[São Paulo]].
Malo agha ghali mu chirwa cha São Vicente, icho chigaŵa chinyake chili mu msumba wa [[Santos]]. Msumba uwu uli na magombe, malo gha mapiri, nkhorongo na malo ghakukhala ŵanthu.
Malo ghake ghali pafupi na nyanja, ndipo ntchito za malonda na ulendo wa ŵanthu ni zakuzirwa chomene pa chuma cha msumba uwu.<ref name="IBGE">{{Cite web|url=https://www.ibge.gov.br/cidades-e-estados/sp/sao-vicente.html|title=São Vicente|website=Instituto Brasileiro de Geografia e Estatística|access-date=9 November 2026}}</ref>
== Mbiri ==
Pambere ŵanthu ŵa ku Portugal ŵandafike, chigaŵa cha São Vicente chikaŵa kale malo ghakukhala ŵanthu ŵakwambilira ŵa ku Brazil.
Mu 1532, Martim Afonso de Sousa wakakhazikiska vila la São Vicente. Ichi chikapangiska kuti msumba uwu uŵe pakati pa malo ghakwambilira agho ŵanthu ŵa ku Portugal ŵakakhazikiskamo ndondomeko ya kuwusa mu Brazil.
Kukhazikiskika kwa vila kukasazgapo kuŵikapo nyumba za boma, tchalitchi, nyumba yakukomanirako ŵanthu na chinthu icho chikayimilira mazaza gha boma.<ref name="Prefeitura"/>
== Kufika kwa Ŵapwitikizi na kusintha kwa malo ==
Kukhazikiskika kwa São Vicente kukachitika mu nyengo iyo Portugal yikayamba kukhazikiska mazaza ghake mu Brazil.
Ŵapwitikizi ŵakakhazikiska malo gha malonda, ulimi na vyakuzenga. Mu vyaka vyakulondezgapo, ŵanthu ŵa ku Portugal ŵakazenga malo ghakupangira shuga na nthowa za malonda.
Chigaŵa ichi chikakumanaso na viwukirano na masuzgo ghakufuma ku ŵarwani ŵa ku nyanja, kusazgapo ŵanthu ŵakakolanga sitima na ŵanthu ŵa vyaru vinyake.<ref name="Prefeitura"/>
== Malo ghakumanyikwa ==
Mu São Vicente muli malo ghanandi agho ngakuzirwa pa mdauko na umoyo wa ŵanthu.
=== Biquinha de Anchieta ===
Ili ni malo agho ghakukolerana na mbiri ya José de Anchieta, uyo wakaŵa m’mishonale wa Ŵajesuiti ndipo wakachitanga ntchito za chisambizgo cha Chikhristu mu chigaŵa ichi.
=== Porto das Naus ===
Ili ni malo ghakale agho ghakukolerana na malonda na ntchito za ŵanthu ŵa ku Portugal mu nyengo yakwamba ya kuwusa Brazil.
=== Ilha Porchat ===
Chirwa ichi chili na malo agho ŵalendo ŵakutemwa kuluta kuti ŵawone nyanja na msumba wa São Vicente.
=== Vikozgo vya mdauko ===
Msumba uwu uli na vikozgo na malo ghanyake ghakukumbukira mdauko wa Brazil, kusazgapo vikumbuso vya vyaka vya kukhazikiskika kwa boma la Portugal.<ref name="Prefeitura"/>
== Ŵanthu na chuma ==
São Vicente ni msumba uwo uli na ŵanthu ŵanandi ndipo uli pafupi na msumba wa Santos.
Mwakuyana na chiŵelengero cha ŵanthu cha mu 2022, msumba uwu ukaŵa na ŵanthu 329,911. Malo ghake ghakaŵa pafupifupi makilomita 147.774 pa sikweya.<ref name="IBGE"/>
Ntchito za chuma zikuphatikizapo:
* [[Ulendo wa ŵanthu]].
* [[Malonda]].
* [[Usodzi]].
* Ntchito za mahotela na malo ghakupumirako.
* Ntchito za maofesi na mabizinesi.
* Ntchito zakukolerana na msumba wa Santos.
== Msumba wa São Vicente mazuŵa ghano ==
Mazuŵa ghano São Vicente ni chigaŵa cha misumba iyo yili mu Baixada Santista. Msumba uwu ukusunga malo ghanandi gha mbiri apo ukulutilira kukura na kuzgoka malo ghakukhala ŵanthu na kulondezga ntchito za malonda.
== Wonaniso ==
* [[Brazil]]
* [[São Paulo (chigaŵa)]]
* [[Santos]]
* [[Martim Afonso de Sousa]]
* [[Mbiri ya Brazil]]
* [[Nyanja ya Atlantic]]
* [[Porto das Naus]]
* [[Baixada Santista]]
* [[José de Anchieta]]
== Ukaboni ==
<references/>
[[Category:Misumba ya ku Brazil]]
[[Category:Vinthu vya mu chigaŵa cha São Paulo]]
[[Category:Mbiri ya Brazil]]
[[Category:Misumba ya m'mphepete mwa nyanja]]
dg6oug5itvb0yt4szdjiq32o2tyjr0u
Category:Misumba ya ku Brazil
14
50376
124292
2026-11-09T21:12:09Z
Tumbuka Arch
6863
Created page with "v"
124292
wikitext
text/x-wiki
v
e9yv19k55x3mdfvl05hszewhi24bhsk
Category:Vinthu vya mu chigaŵa cha São Paulo
14
50377
124293
2026-11-09T21:12:16Z
Tumbuka Arch
6863
Created blank page
124293
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Misumba ya m'mphepete mwa nyanja
14
50378
124294
2026-11-09T21:12:20Z
Tumbuka Arch
6863
Created blank page
124294
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Pedro Álvares Cabral
0
50379
124295
2026-11-09T21:12:42Z
Tumbuka Arch
6863
Created page with "{{Short description|Mwendendau wa ku Portugal uyo wakafika na zombo ku Brazil mu 1500}} {{Infobox | above = Pedro Álvares Cabral | image = Portrait of Pedro Alvares Cabral.jpg | label1 = Kubabika | data1 = 1467 panji 1468, Belmonte, Portugal | label2 = Kufwa | data2 = Pafupifupi 1520, Santarém, Portugal | label3 = Charu | data3 = [[Portugal]] | label4 = Ntchito | data4 = Mwendendau na mulongozgi wa zombo | label5 = Wakumanyikwa chifukwa cha | data5 = Ulendo wa ku Brazi..."
124295
wikitext
text/x-wiki
{{Short description|Mwendendau wa ku Portugal uyo wakafika na zombo ku Brazil mu 1500}}
{{Infobox
| above = Pedro Álvares Cabral
| image = Portrait of Pedro Alvares Cabral.jpg
| label1 = Kubabika
| data1 = 1467 panji 1468, Belmonte, Portugal
| label2 = Kufwa
| data2 = Pafupifupi 1520, Santarém, Portugal
| label3 = Charu
| data3 = [[Portugal]]
| label4 = Ntchito
| data4 = Mwendendau na mulongozgi wa zombo
| label5 = Wakumanyikwa chifukwa cha
| data5 = Ulendo wa ku Brazil mu 1500
| label6 = Nyengo ya ulendo
| data6 = 1500–1501
}}
[[File:Portrait of Pedro Alvares Cabral.jpg|thumb|right|Pedro Álvares Cabral.]]
[[File:Pintura sobre a primeira missa no Brasil.jpg|thumb|right|Chithuzithuzi cha 1860 icho chikulongora misa lakwamba la Ŵakhristu mu Brazil.]]
'''Pedro Álvares Cabral''' (wakababika mu 1467 panji 1468 – wakafwa pafupifupi mu 1520) wakaŵa mwendendau na mulongozgi wa zombo wa ku [[Portugal]]. Wakumanyikwa chomene chifukwa cha kulongozga ulendo wa zombo za ku Portugal uwo ukafika ku [[Brazil]] pa 22 Epulelo 1500. Ulendo uwu ukachitika apo Cabral wakatumizgikanga na Fumu Manuel I kuti wakakhazikiske ubwezi wa malonda pakati pa Portugal na [[India]].<ref name="Pantheon">{{Cite web|url=https://www.panteaonacional.gov.pt/en/homenageados/pedro-alvares-cabral|title=Pedro Álvares Cabral|website=National Pantheon of Portugal|access-date=9 November 2026}}</ref>
== Umoyo wake wa kukwamba ==
Cabral wakababikira mu msumba wa Belmonte mu Portugal mu mbumba ya ŵanthu ŵasambazi. Ŵanthu ŵanandi ŵakumanya yayi vinandi vya umoyo wake wa uwukirano, kweni wakasambizgika umo ŵanthu ŵa mu mbumba zapachanya ŵakasambiranga mu nyengo yake.
Pamanyuma wakazgoka munthu wakutemweka na Fumu Manuel I, iyo yikamupa mulimo wakulongozga ulendo wa zombo za ku India.<ref name="VisitPortugal">{{Cite web|url=https://www.visitportugal.com/en/NR/exeres/E821720B-C136-404D-BBBF-35C3B5739569|title=Pedro Álvares Cabral|website=Visit Portugal|access-date=9 November 2026}}</ref>
== Ulendo wa ku India wa mu 1500 ==
Mu Malichi 1500, Cabral wakanyamuka kufuma ku [[Lisbon]] na zombo 13. Mulimo wake ukaŵa wakuluta ku India kukakhazikiska ubwezi wa ndyali na malonda, kweniso kujumpha mu nthowa izo ŵanthu ŵakaguliskiranga [[vyakununkhira]].
Cabral wakalongozga zombo zake kuluta kumanjiliro gha dazi kwa nyanja ya Atlantic. Pa 22 Epulelo 1500, ŵanthu awo ŵakaŵa mu zombo zake ŵakawona charu icho sono chikumanyikwa kuti Brazil.
Chigaŵa ichi ŵakachithya zina lakuti Terra de Vera Cruz. Pamanyuma zina lake likasintha kuŵa Brazil.<ref name="Pantheon"/><ref name="Arquivo">{{Cite web|url=https://historialuso.an.gov.br/glossario/index.php/verbetes-glossario/14-verbetes-iniciados-em-c/26-cabral-pedro-alvares-1467-68-1520-26|title=Cabral, Pedro Álvares|website=Arquivo Nacional do Brasil|access-date=9 November 2026}}</ref>
Kweni charu ichi chikaŵa kuti chili kale na ŵanthu ŵakwambilira awo ŵakakhalangamo kwa vyaka vinandi pambere Cabral wandafike. Ntheura ulendo wake ukung'anamura kufika kwa ŵanthu ŵa ku Portugal, kweni kuti wakasanga charu icho ŵanthu ŵakafikangapo yayi.
== Kufika ku Brazil ==
Cabral na ŵasilikari ŵake ŵakafika ku chigaŵa icho sono chili kufupi na Porto Seguro. Ŵakakumana na ŵanthu ŵakwambilira ŵa ku Brazil ndipo ŵakayamba kuŵa na maubwezi.
Pa ulendo uwu, ŵanthu ŵa ku Portugal ŵakachitanga vinthu vyakupambanapambana nga ni kupima malo, kulemba vyakuwoneka na kusonkhaniska vinjeru vya charu icho ŵakafikako.
Mujumbe wa Cabral ukatumizga chombo chimoza ku Portugal kuti chikaphalire fumu vya charu icho ŵakasanga. Pero Vaz de Caminha wakalemba kalata iyo yikulongosoranga vya malo na ŵanthu awo ŵakakumana nawo.<ref name="Arquivo"/>
== Kulutilira kwa ulendo wake ==
Pamanyuma pa kukhala mu Brazil kwa nyengo yichoko, zombo za Cabral zikamba ulendo wake wakuluta ku India.
Mu Seputembala 1500, wakafika ku Calicut, mu India. Kweni ŵanthu ŵa ku Portugal ŵakakumana na masuzgo gha malonda na ŵanthu awo ŵakaŵa kale na mazaza pa malonda gha vyakununkhira.
Cabral wakalutilira na ulendo wake, ndipo pamanyuma wakawelera ku Portugal na katundu wakupambanapambana.<ref name="Arquivo"/>
== Umaliro wa umoyo wake ==
Pamanyuma pa ulendo wake, Cabral wakapokera ntchindi kufuma ku ufumu wa Portugal. Mu 1502 wakasankhika kuti walongozge ulendo unyake wa ku mafumiro gha dazi, kweni mulimo uwu ukenda yayi nga umo ŵakakhumbiranga.
Pamanyuma wakakhala mu Santarém, Portugal, uko wakafwira pafupifupi mu 1520. Wakabikika mu tchalitchi la Igreja da Graça.<ref name="Pantheon"/><ref name="VisitPortugal"/>
== Kukhumbikwa kwake mu mdauko ==
Cabral wakumanyikwa chomene mu mdauko wa Portugal na Brazil chifukwa cha ulendo wake wa mu 1500. Ulendo uwu ukajura nyengo yiphya ya ubwezi wa ndyali, malonda na kuwusa kwa Portugal mu Brazil.
Ndipouli, mbiri ya Brazil yikwenera kusazgapo na ya ŵanthu ŵakwambilira awo ŵakakhalangamo kale, kweniso vinthu ivyo vikachitika pamanyuma pa kukhazikiskika kwa boma la Portugal.
== Wonaniso ==
* [[Brazil]]
* [[Portugal]]
* [[Fumu Manuel I ya Portugal]]
* [[Mwendendau]]
* [[Porto Seguro]]
* [[Lisbon]]
* [[Nyengo ya kuwusa kwa Portugal mu Brazil]]
* [[Mbiri ya Brazil]]
* [[Ŵanthu ŵakwambilira ŵa ku Brazil]]
* [[Vakununkhira]]
* [[Nyanja ya Atlantic]]
* [[Pero Vaz de Caminha]]
== Ukaboni ==
<references/>
[[Category:Mwendendau]]
[[Category:Ŵanthu ŵa ku Portugal]]
[[Category:Mbiri ya Brazil]]
[[Category:Ŵanthu ŵa m'ma 15]]
[[Category:Ŵanthu ŵa m'ma 16]]
lnmd3bpjbh25oqzcxx7yucpx9pbtbeo
Category:Ŵanthu ŵa ku Portugal
14
50380
124296
2026-11-09T21:13:09Z
Tumbuka Arch
6863
Created blank page
124296
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Mahatma Gandhi
0
50381
124297
2026-11-09T21:15:40Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulwani wa India uyo wakalimbikira wanangwa kwizira mu nthowa zambura vivulupi}} [[File:Gandhi spinning.jpg|thumb|200px|Mahatma Gandhi wakupota ulusi.]] '''Mahatma Gandhi''' (zina lake lakubabika: Mohandas Karamchand Gandhi; 2 Okutobala 1869 – 30 Janyuwale 1948) wakaŵa mulwani wa wanangwa wa [[India]], wakulembeka vya ndyali na mulongozgi wa gulu ilo likalimbana na ufumu wa Britain. Wakakhozgera chomene nthowa za kulimbana zambura vivulupi, izo zik..."
124297
wikitext
text/x-wiki
{{Short description|Mulwani wa India uyo wakalimbikira wanangwa kwizira mu nthowa zambura vivulupi}}
[[File:Gandhi spinning.jpg|thumb|200px|Mahatma Gandhi wakupota ulusi.]]
'''Mahatma Gandhi''' (zina lake lakubabika: Mohandas Karamchand Gandhi; 2 Okutobala 1869 – 30 Janyuwale 1948) wakaŵa mulwani wa wanangwa wa [[India]], wakulembeka vya ndyali na mulongozgi wa gulu ilo likalimbana na ufumu wa Britain. Wakakhozgera chomene nthowa za kulimbana zambura vivulupi, izo zikamanyikwa kuti ''satyagraha''. Maghanoghano ghake ghakakhwaska magulu gha wanangwa mu vyaru vinandi pa charu chose.<ref>[https://culture.gov.in/hi/mahatma-gandhi About Mahatma Gandhi], Ministry of Culture, Government of India.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Gandhi wakababika pa 2 Okutobala 1869 mu msumba wa Porbandar, mu chigaŵa cha Gujarat, India. Awiske, Karamchand Gandhi, ŵakaŵa mulongozgi wa boma mu chigaŵa ichi, ndipo amama ŵake ŵakaŵa Putlibai.
Mu 1883, apo wakaŵa na vyaka pafupifupi 13, Gandhi wakatora Kasturba Makhanji. Mu 1888 wakaluta ku London, uko wakasambira vya malango pa Inner Temple. Wakati wamala masambiro, wakawelera ku India na kwamba ntchito ya malango.
== Umoyo wake ku South Africa ==
Mu 1893, Gandhi wakaluta ku [[South Africa]] kukagwira ntchito ya malango. Apo wakaŵa ku charu ichi, wakakumana na kusankhana mitundu na vinthu vyambura kuyana ivyo Ŵaindia ŵakachitirikanga.
Ivi vikamupangiska kuti wambe kulimbikira wanangwa wa Ŵaindia awo ŵakakhalanga ku South Africa. Wakamba kunozga magulu gha ŵanthu na kuchita viyezgelero vya kulimbana na malango agho ghakasankhananga ŵanthu.
== Kulimbana na ufumu wa Britain mu India ==
Gandhi wakawelera ku India mu 1915. Wakazgoka mulongozgi wakuzirwa wa Indian National Congress ndipo wakawovwira kupanga gulu likuru la ŵanthu awo ŵakakhumbanga kuti India yiŵe na wanangwa.
Mu 1930, wakalongozga ulendo wakumanyikwa kuti Salt March. Iyi yikaŵa nthowa ya kulimbana na dango la Britain ilo likakanizganga ŵanthu kupanga na kuguliska mchere kwambura kulipira msonkho. Ulendo uwu ukawovwira kuti nkhondo ya wanangwa wa India yimanyikwe chomene pa charu chose.
Gandhi wakawovwiraso mu magulu ghakulimbana nga ni Non-Cooperation Movement na Quit India Movement. Wakakhozgeranga kuti ŵanthu ŵalimbane na vinthu vyambura kuyana kwambura kuchita vivulupi.
== Maghanoghano ghake ==
Gandhi wakakhozgera maghanoghano gha:
* Ahimsa – kuleka kuchitira ŵanthu panji vyamoyo vinyake vivulupi.
* Satyagraha – kulimbikira unenesko na wanangwa kwambura kugwiliskira ntchito vivulupi.
* Kukhala mwakujiyimira pawekha na kugwiliskira ntchito vinthu vya mu charu chake.
* Kuyana kwa ŵanthu kwambura kusankhana.
== Nyifwa ==
Pa 30 Janyuwale 1948, Gandhi wakakomeka mu New Delhi na Nathuram Godse. Nyifwa yake yikadandawulikira chomene mu India na mu vyaru vinyake.
Gandhi wakukumbukika chifukwa cha kulimbikira wanangwa wa India na kukhozgera nthowa zambura vivulupi. Zuŵa ilo wakababikira, 2 Okutobala, likukumbukika mu India nga ni Gandhi Jayanti, kweniso pa charu chose nga ni zuŵa la kulimbana na vivulupi.
== Vithuzithuzi ==
<gallery>
File:Gandhi spinning.jpg|Gandhi wakupota ulusi.
File:Mahatma Gandhi 1931.jpg|Gandhi mu 1931.
File:Gandhi Salt March.jpg|Ulendo wa Salt March.
File:Gandhi at Sabarmati Ashram.jpg|Gandhi pa malo ghake gha Sabarmati Ashram.
</gallery>
== Wonaniso ==
* [[British Raj]]
* [[Indian National Congress]]
* [[Jawaharlal Nehru]]
* [[India]]
* [[South Africa]]
== Ukaboni ==
<references />
[[Category:Ŵakubabika mu 1869]]
[[Category:Ŵakufwa mu 1948]]
[[Category:Ŵanthu ŵa ku India]]
[[Category:Ŵalwani ŵa wanangwa]]
[[Category:Mbiri ya India]]
np3q0i3yu8shgyob6j0fz2yxfupxcbj
Chitukuko cha Chigwa cha Indus
0
50382
124298
2026-11-09T21:16:16Z
Tumbuka Arch
6863
Created page with "{{Short description|Chitukuko chakale icho chikakura mu chigwa cha mlonga wa Indus}} [[File:Mohenjo-daro.jpg|thumb|250px|Malo ghakale gha Mohenjo-daro mu chigaŵa cha Pakistan.]] '''Chitukuko cha Chigwa cha Indus''' (mu Chingelezi: ''Indus Valley Civilisation''), icho chikuchemekaso kuti chitukuko cha Harappa, chikaŵa chitukuko chakale chomene icho chikakura mu chigaŵa cha mlonga wa [[Indus]], mu malo agho sono ni [[Pakistan]] na chigaŵa cha kumanjiliro gha dazi kwa [..."
124298
wikitext
text/x-wiki
{{Short description|Chitukuko chakale icho chikakura mu chigwa cha mlonga wa Indus}}
[[File:Mohenjo-daro.jpg|thumb|250px|Malo ghakale gha Mohenjo-daro mu chigaŵa cha Pakistan.]]
'''Chitukuko cha Chigwa cha Indus''' (mu Chingelezi: ''Indus Valley Civilisation''), icho chikuchemekaso kuti chitukuko cha Harappa, chikaŵa chitukuko chakale chomene icho chikakura mu chigaŵa cha mlonga wa [[Indus]], mu malo agho sono ni [[Pakistan]] na chigaŵa cha kumanjiliro gha dazi kwa [[India]].
Chitukuko ichi chikakura chomene pakati pa vyaka vya 2600 na 1900 B.C.E. Chikaŵa na misumba yakuzengeka mwandondomeko, nyumba za njerwa, nthowa zakudumulirana na ndondomeko zakufumiskira maji.<ref>[https://www.britannica.com/topic/Indus-civilization Indus civilization], Encyclopaedia Britannica.</ref>
== Malo agho chikakura ==
Chitukuko cha Indus chikakura mumphepete mwa mlonga wa Indus na milonga yinyake ya chigaŵa cha Punjab. Malo ghake ghakafika ku vigaŵa vinandi vya Pakistan na ku India.
Misumba yikuru chomene yikaŵa Harappa na Mohenjo-daro. Malo ghanyake ghakuzirwa ghakaŵa Dholavira, Lothal na Kalibangan. Ŵanthu ŵa mu chitukuko ichi ŵakakhalanga mu malo agho ghakaŵa na minda, nyumba na malo ghakugwiliskira ntchito zakupambanapambana.
== Misumba na nyumba ==
Misumba ya Harappa na Mohenjo-daro yikaŵa na nthowa izo zikapangika mwandondomeko. Nyumba zinandi zikazengeka na njerwa zakuyana mu ukuru. Mu vigaŵa vinyake mukaŵa nthowa zakufumiskira maji ghakufuma mu nyumba na mumphepete mwa misewu.
Chinthu chakumanyikwa chomene cha ku Mohenjo-daro ni Great Bath, malo ghakuru gha maji agho ŵakusambira mbiri ŵakughanaghana kuti ghakaŵa na ntchito ya mwambo panji ya chikaya.
== Ulimi na malonda ==
Ŵanthu ŵa mu chitukuko ichi ŵakalima tirigu, barele na vyakurya vinyake. Kweniso ŵakaweta viŵeto nga ni ng'ombe, mberere na mbuzi.
Ŵakagwiliskiranga ntchito malonda kuti ŵasazgane na malo ghanyake. Vinthu ivyo vikapangikanga mu chigaŵa cha Indus vikusangikaso mu malo ghakale gha Mesopotamia, ndipo ichi chikulongora kuti kukaŵa malonda pakati pa vigaŵa viŵiri ivi.
Ŵanthu ŵakazenganga vinthu na kupanga viŵiya, mikanda, vyakudindira na vinthu vinyake vya ntchito.
== Malembi na vyakudindira ==
Ŵanthu ŵa mu chitukuko cha Indus ŵakagwiliskiranga ntchito vyakudindira ivyo vikaŵa na vimanyikwiro. Malembi agha ghakusangika pa vinthu nga ni vimakuni vya malibwe, viŵiya na vinthu vinyake.
Mpaka sono malembi agha ghandamasulirike mwakukwana. Chifukwa cha ichi, viyowoyero ivyo ŵanthu aŵa ŵakayowoyanga na vinandi vya umoyo wawo vichali vyakumanyikwa yayi.
== Kumara kwa chitukuko ==
Pamanyuma pa 1900 B.C.E., misumba yikuru ya Indus yikamba kuchepa, ndipo ŵanthu ŵanandi ŵakasintha malo agho ŵakakhalanga. Vifukwa vya kusintha uku vichali kusambilirika. Ŵakusambira ŵakughanaghana kuti kusintha kwa nyengo, kusintha kwa milonga na kusintha kwa malonda vikwenera kuti vikawovwira pa nkhani iyi.
Palije ukaboni wakukwana wakuti chitukuko chose chikaparanyika pa zuŵa limoza panji chifukwa cha kuwukira kwa gulu limoza la ŵanthu.
== Kufunika kwake ==
Chitukuko cha Indus ni chimoza mwa vyitukuko vikuru vyakale vya mu Asia. Chikulongora kuti ŵanthu ŵakale ŵakaŵa na luso lwa kuzenga misumba, ulimi, malonda na kupanga vinthu mwaluso.
== Vithuzithuzi ==
<gallery>
File:Mohenjo-daro.jpg|Malo ghakale gha Mohenjo-daro.
File:Dancing Girl of Mohenjo-daro.jpg|Chikozgo cha Dancing Girl icho chikafukulika ku Mohenjo-daro.
File:Priest King statue.jpg|Chikozgo icho chikumanyikwa kuti Priest-King.
File:Great Bath, Mohenjo-daro.jpg|Great Bath ku Mohenjo-daro.
</gallery>
== Wonaniso ==
* [[India]]
* [[Pakistan]]
* [[Chitukuko cha Mesopotamia]]
* [[Mlonga wa Indus]]
== Ukaboni ==
<references />
[[Category:Mbiri ya India]]
[[Category:Mbiri ya Pakistan]]
[[Category:Vyitukuko vyakale]]
k0nuvq8iurjpnb9eqql18t0l431pdxh
124299
124298
2026-11-09T21:16:44Z
Tumbuka Arch
6863
Tumbuka Arch moved page [[Indus Valley Civilisation]] to [[Chitukuko cha Chigwa cha Indus]]
124298
wikitext
text/x-wiki
{{Short description|Chitukuko chakale icho chikakura mu chigwa cha mlonga wa Indus}}
[[File:Mohenjo-daro.jpg|thumb|250px|Malo ghakale gha Mohenjo-daro mu chigaŵa cha Pakistan.]]
'''Chitukuko cha Chigwa cha Indus''' (mu Chingelezi: ''Indus Valley Civilisation''), icho chikuchemekaso kuti chitukuko cha Harappa, chikaŵa chitukuko chakale chomene icho chikakura mu chigaŵa cha mlonga wa [[Indus]], mu malo agho sono ni [[Pakistan]] na chigaŵa cha kumanjiliro gha dazi kwa [[India]].
Chitukuko ichi chikakura chomene pakati pa vyaka vya 2600 na 1900 B.C.E. Chikaŵa na misumba yakuzengeka mwandondomeko, nyumba za njerwa, nthowa zakudumulirana na ndondomeko zakufumiskira maji.<ref>[https://www.britannica.com/topic/Indus-civilization Indus civilization], Encyclopaedia Britannica.</ref>
== Malo agho chikakura ==
Chitukuko cha Indus chikakura mumphepete mwa mlonga wa Indus na milonga yinyake ya chigaŵa cha Punjab. Malo ghake ghakafika ku vigaŵa vinandi vya Pakistan na ku India.
Misumba yikuru chomene yikaŵa Harappa na Mohenjo-daro. Malo ghanyake ghakuzirwa ghakaŵa Dholavira, Lothal na Kalibangan. Ŵanthu ŵa mu chitukuko ichi ŵakakhalanga mu malo agho ghakaŵa na minda, nyumba na malo ghakugwiliskira ntchito zakupambanapambana.
== Misumba na nyumba ==
Misumba ya Harappa na Mohenjo-daro yikaŵa na nthowa izo zikapangika mwandondomeko. Nyumba zinandi zikazengeka na njerwa zakuyana mu ukuru. Mu vigaŵa vinyake mukaŵa nthowa zakufumiskira maji ghakufuma mu nyumba na mumphepete mwa misewu.
Chinthu chakumanyikwa chomene cha ku Mohenjo-daro ni Great Bath, malo ghakuru gha maji agho ŵakusambira mbiri ŵakughanaghana kuti ghakaŵa na ntchito ya mwambo panji ya chikaya.
== Ulimi na malonda ==
Ŵanthu ŵa mu chitukuko ichi ŵakalima tirigu, barele na vyakurya vinyake. Kweniso ŵakaweta viŵeto nga ni ng'ombe, mberere na mbuzi.
Ŵakagwiliskiranga ntchito malonda kuti ŵasazgane na malo ghanyake. Vinthu ivyo vikapangikanga mu chigaŵa cha Indus vikusangikaso mu malo ghakale gha Mesopotamia, ndipo ichi chikulongora kuti kukaŵa malonda pakati pa vigaŵa viŵiri ivi.
Ŵanthu ŵakazenganga vinthu na kupanga viŵiya, mikanda, vyakudindira na vinthu vinyake vya ntchito.
== Malembi na vyakudindira ==
Ŵanthu ŵa mu chitukuko cha Indus ŵakagwiliskiranga ntchito vyakudindira ivyo vikaŵa na vimanyikwiro. Malembi agha ghakusangika pa vinthu nga ni vimakuni vya malibwe, viŵiya na vinthu vinyake.
Mpaka sono malembi agha ghandamasulirike mwakukwana. Chifukwa cha ichi, viyowoyero ivyo ŵanthu aŵa ŵakayowoyanga na vinandi vya umoyo wawo vichali vyakumanyikwa yayi.
== Kumara kwa chitukuko ==
Pamanyuma pa 1900 B.C.E., misumba yikuru ya Indus yikamba kuchepa, ndipo ŵanthu ŵanandi ŵakasintha malo agho ŵakakhalanga. Vifukwa vya kusintha uku vichali kusambilirika. Ŵakusambira ŵakughanaghana kuti kusintha kwa nyengo, kusintha kwa milonga na kusintha kwa malonda vikwenera kuti vikawovwira pa nkhani iyi.
Palije ukaboni wakukwana wakuti chitukuko chose chikaparanyika pa zuŵa limoza panji chifukwa cha kuwukira kwa gulu limoza la ŵanthu.
== Kufunika kwake ==
Chitukuko cha Indus ni chimoza mwa vyitukuko vikuru vyakale vya mu Asia. Chikulongora kuti ŵanthu ŵakale ŵakaŵa na luso lwa kuzenga misumba, ulimi, malonda na kupanga vinthu mwaluso.
== Vithuzithuzi ==
<gallery>
File:Mohenjo-daro.jpg|Malo ghakale gha Mohenjo-daro.
File:Dancing Girl of Mohenjo-daro.jpg|Chikozgo cha Dancing Girl icho chikafukulika ku Mohenjo-daro.
File:Priest King statue.jpg|Chikozgo icho chikumanyikwa kuti Priest-King.
File:Great Bath, Mohenjo-daro.jpg|Great Bath ku Mohenjo-daro.
</gallery>
== Wonaniso ==
* [[India]]
* [[Pakistan]]
* [[Chitukuko cha Mesopotamia]]
* [[Mlonga wa Indus]]
== Ukaboni ==
<references />
[[Category:Mbiri ya India]]
[[Category:Mbiri ya Pakistan]]
[[Category:Vyitukuko vyakale]]
k0nuvq8iurjpnb9eqql18t0l431pdxh
Indus Valley Civilisation
0
50383
124300
2026-11-09T21:16:44Z
Tumbuka Arch
6863
Tumbuka Arch moved page [[Indus Valley Civilisation]] to [[Chitukuko cha Chigwa cha Indus]]
124300
wikitext
text/x-wiki
#REDIRECT [[Chitukuko cha Chigwa cha Indus]]
mj6kypss9qpj2rk7ts7v5itd4kq6d18
Chandragupta Maurya
0
50384
124301
2026-11-09T21:16:58Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi uyo wakakhazikiska Ufumu wa Maurya}} [[File:Chandragupta Maurya.jpg|thumb|200px|Chithuzithuzi cha Chandragupta Maurya.]] '''Chandragupta Maurya''' (wakawusa cha m'ma 321 mpaka 297 B.C.E.) wakaŵa mulongozgi wa ku India uyo wakakhazikiska [[Ufumu wa Maurya]]. Wakawovwira kuwuskapo ufumu wa Nanda na kuunganiska vigaŵa vinandi vya kumpoto kwa India pasi pa boma limoza. Ufumu uwo wakakhazikiska ukazgoka umoza mwa maufumu ghakuru chomene gha mu..."
124301
wikitext
text/x-wiki
{{Short description|Mulongozgi uyo wakakhazikiska Ufumu wa Maurya}}
[[File:Chandragupta Maurya.jpg|thumb|200px|Chithuzithuzi cha Chandragupta Maurya.]]
'''Chandragupta Maurya''' (wakawusa cha m'ma 321 mpaka 297 B.C.E.) wakaŵa mulongozgi wa ku India uyo wakakhazikiska [[Ufumu wa Maurya]]. Wakawovwira kuwuskapo ufumu wa Nanda na kuunganiska vigaŵa vinandi vya kumpoto kwa India pasi pa boma limoza. Ufumu uwo wakakhazikiska ukazgoka umoza mwa maufumu ghakuru chomene gha mu mbiri ya India.<ref>[https://www.britannica.com/biography/Chandragupta Chandragupta], Encyclopaedia Britannica.</ref>
== Kwamba kwa umoyo wake ==
Vyakukhwaskana na ubwana wa Chandragupta vikulongosoreka mu mabuku ghakupambanapambana, ndipo nkhani zinyake zikusazgana na nthano. Ŵakusambira mbiri ŵakumanya kuti wakakura mu nyengo iyo ufumu wa Nanda ukaŵa na mazaza mu chigaŵa cha Magadha.
Chandragupta wakawovwirika na Chanakya, uyo wakumanyikwaso kuti Kautilya panji Vishnugupta. Chanakya wakuzunulika mu mabuku gha kale nga ni munthu uyo wakamovwira pa ndyali na kukhazikiska boma liphya.
== Kukhazikiska Ufumu wa Maurya ==
Cha m'ma 321 B.C.E., Chandragupta wakathereska ufumu wa Nanda na kukhazikiska ufumu wake. Likuru la boma lake likaŵa ku Pataliputra, uko lero kukumanyikwa kuti Patna.
Pamanyuma, wakakura na kutora vigaŵa vinandi vya kumpoto kwa India. Mu nyengo yakulondezgapo wakachita phangano na Seleucus I Nicator, uyo wakaŵa yumoza mwa ŵalongozgi ŵa ufumu wa Alexander the Great. Phangano ili likawovwira kukhazikiska ubwezi pakati pa ufumu wa Maurya na ufumu wa Seleucid.
== Boma lake ==
Chandragupta wakakhazikiska boma ilo likaŵa na ŵalara ŵa boma, ŵalongozgi ŵa vigaŵa na ŵanthu ŵakuwoneseska milimo ya boma. Boma ili likawovwira kusonkhaniska msonkho, kulongozga ulimi na kusunga ndondomeko za charu.
Buku lakumanyikwa kuti ''Arthashastra'' likulongosora vya kawusiro, chuma na ndyali mu India wakale. Buku ili likukolerana na zina la Chanakya, nangauli mbiri ya kulembeka kwake njakusuzga kuyimanya mwakudunjika.
== Kuleka kuwusa na nyifwa ==
Mwakuyana na mitheto yinyake ya Chijain, Chandragupta wakaleka kuwusa ndipo wakaluta ku Shravanabelagola, uko wakachita umoyo wa kujipatura ku vinthu vya charu. Nkhani za chisopa cha Chijain zikulongosora kuti wakafwira ku malo agha. Ndipouli, nkhani iyi yikupulikikwa nga ni mwambo wa chisopa ndipo yikukhumbikwira kusiyaniskika na ukaboni wa mbiri.
== Kufunika kwake ==
Chandragupta Maurya wakukumbukika chifukwa cha kukhazikiska ufumu uwo ukazgoka chimoza mwa vyaru vikuru vya kale mu Asia. Mwana wa mwana wake, [[Ashoka]], wakazgoka yumoza mwa mafumu ghakumanyikwa chomene mu mbiri ya India.
== Vithuzithuzi ==
<gallery>
File:Chandragupta Maurya.jpg|Chithuzithuzi cha Chandragupta Maurya.
File:Chanakya.jpg|Chithuzithuzi icho chikulongora Chanakya.
File:Maurya Empire, c. 250 BCE.png|Mapu gha Ufumu wa Maurya mu nyengo ya Ashoka.
</gallery>
== Wonaniso ==
* [[Ufumu wa Maurya]]
* [[Ashoka]]
* [[India]]
* [[Chanakya]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Ŵanthu ŵa ku India]]
[[Category:Ŵakawusi ŵa kale]]
[[Category:Mbiri ya India]]
t9x6zvsffs6ctr5t0zzpa1c8tllkdq9
Maurya Empire
0
50385
124302
2026-11-09T21:17:39Z
Tumbuka Arch
6863
Redirected page to [[Ufumu wa Maurya]]
124302
wikitext
text/x-wiki
#REDIRECT [[Ufumu wa Maurya]]
1euzx34bxftk8hnv8m5ole8vsr3evml
Ufumu wa Maurya
0
50386
124303
2026-11-09T21:17:50Z
Tumbuka Arch
6863
Created page with "{{Short description|Ufumu ukuru wa kale wa ku India}} [[File:Maurya Empire, c. 250 BCE.png|thumb|250px|Mapu gha Ufumu wa Maurya mu nyengo yake yikuru.]] '''Ufumu wa Maurya''' ukaŵa ufumu ukuru wa kale wa ku [[India]] uwo ukawusa pakati pa vyaka vya m'ma 321 na 185 B.C.E. Ukakhazikiskika na [[Chandragupta Maurya]] ndipo ukafika pa ukuru wake mu nyengo ya [[Ashoka]]. Likuru la ufumu uwu likaŵa ku Pataliputra, uko lero kukumanyikwa kuti Patna.<ref>[https://www.britannica...."
124303
wikitext
text/x-wiki
{{Short description|Ufumu ukuru wa kale wa ku India}}
[[File:Maurya Empire, c. 250 BCE.png|thumb|250px|Mapu gha Ufumu wa Maurya mu nyengo yake yikuru.]]
'''Ufumu wa Maurya''' ukaŵa ufumu ukuru wa kale wa ku [[India]] uwo ukawusa pakati pa vyaka vya m'ma 321 na 185 B.C.E. Ukakhazikiskika na [[Chandragupta Maurya]] ndipo ukafika pa ukuru wake mu nyengo ya [[Ashoka]]. Likuru la ufumu uwu likaŵa ku Pataliputra, uko lero kukumanyikwa kuti Patna.<ref>[https://www.britannica.com/place/Mauryan-Empire Mauryan Empire], Encyclopaedia Britannica.</ref>
== Kukhazikiskika ==
Ufumu wa Maurya ukakhazikiskika cha m'ma 321 B.C.E., apo Chandragupta Maurya wakathereska ufumu wa Nanda. Wakawovwirika na Chanakya, uyo wakumanyikwaso kuti Kautilya. Chandragupta wakalutilira kutora vigaŵa vinandi vya kumpoto kwa India na kupanga boma limoza.
== Kukura kwa ufumu ==
Mu nyengo ya Chandragupta na mwana wake Bindusara, ufumu uwu ukathandazgikira mu vigaŵa vinandi vya India. Mu nyengo ya Bindusara, boma likalutilira kukura na kusunga malo agho likawusanga.
Ashoka, uyo wakaŵa muzukuru wa Chandragupta, wakakwera pa chitengo cha ufumu cha m'ma 268 B.C.E. Mu nyengo yake, ufumu wa Maurya ukafika pa malo ghakuru chomene ndipo ukaŵa na mazaza pa vigaŵa vinandi vya South Asia.
== Ashoka na chisopa cha Ubuddha ==
Mu nyengo ya Ashoka, ufumu wa Maurya ukapambana na boma la Kalinga pa nkhondo iyo yikachitika cha m'ma 261 B.C.E. Nkhondo iyi yikapangiska kuti Ashoka wadandawure chifukwa cha masuzgo agho ghakawira ŵanthu.
Pamanyuma pake wakakhozgera visambizgo vya [[Ubuddha]] na kuyowoya vya mtende, kulolerana pa chisopa na kuchitira lusungu ŵanthu. Wakazika malibwe agho ghakaŵa na malemba ghake, agho mazuŵa ghano ghakumanyikwa kuti Ashoka's Edicts.
== Kawusiro ka ufumu ==
Ufumu wa Maurya ukaŵa na boma la pakati ilo likaŵa ku Pataliputra. Vigaŵa vya ufumu vikawusikanga na ŵalara awo ŵakaŵa pasi pa boma likuru. Boma likasunganga ndondomeko za msonkho, ulimi, misewu na malonda.
Buku la ''Arthashastra'' likusangika pakati pa mabuku ghakuzirwa agho ghakulongosora ndyali na kayendeskero ka boma mu India wakale.
== Kugwa kwa ufumu ==
Pamanyuma pa nyifwa ya Ashoka, ufumu ukamba kuchepa nkhongono. Vigaŵa vinyake vikamba kujiyimira pawekha, ndipo ŵalongozgi ŵakupambanapambana ŵakamba kupoka mazaza.
Mu 185 B.C.E., fumu yaumaliro ya Maurya, Brihadratha, yikakomeka na mulongozgi wake wa ŵasilikari Pushyamitra Shunga. Ichi chikamara kuwusa kwa mbumba ya Maurya.
== Kufunika kwake ==
Ufumu wa Maurya ukaŵa wakuzirwa chomene pa mbiri ya India chifukwa ukaunganiska vigaŵa vinandi vya charu pasi pa boma limoza. Kweniso ukawovwira kuthandazga Ubuddha mu Asia, ndipo malemba gha Ashoka ghakutovwira kupulikiska ndyali na umoyo wa ŵanthu mu nyengo yakale.
== Vithuzithuzi ==
<gallery>
File:Maurya Empire, c. 250 BCE.png|Mapu gha ufumu mu nyengo ya Ashoka.
File:Ashoka Pillar at Vaishali.jpg|Chimanyikwiro cha nyengo ya Maurya.
File:Lion Capital of Ashoka at Sarnath.jpg|Chikozgo cha nkhalamu cha pa mzati wa Ashoka.
File:Ashoka's edicts.jpg|Malemba gha Ashoka pa libwe.
</gallery>
== Wonaniso ==
* [[Chandragupta Maurya]]
* [[Ashoka]]
* [[India]]
* [[Ubuddha]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Maufumu gha kale]]
[[Category:Mbiri ya India]]
[[Category:India wakale]]
6u219qkxcarcybvo8pxk1hhxdnf24f0
Ashoka
0
50387
124304
2026-11-09T21:18:04Z
Tumbuka Arch
6863
Created page with "{{Short description|Fumu ya Ufumu wa Maurya iyo yikakhozgera Ubuddha}} [[File:Ashoka lion capital.jpg|thumb|200px|Chikozgo cha nkhalamu cha pa mzati wa Ashoka ku Sarnath.]] '''Ashoka''' (wakawusa cha m'ma 268 mpaka 232 B.C.E.), uyo wakumanyikwaso kuti Ashoka the Great, wakaŵa fumu ya [[Ufumu wa Maurya]] mu [[India]] wakale. Wakazgoka mulongozgi wa ufumu pamanyuma pa adada ŵake Bindusara. Mu nyengo yake, ufumu wa Maurya ukafika pa malo ghakuru chomene mu mbiri yake.<ref..."
124304
wikitext
text/x-wiki
{{Short description|Fumu ya Ufumu wa Maurya iyo yikakhozgera Ubuddha}}
[[File:Ashoka lion capital.jpg|thumb|200px|Chikozgo cha nkhalamu cha pa mzati wa Ashoka ku Sarnath.]]
'''Ashoka''' (wakawusa cha m'ma 268 mpaka 232 B.C.E.), uyo wakumanyikwaso kuti Ashoka the Great, wakaŵa fumu ya [[Ufumu wa Maurya]] mu [[India]] wakale. Wakazgoka mulongozgi wa ufumu pamanyuma pa adada ŵake Bindusara. Mu nyengo yake, ufumu wa Maurya ukafika pa malo ghakuru chomene mu mbiri yake.<ref>[https://www.britannica.com/biography/Ashoka Ashoka], Encyclopaedia Britannica.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Ashoka wakaŵa mwana wa Bindusara na muzukuru wa [[Chandragupta Maurya]], uyo wakakhazikiska ufumu wa Maurya. Vyakukhwaskana na umoyo wake wa apo wakaŵa mwana vikulongosoreka mu mabuku ghakupambanapambana, ndipo nkhani zinyake zikusazgana na nthano.
Mu nyengo ya adada ŵake, Ashoka wakapika milimo ya boma mu vigaŵa vyakupambanapambana. Pamanyuma pa nyifwa ya Bindusara, wakatora chitengo cha ufumu.
== Kuwusa kwake ==
Ashoka wakakwera pa chitengo cha ufumu cha m'ma 268 B.C.E. Wakalamulira ufumu uwo ukaŵa na vigaŵa vikuruvikuru vya India na malo ghanyake gha ku South Asia. Likuru la ufumu wake likaŵa ku Pataliputra.
== Nkhondo ya Kalinga ==
Chochitika chakuzirwa chomene mu nyengo ya Ashoka chikaŵa nkhondo ya Kalinga, iyo yikachitika cha m'ma 261 B.C.E. Kalinga yikaŵa mu chigaŵa icho sono chili ku Odisha, India.
Pamanyuma pa nkhondo iyi, Ashoka wakalongora kudandawura chifukwa cha ŵanthu awo ŵakafwa na masuzgo agho ghakawira ŵanthu. Mu malemba ghake ghakudindika pa malibwe, wakulongosora kuti nkhondo iyi yikamupangiska kughanaghaniraso vya umo wakwenera kulongozgera ufumu wake.
== Ubuddha na Dhamma ==
Pamanyuma pa nkhondo ya Kalinga, Ashoka wakakhozgera chomene [[Ubuddha]]. Wakawovwira kuti visambizgo vya Buddha vithandazgike mu India na mu vigaŵa vinyake vya Asia.
Ashoka wakagwiliskira ntchito lizgu lakuti ''Dhamma'' pa visambizgo vyake vya nkharo yiwemi. Wakakhozgera kuchitira lusungu ŵanthu na vinyama, kuleka kusuzga ŵanthu, na kulolerana pakati pa ŵanthu ŵa visopa vyakupambanapambana.
== Malemba gha Ashoka ==
Ashoka wakazika malibwe na mizati iyo yikaŵa na malemba ghake mu vigaŵa vya ufumu wake. Malemba agha ghakulongosora vya Dhamma, ndondomeko za boma na umo wakakhumbiranga kuti ŵanthu ŵakhalire.
Malemba agha ni ukaboni wakuzirwa chomene wa mbiri ya India wakale chifukwa ghakulongosora umo fumu yikakhumbiranga kuti ŵanthu ŵake ŵakhalire.
== Nyifwa na chiharo chake ==
Ashoka wakafwa cha m'ma 232 B.C.E. Pamanyuma pa nyifwa yake, ufumu wa Maurya ukamba kuchepa nkhongono ndipo pamanyuma ukamara mu 185 B.C.E.
Chimanyikwiro cha nkhalamu cha ku Sarnath icho chikukolerana na Ashoka chikazgoka chimanyikwiro cha boma la India. Kweniso gudumu la Ashoka, ilo lili pa mbendela ya India, likukumbuskana na Dhamma na mitheto ya charu.
== Vithuzithuzi ==
<gallery>
File:Ashoka lion capital.jpg|Chikozgo cha nkhalamu cha ku Sarnath.
File:Ashoka Chakra.svg|Gudumu la Ashoka ilo lili pa mbendela ya India.
File:Ashoka Pillar at Vaishali.jpg|Mzati wakukolerana na Ashoka.
File:Ashoka's edicts.jpg|Malemba gha Ashoka pa libwe.
</gallery>
== Wonaniso ==
* [[Chandragupta Maurya]]
* [[Ufumu wa Maurya]]
* [[Ubuddha]]
* [[India]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Ŵakawusi ŵa India]]
[[Category:Ŵakubabika mu vyaka vya m'ma 300 B.C.E.]]
[[Category:Mbiri ya India]]
[[Category:Ubuddha]]
rsh29awkzpvhhpf6zx6k0jl4bn9e873
Buddhism
0
50388
124305
2026-11-09T21:18:40Z
Tumbuka Arch
6863
Redirected page to [[Ubuddha]]
124305
wikitext
text/x-wiki
#REDIRECT [[Ubuddha]]
hrut5yoolu3m5ly6z9w1x9qn4acj28i
Ubuddha
0
50389
124306
2026-11-09T21:18:51Z
Tumbuka Arch
6863
Created page with "{{Short description|Chisopa na visambizgo ivyo vikafuma kwa Siddhartha Gautama}} [[File:Great Buddha at Sarnath.jpg|thumb|200px|Chikozgo cha Buddha icho chikulongora umo wakasambizgiranga.]] '''Ubuddha''' (mu Chingelezi: ''Buddhism'') ni chisopa na nthowa ya umoyo iyo yikafuma ku India wakale. Yikakhazikiskika pa visambizgo vya [[Siddhartha Gautama]], uyo wakumanyikwa kuti Buddha. Lizgu lakuti Buddha likung'anamura munthu uyo wawuka ku tulo twa kuleka kumanya unenesko. V..."
124306
wikitext
text/x-wiki
{{Short description|Chisopa na visambizgo ivyo vikafuma kwa Siddhartha Gautama}}
[[File:Great Buddha at Sarnath.jpg|thumb|200px|Chikozgo cha Buddha icho chikulongora umo wakasambizgiranga.]]
'''Ubuddha''' (mu Chingelezi: ''Buddhism'') ni chisopa na nthowa ya umoyo iyo yikafuma ku India wakale. Yikakhazikiskika pa visambizgo vya [[Siddhartha Gautama]], uyo wakumanyikwa kuti Buddha. Lizgu lakuti Buddha likung'anamura munthu uyo wawuka ku tulo twa kuleka kumanya unenesko. Visambizgo vya Ubuddha vikulongosora vya masuzgo gha umoyo, umo masuzgo agha ghakwambira, na nthowa yakufiskira mtende wa maghanoghano.<ref>[https://www.britannica.com/topic/Buddhism Buddhism], Encyclopaedia Britannica.</ref>
== Kwamba kwa Ubuddha ==
Ubuddha ukambira kumpoto kwa India, mu nyengo ya m'ma 500 panji m'ma 400 B.C.E. Siddhartha Gautama wakababika mu banja la mafumu gha ku Lumbini, uko sono kuli mu Nepal. Pamanyuma pa kuwona masuzgo gha ukalamba, ulwari na nyifwa, wakaleka umoyo wa pa nyumba na kupenja nthowa yakumanyira chifukwa cha masuzgo gha ŵanthu.
Pamanyuma pa kusambira na kughanaghanira chomene, wakafika pa kumanya ivyo ŵasambiri ŵake ŵakumanyikwira kuti kuŵa Buddha. Wakamba kusambizga ŵanthu mu vigaŵa vya kumpoto kwa India.
== Visambizgo vikuru ==
Ubuddha ukusambizga vya Unenesko Ukanayi Wakuzirwa:
* Umoyo uli na masuzgo na kuleka kukhorwa.
* Masuzgo agha ghakufuma ku khumbo lakusuzga na kukoleska vinthu.
* Masuzgo ghangamara.
* Pali nthowa iyo munthu wangayendera kuti wafiske kumara kwa masuzgo.
Nthowa iyi yikumanyikwa kuti Nthowa ya Vigaŵa Vinkhondi na Vinayi. Yikusazgapo maghanoghano ghakwenelera, kuyowoya makora, kuchita vinthu mwakwenelera, umoyo uwemi, na kughanaghanira mwakupwelelera.
== Kuthandazgika kwa Ubuddha ==
Mu vyaka vyakulondezgapo, Ubuddha ukathandazgika kufuma ku India kuya ku vyaru vinyake vya ku Asia. [[Ashoka]], fumu ya [[Ufumu wa Maurya]], wakawovwira kuti visambizgo vya Ubuddha vimanyikwe mu vigaŵa vinandi.
Ubuddha ukafika ku Sri Lanka na mu vigaŵa vya Central Asia, China, Korea na Japan. Pamanyuma ukafika ku Tibet na ku Southeast Asia.
== Magulu gha Ubuddha ==
Ubuddha uli na mitundu mikuru yakupambanapambana, kusazgapo:
* '''Theravada''' – ukusangika chomene mu Sri Lanka, Thailand, Myanmar, Laos na Cambodia.
* '''Mahayana''' – ukusangika chomene mu China, Korea, Japan na Vietnam.
* '''Vajrayana''' – ukusangika chomene mu Tibet na mu vigaŵa vinyake vya Himalaya.
Magulu agha ghali na mphambano pa umo ghakusambizgira na kuchitira chisopa, kweni ghakukolerana pa vinthu vinandi vya visambizgo vya Buddha.
== Ubuddha mazuŵa ghano ==
Mazuŵa ghano, Ubuddha uli na ŵanthu awo ŵakuluska mu vyaru vinandi vya Asia na mu vigaŵa vinyake vya charu. Ŵanthu ŵanyake awo ŵakusopa Ubuddha ŵakuchita kusinkhasinkha, kuluta ku nyumba za chisopa na kusambira malemba gha Buddha.
== Vithuzithuzi ==
<gallery>
File:Great Buddha at Sarnath.jpg|Chikozgo cha Buddha ku Sarnath.
File:Mahabodhi Temple Bodhgaya.jpg|Nyumba ya Mahabodhi ku Bodh Gaya, India.
File:Dhamek Stupa, Sarnath.jpg|Stupa ya ku Sarnath.
File:Buddha statue in Thailand.jpg|Chikozgo cha Buddha ku Thailand.
</gallery>
== Wonaniso ==
* [[Ashoka]]
* [[India]]
* [[Chisopa]]
* [[Chishinto]]
* [[Kusinkhasinkha]]
== Ukaboni ==
<references />
[[Category:Visopa]]
[[Category:Ubuddha]]
[[Category:Mbiri ya India]]
het4hmsysojib76u89j46gxzv3rrvmh
Babur
0
50390
124307
2026-11-09T21:19:08Z
Tumbuka Arch
6863
Created page with "{{Short description|Mulongozgi uyo wakakhazikiska Ufumu wa Mughal mu India}} [[File:Babur.jpg|thumb|200px|Chithuzithuzi cha Babur.]] '''Babur''' (zina lake lose: Zahir-ud-din Muhammad Babur; 14 Febuluwale 1483 – 26 Disembala 1530) wakaŵa mulongozgi wa ku Central Asia uyo wakakhazikiska [[Ufumu wa Mughal]] mu [[India]]. Wakawusa kufuma mu 1526 mpaka 1530. Mu 1526, wakathereska Ibrahim Lodi pa Nkhondo Yakwamba ya Panipat, ndipo kuwina uku kukamba nyengo ya kuwusa kwa Mu..."
124307
wikitext
text/x-wiki
{{Short description|Mulongozgi uyo wakakhazikiska Ufumu wa Mughal mu India}}
[[File:Babur.jpg|thumb|200px|Chithuzithuzi cha Babur.]]
'''Babur''' (zina lake lose: Zahir-ud-din Muhammad Babur; 14 Febuluwale 1483 – 26 Disembala 1530) wakaŵa mulongozgi wa ku Central Asia uyo wakakhazikiska [[Ufumu wa Mughal]] mu [[India]]. Wakawusa kufuma mu 1526 mpaka 1530. Mu 1526, wakathereska Ibrahim Lodi pa Nkhondo Yakwamba ya Panipat, ndipo kuwina uku kukamba nyengo ya kuwusa kwa Mughal mu kumpoto kwa India.<ref>[https://www.britannica.com/biography/Babur Babur], Encyclopaedia Britannica.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Babur wakababika pa 14 Febuluwale 1483 ku Andijan, mu chigaŵa cha Fergana, icho sono chili mu Uzbekistan. Awiske ŵakaŵa Umar Sheikh Mirza, mulongozgi wa Fergana, ndipo amama ŵake ŵakaŵa Qutlugh Nigar Khanum.
Babur wakafuma mu mbumba ya Timur kwizira kwa awiske. Kwizira kwa amama ŵake, wakakolerananga na banja la Chinggis Khan. Apo wakaŵa na vyaka pafupifupi 12, wakatora udindo wa mulongozgi wa Fergana pamanyuma pa nyifwa ya awiske.
== Kuwusa ku Central Asia ==
Babur wakayezga kanandi kusanga mazaza mu Samarkand, msumba uwo ukaŵa wakuzirwa chomene mu Central Asia. Nangauli wakawina na kutaya malo agha mu nyengo zakupambanapambana, wakalutilira kupenja malo ghakukhazikiskira ufumu wake.
Mu 1504, wakapoka Kabul ndipo wakakhazikiska likuru lake mu Afghanistan. Kufuma apo wakamba kunozga maulendo ghake kuluta ku India.
== Kukhazikiska Ufumu wa Mughal ==
Mu 1526, Babur wakaluta ku India ndipo wakakumana na Ibrahim Lodi, mulongozgi wa Delhi Sultanate. Pa 21 Epulero 1526, ŵasilikari ŵake ŵakathereska ŵa Lodi pa Nkhondo Yakwamba ya Panipat.
Wakakhazikiska boma lake mu Delhi na Agra. Mu 1527 wakathereska gulu la Rajput pa Nkhondo ya Khanwa. Vinthu ivi vikawovwira kukhozga mazaza ghake mu kumpoto kwa India.
== Baburnama ==
Babur wakalemba buku la umoyo wake lakumanyikwa kuti ''Baburnama''. Buku ili likalembeka mu chiyowoyero cha Chagatai Turkic ndipo likulongosora vya maulendo ghake, nkhondo, malo, vyakumera, vinyama na ŵanthu awo wakakumana nawo.
Baburnama ni ukaboni wakuzirwa chomene pa kusambira mbiri ya Central Asia na India mu vyaka vya m'ma 1500.
== Nyifwa na chiharo ==
Babur wakafwa pa 26 Disembala 1530 ku Agra. Mwana wake Humayun wakalondezga pa chitengo cha ufumu.
Babur wakukumbukika nga ni munthu uyo wakakhazikiska ufumu wa Mughal, uwo pamanyuma ukazgoka umoza mwa maufumu ghakuru na ghakukondweska chomene pa mbiri ya India.
== Vithuzithuzi ==
<gallery>
File:Babur.jpg|Chithuzithuzi cha Babur.
File:Portrait of Babur.jpg|Babur mu chithuzithuzi cha mu nyengo ya Mughal.
File:Battle of Panipat (20 April 1526). Baburnama of 1598.jpg|Chithuzithuzi cha Nkhondo Yakwamba ya Panipat mu Baburnama.
File:Babur's garden in Kabul.jpg|Minda iyo yikukolerana na Babur ku Kabul.
</gallery>
== Wonaniso ==
* [[Ufumu wa Mughal]]
* [[Nkhondo yakwamba ya Panipat]]
* [[India]]
* [[Afghanistan]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Ŵakubabika mu 1483]]
[[Category:Ŵakufwa mu 1530]]
[[Category:Ŵalongozgi ŵa ku Asia]]
[[Category:Mbiri ya India]]
p6ondzjbyour4omjgvw4ffryn2o0zun
Mughal Empire
0
50391
124308
2026-11-09T21:19:43Z
Tumbuka Arch
6863
Redirected page to [[Ufumu wa Mughal]]
124308
wikitext
text/x-wiki
#REDIRECT [[Ufumu wa Mughal]]
4nhw2p8kzj48ubui97qwjnw6t27awd4
Ufumu wa Mughal
0
50392
124309
2026-11-09T21:20:10Z
Tumbuka Arch
6863
Created page with "{{Short description|Ufumu uwo ukawusa vigaŵa vikuru vya India kufuma mu 1526 mpaka 1857}} [[File:Mughal Empire 1707 AD.png|thumb|250px|Mapu gha Ufumu wa Mughal pa nyengo iyo ukaŵa ukuru chomene.]] '''Ufumu wa Mughal''' (mu Chingelezi: ''Mughal Empire'') ukaŵa ufumu ukuru uwo ukawusa vigaŵa vinandi vya [[India]] na vigaŵa vinyake vya South Asia pakati pa 1526 na 1857. Ukakhazikiskika na [[Babur]] pamanyuma pa kuwina kwake pa Nkhondo Yakwamba ya Panipat. Ufumu uwu uka..."
124309
wikitext
text/x-wiki
{{Short description|Ufumu uwo ukawusa vigaŵa vikuru vya India kufuma mu 1526 mpaka 1857}}
[[File:Mughal Empire 1707 AD.png|thumb|250px|Mapu gha Ufumu wa Mughal pa nyengo iyo ukaŵa ukuru chomene.]]
'''Ufumu wa Mughal''' (mu Chingelezi: ''Mughal Empire'') ukaŵa ufumu ukuru uwo ukawusa vigaŵa vinandi vya [[India]] na vigaŵa vinyake vya South Asia pakati pa 1526 na 1857. Ukakhazikiskika na [[Babur]] pamanyuma pa kuwina kwake pa Nkhondo Yakwamba ya Panipat. Ufumu uwu ukazgoka wakuzirwa pa ndyali, chuma, vyakuzenga na mitheto ya mu chigaŵa ichi.<ref>[https://www.britannica.com/place/Mughal-dynasty Mughal dynasty], Encyclopaedia Britannica.</ref>
== Kukhazikiskika kwa ufumu ==
Mu 1526, Babur wakathereska Ibrahim Lodi pa Nkhondo Yakwamba ya Panipat ndipo wakatora Delhi na Agra. Ichi chikamba kuwusa kwa mbumba ya Mughal mu India.
Pamanyuma pa nyifwa ya Babur mu 1530, mwana wake Humayun wakalondezga pa chitengo. Nangauli Humayun wakataya ufumu kwa nyengo yichoko, pamanyuma wakawelera ndipo wakawusaso.
== Nyengo ya Akbar ==
Akbar wakawusa kufuma mu 1556 mpaka 1605. Mu nyengo yake, ufumu wa Mughal ukakura chomene na kuunganiska vigaŵa vinandi vya kumpoto na pakati pa India.
Akbar wakanozga ndondomeko za boma, msonkho na kayendeskero ka vigaŵa. Kweniso wakazomerezga ŵanthu ŵa chisopa chakupambanapambana kugwira ntchito mu boma lake. Mu nyengo yake, vyakuzenga na luso vikakura chomene.
== Jahangir na Shah Jahan ==
Jahangir wakawusa kufuma mu 1605 mpaka 1627. Mu nyengo yake, luso lwa kujambula na kupanga vinthu vyakutowa lukakura.
Shah Jahan wakawusa kufuma mu 1628 mpaka 1658. Wakumanyikwa chomene chifukwa cha kuzenga [[Taj Mahal]] ku Agra, iyo yikazengeka nga ni manda gha muwoli wake Mumtaz Mahal. Kweniso wakazenga Red Fort ku Delhi.
== Nyengo ya Aurangzeb ==
Aurangzeb wakawusa kufuma mu 1658 mpaka 1707. Mu nyengo yake, ufumu ukathandazgikira chomene mu vigaŵa vya kumwera kwa India. Kweni nkhondo zakulutilira na masuzgo gha kawusiro vikapangiska kuti boma liŵe na masuzgo ghakuru.
== Kucepa kwa ufumu ==
Pamanyuma pa nyifwa ya Aurangzeb mu 1707, ufumu wa Mughal ukamba kuchepa nkhongono. Vigaŵa vinandi vikamba kujiyimira pawekha, ndipo magulu ghanyake gha ndyali na ŵalongozgi ŵa ku Europe ŵakakura mu nkhongono.
Mu 1857, ŵasilikari na ŵanthu ŵanyake ŵakawuska nkhondo yakugaruka ku Britain. Bahadur Shah II, fumu yaumaliro ya Mughal, wakazgoka chizindikiro cha gulu ili. Pamanyuma pa nkhondo iyi, Britain wakamuchimbizgira ku Burma ndipo ufumu wa Mughal ukamara.
== Chikhalidwe na vyakuzenga ==
Ufumu wa Mughal ukawovwira chomene pa luso, vyakuzenga, mabuku na malonda. Vyakuzenga vyakumanyikwa vya mu nyengo iyi ni:
* Taj Mahal ku Agra.
* Red Fort ku Delhi.
* Fatehpur Sikri.
* Manda gha Humayun ku Delhi.
Luso lwa Mughal lukasazganga mitheto ya ku Central Asia, Persia na India.
== Vithuzithuzi ==
<gallery>
File:Mughal Empire 1707 AD.png|Mapu gha ufumu mu 1707.
File:Taj Mahal in March 2004.jpg|Taj Mahal.
File:Red Fort Delhi.jpg|Red Fort ku Delhi.
File:Humayun's Tomb Delhi.jpg|Manda gha Humayun.
File:Akbar's tomb at Sikandra.jpg|Manda gha Akbar.
</gallery>
== Wonaniso ==
* [[Babur]]
* [[Nkhondo yakwamba ya Panipat]]
* [[India]]
* [[British Raj]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Maufumu gha kale]]
[[Category:Mbiri ya India]]
[[Category:Maufumu gha ku Asia]]
3d8eco8ktiff0vfd37lj10uk4wl01yf
First Battle of Panipat
0
50393
124310
2026-11-09T21:20:44Z
Tumbuka Arch
6863
Redirected page to [[Nkhondo Yakwamba ya Panipat]]
124310
wikitext
text/x-wiki
#REDIRECT [[Nkhondo Yakwamba ya Panipat]]
74ttd6hiyw5dzzk4dtbphdrhdtt2bqj
Nkhondo Yakwamba ya Panipat
0
50394
124311
2026-11-09T21:20:56Z
Tumbuka Arch
6863
Created page with "{{Short description|Nkhondo iyo Babur wakathereskera Ibrahim Lodi mu 1526}} [[File:Battle of Panipat (20 April 1526). Baburnama of 1598.jpg|thumb|250px|Chithuzithuzi cha nkhondo ya Panipat icho chili mu buku la Baburnama.]] '''Nkhondo Yakwamba ya Panipat''' (mu Chingelezi: ''First Battle of Panipat'') yikaŵa nkhondo iyo yikachitika pa 21 Epulero 1526 pafupi na msumba wa Panipat, mu chigaŵa icho sono chili mu charu cha [[India]]. Nkhondo iyi yikaŵa pakati pa ŵasilikar..."
124311
wikitext
text/x-wiki
{{Short description|Nkhondo iyo Babur wakathereskera Ibrahim Lodi mu 1526}}
[[File:Battle of Panipat (20 April 1526). Baburnama of 1598.jpg|thumb|250px|Chithuzithuzi cha nkhondo ya Panipat icho chili mu buku la Baburnama.]]
'''Nkhondo Yakwamba ya Panipat''' (mu Chingelezi: ''First Battle of Panipat'') yikaŵa nkhondo iyo yikachitika pa 21 Epulero 1526 pafupi na msumba wa Panipat, mu chigaŵa icho sono chili mu charu cha [[India]]. Nkhondo iyi yikaŵa pakati pa ŵasilikari ŵa [[Babur]] na ŵa Ibrahim Lodi, uyo wakaŵa mulongozgi wa Delhi Sultanate. Kuwina kwa Babur kukamba kuwusa kwa [[Ufumu wa Mughal]] mu India.<ref>[https://panipat.gov.in/first-battle/ First Battle of Panipat (1526)], District Administration, Panipat.</ref>
== Ivyo vikachitika pambere nkhondo yindambe ==
Babur wakaŵa mulongozgi wa Kabul ndipo wakakhumbanga kukhazikiska mazaza ghake mu kumpoto kwa India. Mu nyengo iyo, Ibrahim Lodi ndiyo wakawusanga Delhi Sultanate, kweni wakaŵa na masuzgo gha ubwezi na ŵalongozgi ŵanyake.
Babur wakaluta ku India na kukumana na ŵasilikari ŵa Ibrahim Lodi kufupi na Panipat. Nkhondo iyi yikaŵa yimoza mwa nkhondo zakuzirwa chomene za mu mbiri ya India.
== Nkhondo ==
Nkhondo yikachitika pa 21 Epulero 1526. Ŵasilikari ŵa Babur ŵakathereska ŵa Ibrahim Lodi. Ibrahim Lodi wakafwa pa nkhondo iyi, ndipo gulu lake likathereskeka.
Nkhondo iyi yikuzunulika chomene chifukwa cha umo Babur wakagwiliskilira ntchito ŵasilikari ŵake na vinthu vya nkhondo vya nyengo iyo. Kweni chinthu chakuzirwa chomene pa mbiri ni chakuti kuwina kwake kukasintha uyo wakaŵa na mazaza mu kumpoto kwa India.
== Ivyo vikachitika pamanyuma ==
Pamanyuma pa nkhondo, Babur wakatora Delhi na Agra. Wakakhazikiska ufumu wa Mughal uwo pamanyuma ukawusa vigaŵa vikuru vya India kwa vyaka vinandi.
Kuwina kwa Babur kukasintha mbiri ya ndyali ya mu kumpoto kwa India ndipo kukamba nyengo yiphya ya ufumu uwo ukawovwira chomene pa vyakuzenga, luso, mabuku na chikhalidwe.
== Kufunika kwake ==
Nkhondo Yakwamba ya Panipat yikupimika kuti njimoza mwa nkhondo izo zikasintha chomene mbiri ya India. Yikamara kuwusa kwa Ibrahim Lodi ndipo yikamba kwa ufumu wa Mughal.
== Vithuzithuzi ==
<gallery>
File:Battle of Panipat (20 April 1526). Baburnama of 1598.jpg|Chithuzithuzi cha nkhondo mu Baburnama.
File:Babur.jpg|Babur, mulongozgi wa ŵasilikari ŵake.
File:Panipat battle memorial.jpg|Chikumbusko cha nkhondo ya Panipat.
</gallery>
== Wonaniso ==
* [[Babur]]
* [[Ufumu wa Mughal]]
* [[India]]
* [[Mbiri ya India]]
== Ukaboni ==
<references />
[[Category:Nkhondo mu India]]
[[Category:1526]]
[[Category:Mbiri ya India]]
kuqyucr131fvb2g0k6snkuold4kudzo
British East India Company
0
50395
124312
2026-11-09T21:21:21Z
Tumbuka Arch
6863
Created page with "{{Short description|Kampani ya Britain iyo yikachita malonda na kuwusa vigaŵa vya India}} [[File:East India Company flag.svg|thumb|200px|Mbendela iyo yikakolerananga na British East India Company.]] '''British East India Company''' yikaŵa kampani ya malonda ya ku [[Britain]] iyo yikapokera chilolezo cha ufumu pa 31 Disembala 1600 kuti yichite malonda mu Asia. Pakwamba yikaguliskanga na kugura vinthu nga ni vyakuvwara, vyakununkhira, tiyi na vinthu vinyake. Pamanyuma, y..."
124312
wikitext
text/x-wiki
{{Short description|Kampani ya Britain iyo yikachita malonda na kuwusa vigaŵa vya India}}
[[File:East India Company flag.svg|thumb|200px|Mbendela iyo yikakolerananga na British East India Company.]]
'''British East India Company''' yikaŵa kampani ya malonda ya ku [[Britain]] iyo yikapokera chilolezo cha ufumu pa 31 Disembala 1600 kuti yichite malonda mu Asia. Pakwamba yikaguliskanga na kugura vinthu nga ni vyakuvwara, vyakununkhira, tiyi na vinthu vinyake. Pamanyuma, yikakura na kuŵa na mazaza gha ndyali na ŵasilikari mu vigaŵa vinandi vya [[India]].<ref>[https://www.nam.ac.uk/explore/armies-east-india-company Armies of the East India Company], National Army Museum.</ref>
== Kukhazikiskika ==
Kampani iyi yikakhazikiskika pa 31 Disembala 1600, apo Fumukazi Elizabeth I wa ku England yikayipa chilolezo chakuchitira malonda mu vigaŵa vya kumafumiro gha dazi.
Pakwamba kampani iyi yikagwiliskiranga ntchito sitima za pa nyanja kuti yichite malonda na misika ya mu Asia. Yikakhazikiska malo gha malonda mu India, kusazgapo ku Surat, Madras, Bombay na Calcutta.
== Kukura kwa mazaza mu India ==
Mu vyaka vya m'ma 1700, kampani iyi yikamba kunjira mu nkhani za ndyali na nkhondo za mu vigaŵa vya India. Yikapangana na ŵalongozgi ŵanyake na kuŵa na mazaza pa malo agho pakwamba yikachitanga waka malonda.
Mu 1757, ŵasilikari ŵa kampani ŵakathereska Nawab wa Bengal pa Nkhondo ya Plassey. Mu 1764, ŵakawinaso pa Nkhondo ya Buxar. Pamanyuma, mu 1765 kampani yikapokera wanangwa wa kusonkhaniska ndalama za msonkho mu Bengal, Bihar na Orissa.<ref>[https://www.nam.ac.uk/explore/armies-east-india-company Armies of the East India Company], National Army Museum.</ref>
== Kayendeskero ka kampani ==
Kampani iyi yikaŵa na boma lake la malonda na ŵasilikari. Yikalamuliranga vigaŵa vinyake vya India na kusonkhaniska msonkho, kweniso yikakhazikiska maofesi gha boma. Ŵasilikari ŵake ŵakaŵa na ŵanthu ŵa ku Europe na ŵa mu India awo ŵakateŵeteranga kampani.
Kukura kwa mazaza gha kampani kukapangiska kuti mu India muŵe masuzgo gha ndyali na chuma. Mu vigaŵa vinyake, ndondomeko za msonkho na malonda zikakhwaska umoyo wa ŵalimi na ŵanthu ŵanyake.
== Kugaruka kwa 1857 na kumara kwa kampani ==
Mu 1857, ŵasilikari na ŵanthu ŵanyake ŵakagarukira boma la kampani. Kugaruka uku kukamara na kusintha kukuru kwa kayendeskero ka India.
Mu 1858, boma la Britain likatora mazaza gha India kufuma ku kampani na kwamba kulamula charu ichi mwakudunjika. Kampani yikaleka milimo yake ya boma, ndipo mu 1874 yikamara mwakudunjika.
== Kufunika kwake mu mbiri ==
British East India Company yikasintha chomene mbiri ya India na ya Britain. Yikamba nga ni kampani ya malonda, kweni pamanyuma yikazgoka chimoza mwa mabungwe agho ghakawovwira kukhazikiska ukoloni wa Britain mu South Asia.
== Vithuzithuzi ==
<gallery>
File:East India Company flag.svg|Mbendela ya kampani.
File:East India House, Leadenhall Street, London.jpg|Nyumba ya kampani ku London.
File:Robert Clive.jpg|Robert Clive, mulongozgi wa kampani mu India.
File:British East India Company coin.jpg|Ndalama izo kampani yikapanga.
</gallery>
== Wonaniso ==
* [[Nkhondo ya Plassey]]
* [[British Raj]]
* [[Ufumu wa Mughal]]
* [[India]]
* [[Britain]]
== Ukaboni ==
<references />
[[Category:Makampani gha ku Britain]]
[[Category:Mbiri ya India]]
[[Category:Ukoloni wa Britain]]
djvcxawnyxn78acuc6c52fobotklnn1
Battle of Plassey
0
50396
124313
2026-11-09T21:22:08Z
Tumbuka Arch
6863
Redirected page to [[Nkhondo ya Plassey]]
124313
wikitext
text/x-wiki
#REDIRECT [[Nkhondo ya Plassey]]
73qhbaq5pjt61hrryapu8ciq4fzhlpb
Nkhondo ya Plassey
0
50397
124314
2026-11-09T21:22:31Z
Tumbuka Arch
6863
Created page with "{{Short description|Nkhondo iyo yikachitika mu 1757 na kusintha mbiri ya India}} [[File:Robert Clive and Mir Jafar after the Battle of Plassey, 1757.jpg|thumb|250px|Chithuzithuzi cha Robert Clive na Mir Jafar pamanyuma pa nkhondo.]] '''Nkhondo ya Plassey''' (mu Chingelezi: ''Battle of Plassey'') yikaŵa nkhondo iyo yikachitika pa 23 Juni 1757 ku Bengal, kumpoto chakumafumiro gha dazi kwa [[India]]. Yikaŵa pakati pa ŵasilikari ŵa [[British East India Company]], awo ŵa..."
124314
wikitext
text/x-wiki
{{Short description|Nkhondo iyo yikachitika mu 1757 na kusintha mbiri ya India}}
[[File:Robert Clive and Mir Jafar after the Battle of Plassey, 1757.jpg|thumb|250px|Chithuzithuzi cha Robert Clive na Mir Jafar pamanyuma pa nkhondo.]]
'''Nkhondo ya Plassey''' (mu Chingelezi: ''Battle of Plassey'') yikaŵa nkhondo iyo yikachitika pa 23 Juni 1757 ku Bengal, kumpoto chakumafumiro gha dazi kwa [[India]]. Yikaŵa pakati pa ŵasilikari ŵa [[British East India Company]], awo ŵakalongozgekanga na Robert Clive, na ŵasilikari ŵa Nawab Siraj-ud-Daulah wa Bengal, awo ŵakawovwirikanga na ŵanyake ŵa ku France. Kuwina kwa kampani ya Britain kukawovwira kuti yikure mu mazaza mu India.<ref>[https://www.nam.ac.uk/explore/battle-plassey Battle of Plassey], National Army Museum.</ref>
== Ivyo vikapangiska nkhondo ==
Mu vyaka vya m'ma 1700, Ufumu wa Mughal ukaŵa kuti wayamba kuchepa nkhongono, ndipo ŵalongozgi ŵa vigaŵa na mabungwe gha ku Europe ŵakakhumbanga kuŵa na mazaza pa malonda na malo gha India.
British East India Company yikaŵa na malo ghakukolerana na malonda ku Bengal. Siraj-ud-Daulah, uyo wakaŵa mulongozgi wa Bengal, wakasuskanga umo kampani iyi yikakuliranga mu mazaza na umo yikagwiliskiranga ntchito malo ghake.
Mu 1756, ŵasilikari ŵa Siraj-ud-Daulah ŵakapoka Fort William ku Calcutta. Ivi vikapangiska kuti kususkana pakati pa kampani na boma la Bengal kukure.
== Nkhondo ==
Nkhondo yikachitika pa 23 Juni 1757 kufupi na muzi wa Plassey, mumphepete mwa mlonga wa Bhagirathi. Robert Clive ndiyo wakalongozganga ŵasilikari ŵa kampani, apo Siraj-ud-Daulah ndiyo wakaŵa mulongozgi wa gulu la Bengal.
Siraj-ud-Daulah wakathereskeka ndipo wakachimbira. Pamanyuma pake wakakoleka na kukomeka. Mir Jafar, uyo wakakolerana na kampani ya Britain, wakazgoka Nawab wa Bengal.
== Ivyo vikachitika pamanyuma ==
Kuwina kwa kampani ya Britain kukawovwira kuti yiŵe na mazaza ghanandi pa Bengal. Mu 1765, kampani yikapokera wanangwa wa kusonkhaniska msonkho mu Bengal, Bihar na Orissa.
Ivi vikasintha chomene kayendeskero ka ndyali na chuma mu India. Kampani yikakura kufuma ku gulu la malonda na kuŵa na mazaza gha kuwusa vigaŵa vikuru vya charu.
== Kufunika kwake ==
Nkhondo ya Plassey yikuwoneka kuti yikaŵa chochitika chakuzirwa pa kwamba kwa ukoloni wa Britain mu India. Kuwina kwa kampani yikapangiska kuti Britain yiŵe na mazaza ghakuru pa nkhani za ndyali na chuma mu chigaŵa ichi.<ref>[https://academic.oup.com/reference/62399/reference-article-abstract/555388136 Battle of Plassey, 1757], Oxford Bibliographies.</ref>
== Vithuzithuzi ==
<gallery>
File:Robert Clive and Mir Jafar after the Battle of Plassey, 1757.jpg|Robert Clive na Mir Jafar.
File:Battle of Plassey 1757.jpg|Chithuzithuzi cha nkhondo ya Plassey.
File:Robert Clive.jpg|Robert Clive.
File:Siraj ud-Daulah.jpg|Chithuzithuzi cha Siraj-ud-Daulah.
</gallery>
== Wonaniso ==
* [[British East India Company]]
* [[British Raj]]
* [[Ufumu wa Mughal]]
* [[India]]
== Ukaboni ==
<references />
[[Category:Nkhondo mu India]]
[[Category:1757]]
[[Category:Mbiri ya India]]
td2uzth7vp4mj327fqhi7d6bs0i5q3q
British Raj
0
50398
124315
2026-11-09T21:23:09Z
Tumbuka Arch
6863
Created page with "{{Short description|Nyengo iyo Britain yikalamuliranga India mwakudunjika}} [[File:British India 1909 Imperial Gazetteer.jpg|thumb|250px|Mapu gha India mu nyengo ya kuwusa kwa Britain.]] '''Ukoloni wa Britain mu India''' (mu Chingelezi: ''British Raj'') ukaŵa nyengo iyo boma la Britain likalamuliranga vigaŵa vikuru vya India mwakudunjika. Ukamba mu 1858, pamanyuma pa kugaruka kwa ŵasilikari na ŵanthu mu 1857, ndipo ukamara mu 1947, apo India na Pakistan vikapokera wa..."
124315
wikitext
text/x-wiki
{{Short description|Nyengo iyo Britain yikalamuliranga India mwakudunjika}}
[[File:British India 1909 Imperial Gazetteer.jpg|thumb|250px|Mapu gha India mu nyengo ya kuwusa kwa Britain.]]
'''Ukoloni wa Britain mu India''' (mu Chingelezi: ''British Raj'') ukaŵa nyengo iyo boma la Britain likalamuliranga vigaŵa vikuru vya India mwakudunjika. Ukamba mu 1858, pamanyuma pa kugaruka kwa ŵasilikari na ŵanthu mu 1857, ndipo ukamara mu 1947, apo India na Pakistan vikapokera wanangwa.<ref>[https://www.nam.ac.uk/explore/why-did-indian-mutiny-happen Why did the Indian Rebellion happen?], National Army Museum.</ref>
== Kwamba kwa kuwusa kwa Britain ==
Pambere 1858 wandafike, British East India Company ndiyo yikaŵa na mazaza pa vigaŵa vikuru vya India. Kweni pamanyuma pa kugaruka kwa 1857, boma la Britain likasintha ndondomeko ya kawusiro.
Mu 1858, boma la Britain likatora mazaza kufuma ku kampani ndipo likamba kulamula India kwizira mu boma la ufumu. Mwakawiro, mulongozgi mukuru wa Britain mu India wakachemekanga Viceroy.
== Kayendeskero ka boma ==
Boma la Britain likalamuliranga vigaŵa vinandi vya India kwizira mu ŵalara awo ŵakimikiranga ufumu wa Britain. Kweniso kukaŵa maufumu ghachoko agho ghakalongozgekanga na ŵafumu ŵa mu chikaya, kweni ghakaŵa na mapangano na Britain.
Mu nyengo iyi, boma likakhazikiska njanji, maofesi, sukulu na ndondomeko za malango. Kweni ndondomeko za chuma na za msonkho zikakhwaskanga chomene ŵanthu ŵa mu chikaya, chomenechomene ŵalimi.
== Kususka ukoloni ==
Mu nyengo ya British Raj, magulu gha ŵanthu ŵa mu India ghakamba kulimbikira kuti charu chipoke wanangwa. Gulu la [[Indian National Congress]] likakhazikiskika mu 1885 ndipo likazgoka gulu lakuzirwa pa kulimbana na ukoloni.
Ŵalongozgi nga ni [[Mahatma Gandhi]], [[Jawaharlal Nehru]] na ŵanyake ŵakawovwira kulongozga gulu la wanangwa. Ŵanthu ŵakachita viyezgelero vya kususka malango, kuluta mu maulendo gha mtende na kuchita magulu gha ŵanthu.
== Nkhondo Yachiŵiri ya Charu Chose ==
Mu 1939, Britain yikanjira mu [[Nkhondo Yachiŵiri ya Charu Chose]] ndipo India nayo yikasazgikamo mu nkhondo iyi kwambura kudumbiskana na ŵalongozgi ŵa India. Ivi vikapangiska kuti kususkana pakati pa ŵalongozgi ŵa India na boma la Britain kukure.
Pamanyuma pa nkhondo, Britain yikakumana na masuzgo gha chuma na ndyali, ndipo nkhani ya kupeleka wanangwa ku India yikakura chomene.
== Wanangwa wa India na kugaŵika kwa charu ==
Pa 15 Ogasiti 1947, India yikapokera wanangwa kufuma ku Britain. Mu chaka ichocho, chigaŵa cha charu chikagaŵika ndipo Pakistan yikazgoka charu chakujiyimira pawekha.
Kugaŵika uku kukapangiska kuti ŵanthu mamiliyoni ghanandi ŵasamuke kufuma ku malo agho ŵakakhalanga, ndipo kukaŵa masuzgo ghakuru gha ŵanthu. Nyengo ya British Raj yikamara apo India na Pakistan vikapokera wanangwa.
== Chiharo cha ukoloni ==
Ukoloni wa Britain ukakhwaska malango, masambiro, chuma, ndyali na vinthu vya boma mu India. Nangauli vinthu vinyake nga ni njanji na maofesi vikakura mu nyengo iyi, ndondomeko ya ukoloni yikaŵaso na kusonkhaniska vinthu vya chuma na kulamulira ŵanthu ŵa mu chikaya.
== Vithuzithuzi ==
<gallery>
File:British India 1909 Imperial Gazetteer.jpg|Mapu gha India mu 1909.
File:British Raj Red Ensign.svg|Mbendela iyo yikakolerananga na India ya pasi pa Britain.
File:Delhi Durbar 1911.jpg|Mwambo wa Delhi Durbar mu 1911.
File:Indian independence 1947.jpg|Chikondwelero cha wanangwa wa India mu 1947.
</gallery>
== Wonaniso ==
* [[British East India Company]]
* [[Indian National Congress]]
* [[Mahatma Gandhi]]
* [[Jawaharlal Nehru]]
* [[India]]
* [[Pakistan]]
== Ukaboni ==
<references />
[[Category:Mbiri ya India]]
[[Category:Ukoloni wa Britain]]
[[Category:1858]]
[[Category:1947]]
7lg7rkhfuk6lzxa5axhobgvyux2hzcs
Indian National Congress
0
50399
124316
2026-11-09T21:23:28Z
Tumbuka Arch
6863
Created page with "{{Short description|Gulu la ndyali la ku India ilo likakhazikiskika mu 1885}} [[File:Indian National Congress session.jpg|thumb|250px|Ŵanthu awo ŵakutora chigaŵa pa ungano wa Indian National Congress.]] '''Indian National Congress''' (INC) ni gulu la ndyali la ku [[India]] ilo likakhazikiskika pa 28 Disembala 1885. Gulu ili likaŵa na ntchito yakuzirwa chomene pa kulimbana na ukoloni wa Britain na kupenja wanangwa wa India. Pamanyuma pa wanangwa, likalutilira kuŵa gu..."
124316
wikitext
text/x-wiki
{{Short description|Gulu la ndyali la ku India ilo likakhazikiskika mu 1885}}
[[File:Indian National Congress session.jpg|thumb|250px|Ŵanthu awo ŵakutora chigaŵa pa ungano wa Indian National Congress.]]
'''Indian National Congress''' (INC) ni gulu la ndyali la ku [[India]] ilo likakhazikiskika pa 28 Disembala 1885. Gulu ili likaŵa na ntchito yakuzirwa chomene pa kulimbana na ukoloni wa Britain na kupenja wanangwa wa India. Pamanyuma pa wanangwa, likalutilira kuŵa gulu la ndyali mu charu ichi.<ref>[https://inc.in/brief-history-of-congress Brief History of Congress], Indian National Congress.</ref>
== Kukhazikiskika ==
Indian National Congress yikakhazikiskika pa 28 Disembala 1885 pa ungano uwo ukachitikira ku Bombay, uko lero kukumanyikwa kuti Mumbai. Ŵanthu 72 awo ŵakaŵa ŵalongozgi, ŵalembi na ŵanthu ŵa ntchito za malango ndiwo ŵakanjira mu ungano wakwamba.
Womesh Chandra Bonnerjee ndiyo wakaŵa pulezidenti wakwamba wa ungano uwu. Allan Octavian Hume, munthu wa ku Britain uyo wakagwiranga ntchito ya boma, wakawovwira kupanga gulu ili na kunozga ungano wake wakwamba.<ref>[https://inc.in/brief-history-of-congress Brief History of Congress], Indian National Congress.</ref>
== Kulimbana na ukoloni ==
Mu nyengo zakwamba, gulu ili likakhumbanga kuti ŵa India ŵapike malo ghakuru mu kayendeskero ka boma la Britain. Pamanyuma, vilato vyake vikakura na kwambira kupenja wanangwa wakukwana wa India.
Gulu ili likawunganya ŵanthu ŵa maghanoghano ghakupambanapambana, kusazgapo ŵanthu ŵa ntchito za malango, ŵasambizgi, ŵalimi na ŵanthu ŵanyake awo ŵakakhumbanga kusintha ndondomeko ya boma.
== Ŵalongozgi ŵakumanyikwa ==
Ŵalongozgi awo ŵakagwira ntchito mu Indian National Congress ŵakasazgapo:
* Womesh Chandra Bonnerjee – pulezidenti wakwamba wa gulu.
* Dadabhai Naoroji – mulongozgi wakuzirwa mu vyaka vyakwambilira.
* Bal Gangadhar Tilak – mulwani wa ukoloni uyo wakakhozgera wanangwa wa India.
* [[Mahatma Gandhi]] – wakawovwira kulongozga magulu gha kususka ukoloni kwambura vivulupi.
* [[Jawaharlal Nehru]] – mulongozgi wa wanangwa uyo wakazgoka nduna yikuru yakwamba ya India.
* Sardar Vallabhbhai Patel – mulongozgi uyo wakawovwira kuunganiska vigaŵa vya India pamanyuma pa wanangwa.
== Wanangwa wa India ==
Mu vyaka vya m'ma 1900, Indian National Congress yikazgoka gulu likuru la kulimbana na ufumu wa Britain. Likachita viyezgelero vya kususka malango gha ukoloni, maungano gha ŵanthu na maulendo gha mtende.
Gandhi wakawovwira kuti ŵanthu ŵanandi ŵanthu ŵa mu India ŵanjire mu nkhondo ya wanangwa. Nehru wakazgoka yumoza mwa ŵalongozgi ŵakuzirwa chomene mu gulu ili.
India yikapokera wanangwa pa 15 Ogasiti 1947.
== Pamanyuma pa wanangwa ==
Pamanyuma pa 1947, Indian National Congress yikazgoka gulu la ndyali ilo likapikanga mazaza mu boma la India. Jawaharlal Nehru wakazgoka nduna yikuru yakwamba ya charu.
Gulu ili likalutilira kutora chigaŵa mu ndyali za India mu nyengo zakupambanapambana, ndipo ŵalongozgi ŵake ŵakasintha kuyana na nyengo.
== Vithuzithuzi ==
<gallery>
File:Indian National Congress session.jpg|Ungano wa Indian National Congress.
File:Mahatma Gandhi.jpg|Mahatma Gandhi, mulongozgi wa wanangwa wa India.
File:Jawaharlal Nehru 1947.jpg|Jawaharlal Nehru.
File:Indian National Congress 1885.jpg|Mbiri ya ungano wakwamba wa gulu.
</gallery>
== Wonaniso ==
* [[Mahatma Gandhi]]
* [[Jawaharlal Nehru]]
* [[British Raj]]
* [[India]]
* [[Wanangwa wa India]]
== Ukaboni ==
<references />
[[Category:Magulu gha ndyali mu India]]
[[Category:Mbiri ya India]]
[[Category:1885]]
c5hbc4b94ux74yl71lo29kk8cp6ss9n
Jawaharlal Nehru
0
50400
124317
2026-11-09T21:23:51Z
Tumbuka Arch
6863
Created page with "{{Short description|Nduna yikuru yakwamba ya India}} [[File:Jawaharlal Nehru 1947.jpg|thumb|200px|Jawaharlal Nehru mu 1947.]] '''Jawaharlal Nehru''' (14 Novembala 1889 – 27 Meyi 1964) wakaŵa mulongozgi wa wanangwa wa [[India]] na nduna yikuru yakwamba ya charu ichi. Wakagwira ntchito iyi kufuma pa 15 Ogasiti 1947 mpaka pa nyifwa yake mu 1964. Wakaŵa yumoza mwa ŵalongozgi ŵakuzirwa ŵa [[Indian National Congress]] ndipo wakawovwira kupanga ndyali za India pamanyuma..."
124317
wikitext
text/x-wiki
{{Short description|Nduna yikuru yakwamba ya India}}
[[File:Jawaharlal Nehru 1947.jpg|thumb|200px|Jawaharlal Nehru mu 1947.]]
'''Jawaharlal Nehru''' (14 Novembala 1889 – 27 Meyi 1964) wakaŵa mulongozgi wa wanangwa wa [[India]] na nduna yikuru yakwamba ya charu ichi. Wakagwira ntchito iyi kufuma pa 15 Ogasiti 1947 mpaka pa nyifwa yake mu 1964. Wakaŵa yumoza mwa ŵalongozgi ŵakuzirwa ŵa [[Indian National Congress]] ndipo wakawovwira kupanga ndyali za India pamanyuma pa kupokera wanangwa.<ref>[https://www.pmindia.gov.in/en/former_pm/shri-jawaharlal-nehru/ Shri Jawaharlal Nehru], Prime Minister's Office, Government of India.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Nehru wakababika pa 14 Novembala 1889 mu msumba wa Allahabad, uwo mazuŵa ghano ukuchemeka Prayagraj, mu chigaŵa cha Uttar Pradesh, India. Awiske ŵakaŵa Motilal Nehru, loya na mulongozgi wa ndyali. Amama ŵake ŵakaŵa Swarup Rani Nehru.
Nehru wakasambira mu nyumba apo wakaŵa mwana, ndipo mu 1905 wakaluta ku England. Wakasambira ku Harrow School, Trinity College pa University of Cambridge, ndipo pamanyuma wakasambira vya malango ku Inner Temple ku London.<ref>[https://nehruportal.nic.in/early-life Early Life], Nehru Portal, Ministry of Culture, Government of India.</ref>
== Kunjira mu ndyali ==
Nehru wakawelera ku India mu 1912 ndipo wakamba kugwira ntchito ya malango. Pamanyuma wakanjira mu ndyali na kukolerana na gulu la Indian National Congress.
Mu 1916, wakakumana na [[Mahatma Gandhi]], ndipo wakamba kutora chigaŵa mu magulu ghakususka ukoloni wa Britain. Wakakolerana na magulu gha ŵanthu awo ŵakakhumbanga kuti India yiŵe na wanangwa.
Mu nyengo ya nkhondo ya wanangwa, Nehru wakakakika kanandi chifukwa cha milimo yake ya ndyali. Wakatora chigaŵa mu magulu gha kususka ukoloni na kulimbikira kuti India yiŵe charu chakujiyimira pawekha.<ref>[https://nehruportal.nic.in/freedom-struggle Freedom Struggle], Nehru Portal, Ministry of Culture, Government of India.</ref>
== Nduna yikuru yakwamba ya India ==
Pa 15 Ogasiti 1947, India yikapokera wanangwa kufuma ku Britain. Zuŵa lenelili, Nehru wakamba ntchito ya kuŵa nduna yikuru yakwamba ya charu ichi.
Mu nyengo yake, boma likakhazikiska ndondomeko za masambiro, sayansi, mafakitale na ulimi. Kweniso wakawovwira kukhazikiska mabungwe gha boma agho ghakaŵa na milimo ya kusambizga, kafukufuku na kuzenga chuma.
Nehru wakakhozgeranga ndondomeko ya kuti India yileke kujipatura mu magulu gha vyaru vya nkhongono. Wakawovwira kukhazikiska gulu la vyaru ivyo vikasankha kuleka kunjira mu magulu gha nkhondo ghakulongozgeka na vyaru vikuru pa nyengo ya Nkhondo ya Kuzizima.
== Umoyo wa mbumba ==
Nehru wakatorana na Kamala Kaul mu 1916. Ŵakaŵa na mwana mwanakazi yumoza, Indira Gandhi, uyo pamanyuma nayo wakazgoka nduna yikuru ya India.
== Nyifwa na chiharo ==
Jawaharlal Nehru wakafwa pa 27 Meyi 1964 mu New Delhi. Wakakumbukika chifukwa cha milimo yake mu nkhondo ya wanangwa na ntchito yake yakuzenga boma la India pamanyuma pa wanangwa.
Zuŵa lake la kubabika, 14 Novembala, likukumbukika mu India nga ni zuŵa la ŵana, ilo likuchemeka ''Children's Day''.
== Vithuzithuzi ==
<gallery>
File:Jawaharlal Nehru 1947.jpg|Nehru mu 1947.
File:Jawaharlal Nehru.jpg|Chithuzithuzi cha Nehru.
File:Nehru and Gandhi.jpg|Nehru na Mahatma Gandhi.
File:Jawaharlal Nehru speaking.jpg|Nehru wakuyowoya pa ungano.
</gallery>
== Wonaniso ==
* [[Mahatma Gandhi]]
* [[Indian National Congress]]
* [[India]]
* [[British Raj]]
* [[Narendra Modi]]
== Ukaboni ==
<references />
[[Category:Ŵanthu ŵakubabika mu 1889]]
[[Category:Ŵakufwa mu 1964]]
[[Category:Ŵalongozgi ŵa India]]
[[Category:Nduna zikuru za India]]
[[Category:Mbiri ya India]]
bumjmzq2uneuoosqa296bvhb33sqme8
Constitution of India
0
50401
124318
2026-11-09T21:24:23Z
Tumbuka Arch
6863
Redirected page to [[Malango gha India]]
124318
wikitext
text/x-wiki
#REDIRECT [[Malango gha India]]
cdonee5nu0vd9cbtsa2euf0h69elkb7
Malango gha India
0
50402
124319
2026-11-09T21:24:40Z
Tumbuka Arch
6863
Created page with "{{Short description|Dango likuru ilo likulongozga boma la India}} [[File:Constitution of India.jpg|thumb|250px|Buku la Malango gha India.]] '''Malango gha India''' (mu Chingelezi: ''Constitution of India'') ni dango likuru chomene la charu cha [[India]]. Likulongosora umo boma likwenera kugwilira ntchito, mazaza gha mabungwe gha boma, wanangwa na milimo ya ŵanthu, kweniso umo malango ghanyake ghakwenera kupangikira. Dango ili likazomerezgeka pa 26 Novembala 1949 ndipo l..."
124319
wikitext
text/x-wiki
{{Short description|Dango likuru ilo likulongozga boma la India}}
[[File:Constitution of India.jpg|thumb|250px|Buku la Malango gha India.]]
'''Malango gha India''' (mu Chingelezi: ''Constitution of India'') ni dango likuru chomene la charu cha [[India]]. Likulongosora umo boma likwenera kugwilira ntchito, mazaza gha mabungwe gha boma, wanangwa na milimo ya ŵanthu, kweniso umo malango ghanyake ghakwenera kupangikira. Dango ili likazomerezgeka pa 26 Novembala 1949 ndipo likamba kugwira ntchito pa 26 Janyuwale 1950.<ref>[https://sansad.in/ls/about/introduction Constitution of India], Digital Sansad, Parliament of India.</ref>
== Kulembeka kwa malango ==
Pamanyuma pa kupokera wanangwa mu 1947, India yikakhumbikwiranga dango liphya ilo lingalongozga boma la charu chakujiyimira pawekha.
Constituent Assembly ndiyo yikagwira ntchito yakulemba dango ili. Gulu ili likaŵa na ŵimiliri awo ŵakafuma mu vigaŵa vyakupambanapambana vya India. B.R. Ambedkar wakalongozga komiti iyo yikanozganga kulemba kwa dango.
Dango ili likazomerezgeka na Constituent Assembly pa 26 Novembala 1949. Likamba kugwira ntchito pa 26 Janyuwale 1950, zuŵa ilo lero likukumbukika mu India nga ni Republic Day.<ref>[https://sansad.in/ls/about/introduction Introduction: Constitution of India], Parliament of India.</ref>
== Umo dango liliri ==
Dango la India lili na vigaŵa vinandi ivyo vikulongosora umo boma likwenera kugwilira ntchito. Likulongosora:
* Mazaza gha boma la pakati na maboma gha vigaŵa.
* Milimo ya Pulezidenti na Nduna Yikuru.
* Kayendeskero ka nyumba za malango.
* Milimo ya makhoti.
* Wanangwa wakuzirwa wa ŵanthu.
* Milimo ya ŵanthu na mabungwe gha boma.
Dango ili likukhazikiska ndondomeko ya boma la demokilase ilo lili na nyumba ya malango, ndipo likuŵika mazaza gha charu mu mawoko gha ŵanthu.
== Wanangwa wa ŵanthu ==
Dango la India likuzomerezga wanangwa wakuzirwa, kusazgapo wanangwa wa kuyowoya, kusopa, kuwungana mwamtende na kukhala mu charu. Kweniso likulongosora kuti ŵanthu ŵakwenera kulondezga malango na milimo yawo nga ni ŵanthu ŵa charu.
== Mabungwe gha boma ==
Dango ili likukhazikiska mabungwe ghakuru gha boma:
* Pulezidenti wa India.
* Nyumba ya malango ya pakati, iyo yili na Lok Sabha na Rajya Sabha.
* Kabineti iyo yikulongozgeka na Nduna Yikuru.
* Makhoti, kusazgapo Supreme Court.
* Maboma gha vigaŵa vya India.
== Kusintha kwa malango ==
Dango la India lingasinthika kwizira mu ndondomeko iyo yili kulembeka mukati mwake. Pamanyuma pa 1950, dango ili lasinthika kanandi kuti lilongozge vinthu ivyo vikasintha mu charu.
== Kufunika kwake ==
Malango gha India ngakuzirwa chifukwa ghakuŵa maziko gha boma, makhoti, wanangwa wa ŵanthu na umo charu chikwendeskekera. Kweniso ghakuwovwira kusunga ndondomeko ya boma la demokilase.
== Vithuzithuzi ==
<gallery>
File:Constitution of India.jpg|Buku la Malango gha India.
File:Constitution of India original.jpg|Malemba ghakwambilira gha dango.
File:B R Ambedkar.jpg|B. R. Ambedkar, uyo wakalongozga komiti yakulemba dango.
File:Constituent Assembly of India.jpg|Ŵanthu ŵa mu Constituent Assembly.
</gallery>
== Wonaniso ==
* [[India]]
* [[Jawaharlal Nehru]]
* [[Indian National Congress]]
* [[B. R. Ambedkar]]
* [[Demokilase]]
== Ukaboni ==
<references />
[[Category:Malango gha India]]
[[Category:Mbiri ya India]]
[[Category:1950]]
8xaurelo1f2k1y9twy064cxc6kx9due
Narendra Modi
0
50403
124320
2026-11-09T21:24:55Z
Tumbuka Arch
6863
Created page with "{{Short description|Nduna yikuru ya India}} [[File:Narendra Modi official portrait.jpg|thumb|200px|Narendra Modi.]] '''Narendra Modi''' (wakababika pa 17 Seputembala 1950) ni mulongozgi wa ndyali wa ku [[India]] uyo wakhala nduna yikuru ya charu ichi kwambira pa 26 Meyi 2014. Ni membala wa gulu la ndyali la Bharatiya Janata Party (BJP). Wakagwiranga ntchito nga ni nduna yikuru ya chigaŵa cha Gujarat pambere wandazgoke nduna yikuru ya India.<ref>[https://sansad.in/ls/mem..."
124320
wikitext
text/x-wiki
{{Short description|Nduna yikuru ya India}}
[[File:Narendra Modi official portrait.jpg|thumb|200px|Narendra Modi.]]
'''Narendra Modi''' (wakababika pa 17 Seputembala 1950) ni mulongozgi wa ndyali wa ku [[India]] uyo wakhala nduna yikuru ya charu ichi kwambira pa 26 Meyi 2014. Ni membala wa gulu la ndyali la Bharatiya Janata Party (BJP). Wakagwiranga ntchito nga ni nduna yikuru ya chigaŵa cha Gujarat pambere wandazgoke nduna yikuru ya India.<ref>[https://sansad.in/ls/members/biography/4589 Modi, Shri Narendra], Digital Sansad, Parliament of India.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Modi wakababika pa 17 Seputembala 1950 mu msumba wa Vadnagar, mu chigaŵa cha Gujarat, India. Awiske ŵakaŵa Damodardas Modi ndipo amama ŵake ŵakaŵa Hiraben Modi.
Wakasambira mu sukulu za mu chigaŵa chake ndipo pamanyuma wakalutilira na masambiro gha pa yunivesite. Malemba gha Nyumba ya Malango ya India ghakulongora kuti wakasambira vya ndyali pa Gujarat University na Delhi University.<ref>[https://sansad.in/ls/members/biography/4589 Modi, Shri Narendra], Digital Sansad, Parliament of India.</ref>
== Kwamba kwa milimo ya ndyali ==
Modi wakamba kutora chigaŵa mu milimo ya magulu gha ndyali apo wakaŵa wachoko. Wakagwira ntchito mu gulu la Rashtriya Swayamsevak Sangh, ndipo pamanyuma wakatora chigaŵa mu Bharatiya Janata Party.
Mu vyaka vya m'ma 1990, wakagwira ntchito zakupambanapambana mu gulu la BJP. Wakazgoka yumoza wa ŵanthu awo ŵakaŵa na milimo yakuzirwa pakunozga ntchito za gulu ili.
== Nduna yikuru ya Gujarat ==
Mu 2001, Modi wakazgoka nduna yikuru ya chigaŵa cha Gujarat. Wakagwira ntchito iyi mpaka 2014, apo wakasankhika kuŵa mulongozgi wa boma la India.
Mu nyengo yake ya kuwusa Gujarat, nkhani za kukura kwa mafakitale, ulimi, vinthu vya boma na masuzgo gha ndyali zikaŵa pakati pa vinthu ivyo ŵanthu ŵakadumbiskananga chomene.
== Nduna yikuru ya India ==
Pa 26 Meyi 2014, Modi wakalapa kuŵa nduna yikuru ya India. Wakawelera ku udindo uwu pamanyuma pa mavoti gha 2019 na 2024. Pa nyengo ya 2024, wakalapa kachitatu pa 9 Juni 2024.<ref>[https://www.pmindia.gov.in/en/personal-life-story/ Personal Life Story], Prime Minister's Office, Government of India.</ref>
Mu ntchito yake ya nduna yikuru, boma lake lakhala likugwira ntchito pa ndondomeko za chuma, vinthu vya digito, misewu na njanji, umoyo wa ŵanthu, ndondomeko za msonkho na ubwezi wa India na vyaru vinyake.
== Ndyali na ndondomeko za boma ==
Modi wakulongozga boma la India kwizira mu ndondomeko ya nyumba ya malango. Boma lake likuchita ntchito mu nkhani za chuma, chitukuko cha misewu, sayansi, tekinoloje na chitetezo cha charu.
Ndemanga za ndondomeko zake na umo zakhwaskira ŵanthu zikusiyana pakati pa ŵanthu, magulu gha ndyali na ŵakusambira. Nkhani izi zikupimika na ŵanthu kwizira mu mavoti na kudumbiskana pa nkhani za boma.
== Vithuzithuzi ==
<gallery>
File:Narendra Modi official portrait.jpg|Chithuzithuzi cha Narendra Modi.
File:Narendra Modi 2014.jpg|Modi mu 2014.
File:Narendra Modi at the Red Fort.jpg|Modi pa mwambo wa ku Red Fort.
File:Narendra Modi in 2024.jpg|Modi mu 2024.
</gallery>
== Wonaniso ==
* [[India]]
* [[Jawaharlal Nehru]]
* [[Indian National Congress]]
* [[Malango gha India]]
* [[Bharatiya Janata Party]]
== Ukaboni ==
<references />
[[Category:Ŵakubabika mu 1950]]
[[Category:Ŵanthu ŵa ku India]]
[[Category:Nduna zikuru za India]]
[[Category:Ŵanthu ŵamoyo]]
[[Category:Mbiri ya India]]
t5j1vq8z2pznft6w4okpjdpwiu4w0pd
Mbiri ya Brazil
0
50404
124321
2026-11-09T21:25:23Z
Tumbuka Arch
6863
Created page with "{{Short description|Mbiri ya charu cha Brazil kufuma mu nyengo zakale mpaka lero}} [[File:Brazil location in South America map.svg|thumb|250px|Malo agho Brazil yili mu South America.]] '''Mbiri ya Brazil''' yikulongosora vya ŵanthu, maboma, nkhondo, chuma na chikhalidwe cha charu cha [[Brazil]] kufuma mu nyengo zakale mpaka mazuŵa ghano. Brazil ndiyo charu chikuru chomene mu [[South America]], ndipo yili na mbiri iyo yakhwaskika na mitheto ya ŵanthu ŵa mu charu ichi,..."
124321
wikitext
text/x-wiki
{{Short description|Mbiri ya charu cha Brazil kufuma mu nyengo zakale mpaka lero}}
[[File:Brazil location in South America map.svg|thumb|250px|Malo agho Brazil yili mu South America.]]
'''Mbiri ya Brazil''' yikulongosora vya ŵanthu, maboma, nkhondo, chuma na chikhalidwe cha charu cha [[Brazil]] kufuma mu nyengo zakale mpaka mazuŵa ghano. Brazil ndiyo charu chikuru chomene mu [[South America]], ndipo yili na mbiri iyo yakhwaskika na mitheto ya ŵanthu ŵa mu charu ichi, ukoloni wa [[Portugal]], malonda gha ŵanthu ŵa mu wuzga na kusintha kwa ndyali.
== Ŵanthu ŵakwambilira ==
Pambere ŵanthu ŵa ku Europe ŵandafike, mu chigaŵa icho sono ni Brazil mukaŵa mitundu yinandi ya ŵanthu ŵakwambilira. Ŵanthu aŵa ŵakaŵa na viyowoyero, mitheto na nthowa zakupambanapambana za kukhala. Ŵanyake ŵakalima, ŵanyake ŵakasaka vinyama, kukola somba na kuwunjika vipambi.
Ŵanthu ŵakwambilira aŵa ŵakakhalanga mu nkhorongo ya Amazon, mumphepete mwa nyanja na mu vigaŵa vinyake vya charu. Ŵanthu ŵanandi ŵa mu Brazil mazuŵa ghano ŵali na mphapu za ŵanthu aŵa, nangauli mitheto na viyowoyero vinyake vikususkika na masinthiro gha nyengo zakupambanapambana.
== Nyengo ya ukoloni wa Portugal ==
Mu Epulero 1500, munthu wakwendeska sitima wa ku Portugal, [[Pedro Álvares Cabral]], wakafika pa mphepete mwa charu icho sono ni Brazil. Portugal yikamba kuwusa malo agha, ndipo mu 1530s yikamba kukhazikiska malo ghakukhala ŵanthu ŵa ku Europe.
Mu nyengo ya ukoloni, ŵanthu ŵa ku Portugal ŵakalima nzimbe na kupanga shuga kuti ŵaguliske ku vyaru vinyake. Pamanyuma, golide na vinthu vinyake vyakuzirwa vikapelekeka mu malonda. Ŵanthu ŵanandi ŵa mu Africa ŵakakoleskeka na kutolekera ku Brazil mwakuchichizgika kuti ŵakagwire ntchito mu minda na mu migodi.
Ukoloni uwu ukasintha chomene umoyo wa ŵanthu ŵakwambilira, ndipo ŵanthu ŵanandi ŵakafwa chifukwa cha matenda, nkhondo na ntchito zakuchichizgika.
== Ufumu wa Brazil ==
Pa 7 Seputembala 1822, Dom Pedro wakapharazga kuti Brazil yilekenge kulamulirika na Portugal. Pamanyuma wakazgoka Fumu Pedro I, ndipo Brazil yikazgoka ufumu wakujiyimira pawekha.
Mu 1831, Pedro I wakaleka chitengo ndipo mwana wake Pedro II wakazgoka fumu. Pakuti Pedro II wakaŵa mwana muchoko, charu chikawusika na ŵalara ŵa boma mpaka apo wakakwaniskira msinkhu wa kuwusa.
Mu nyengo ya Pedro II, Brazil yikakura mu malonda, njanji, masambiro na vyakuzenga. Kweni malonda gha ŵanthu ŵa mu wuzga ghakalutilira mpaka mu 1888, apo dango la Lei Áurea likamazga ukapolo.
== Kukhazikiska Republic ==
Pa 15 Novembala 1889, ŵasilikari ŵakachita kusintha kwa boma ndipo ufumu ukamara. Brazil yikazgoka republic, ndipo Deodoro da Fonseca wakazgoka mulongozgi wakwamba wa charu ichi.
Mu nyengo yakwamba ya republic, ndyali zikawusika chomene na ŵalongozgi na ŵanthu ŵa chuma cha ulimi. Ŵanthu ŵanandi ŵakaŵa na mwaŵi uchoko wa kutora chigaŵa mu ndyali.
== Nyengo ya Getúlio Vargas ==
Mu 1930, Getúlio Vargas wakatora mazaza pamanyuma pa kusintha kwa boma. Wakawusa mu nyengo zakupambanapambana mpaka 1945. Mu 1937, wakakhazikiska boma la wuzga wa ndyali ilo likachemekanga [[Estado Novo]].
Mu nyengo iyi, boma likazikiska mazaza ghake, likalamuliranga mabungwe gha ŵanthu, ndipo likagwiliskiranga ntchito vyakupharazga vya boma kulongora ndondomeko zake. Kweni boma ili likachitaso masinthiro gha malango gha ntchito na kukhozga ntchito za mafakitale.
Vargas wakaweleraso kuŵa pulezidenti kwizira mu mavoti mu 1951, kweni wakafwa mu 1954.
== Nyengo ya demokilase na boma la ŵasilikari ==
Pamanyuma pa 1945, Brazil yikawelera ku ndondomeko ya mavoti na maboma ghakusankhika. Kweni mu 1964, ŵasilikari ŵakachita kusintha kwa boma ndipo ŵakatora mazaza.
Boma la ŵasilikari likawusa mpaka 1985. Mu nyengo iyi, ŵanthu ŵakakumana na kukanizgika kwa wanangwa wa kuyowoya, kuwungana na kususkana na boma. Ŵanthu ŵanyake ŵakakakika ndipo ŵanyake ŵakachimbira mu charu.
== Brazil ya mazuŵa ghano ==
Mu 1985, Brazil yikamba kuwelera ku boma la ŵanthu ŵambura kuŵa ŵasilikari. Mu 1988, dango liphya likazomerezgeka, ndipo likakhazikiska ndondomeko ya demokilase na wanangwa wa ŵanthu.
Brazil mazuŵa ghano ni republic ya demokilase iyo yili na ndondomeko ya boma la pulezidenti. Yili na vigaŵa 26 na Federal District. Likuru la boma ni Brasília.
== Vithuzithuzi ==
<gallery>
File:Pedro Américo - Independência ou Morte - Google Art Project.jpg|Chithuzithuzi cha kupharazga wanangwa wa Brazil mu 1822.
File:DpedroI-brasil.png|Fumu Pedro I.
File:Retrato do Imperador Dom Pedro II.jpg|Fumu Pedro II.
File:Getúlio Vargas - 1930.jpg|Getúlio Vargas mu 1930.
File:Constituição da República Federativa do Brasil 1988 (livro de bolso,exemplar especial pela Encyclopaedia Britannica do Brasil).JPG|Buku la dango la Brazil la 1988.
File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|Nyumba ya Nyumba ya Malango ya Brazil ku Brasília.
</gallery>
== Wonaniso ==
* [[Brazil]]
* [[Estado Novo]]
* [[Petrobras]]
* [[Demokilase]]
* [[Ŵalongozgi ŵa Brazil]]
* [[Ndyali za ku South America]]
== Ukaboni ==
<references>
<ref>{{Cite web |url=https://www.loc.gov/item/2011525299/ |title=Brazil: A Country Study |publisher=Library of Congress}}</ref>
<ref>{{Cite web |url=https://www2.camara.leg.br/a-camara/conheca/historia-e-arquivo |title=História e Arquivo da Câmara dos Deputados |publisher=Chamber of Deputies of Brazil}}</ref>
<ref>{{Cite web |url=https://www.everycrsreport.com/reports/R46236.html |title=Brazil: Background and U.S. Relations |publisher=Congressional Research Service}}</ref>
</references>
[[Category:Mbiri ya Brazil]]
[[Category:Mbiri ya South America]]
[[Category:Brazil]]
iavyh6qdrxrwtqxwidwdru1txjwzbtn
Estado Novo
0
50405
124322
2026-11-09T21:25:54Z
Tumbuka Arch
6863
Created page with "{{Short description|Boma la wuzga wa ndyali ilo likawusa Brazil pakati pa 1937 na 1945}} [[File:Retrato de Getúlio Vargas (1938).jpg|thumb|200px|Chithuzithuzi cha Getúlio Vargas mu 1938.]] '''Estado Novo''' likaŵa boma la wuzga wa ndyali ilo likawusa [[Brazil]] kufuma pa 10 Novembala 1937 mpaka pa 29 Okutobala 1945. Boma ili likalongozgekanga na [[Getúlio Vargas]], uyo wakatora mazaza mu 1930. Lizgu lakuti ''Estado Novo'' ni Chiphwitikizi ndipo likung'anamura kuti ''..."
124322
wikitext
text/x-wiki
{{Short description|Boma la wuzga wa ndyali ilo likawusa Brazil pakati pa 1937 na 1945}}
[[File:Retrato de Getúlio Vargas (1938).jpg|thumb|200px|Chithuzithuzi cha Getúlio Vargas mu 1938.]]
'''Estado Novo''' likaŵa boma la wuzga wa ndyali ilo likawusa [[Brazil]] kufuma pa 10 Novembala 1937 mpaka pa 29 Okutobala 1945. Boma ili likalongozgekanga na [[Getúlio Vargas]], uyo wakatora mazaza mu 1930. Lizgu lakuti ''Estado Novo'' ni Chiphwitikizi ndipo likung'anamura kuti ''Boma Liphya''.<ref>{{Cite web |url=https://atlas.fgv.br/verbete/5863 |title=Estado Novo |publisher=Fundação Getulio Vargas}}</ref>
== Ivyo vikapangiska kuti boma ili likhazikiskike ==
Mu vyaka vya m'ma 1930, Brazil yikaŵa na masuzgo gha ndyali na kupambana maghanoghano pakati pa magulu gha ndyali. Getúlio Vargas wakawusa kufuma mu 1930, ndipo mu 1934 wakakhazikiska dango liphya la charu.
Mu 1937, apo mavoti gha pulezidenti ghakeneranga kuchitika, Vargas wakapharazga kuti charu chikakumana na ngozi ya kuwukira kwa ŵanthu ŵa chisopa cha chikomyunizimu. Boma likagwiliskira ntchito nkhani iyi kuti likhazikiske ndondomeko yiphya ya kuwusa.
Pa 10 Novembala 1937, Vargas wakachita kusintha kwa boma, wakamazga nyumba ya malango na kukhazikiska boma la Estado Novo.<ref>{{Cite web |url=https://atlas.fgv.br/verbete/5863 |title=Estado Novo |publisher=Fundação Getulio Vargas}}</ref>
== Umo boma likawusiranga ==
Estado Novo likaŵa boma ilo mazaza ghanandi ghakaŵa mu mawoko gha pulezidenti. Nyumba ya malango yikajara, ndipo magulu gha ndyali ghakakanizgika. Maboma gha vigaŵa ghakaŵa pasi pa ulongozgi wa boma la pakati.
Boma likagwiliskiranga ntchito ŵalara ŵake kulamulira vigaŵa vya charu. Likakhazikiskaso ndondomeko za kupenja chovwiri cha ŵanthu kwizira mu vyakupharazga vya boma.
== Kukanizga wanangwa na vyakupharazga ==
Mu nyengo ya Estado Novo, boma likalamuliranga nkhani izo zikafumanga mu manyuzipepala, wayilesi na vyakujambura. Magulu agho ghakasuskanga boma ghakasuzgika, ndipo ŵanthu ŵanyake ŵakakakika chifukwa cha maghanoghano ghawo gha ndyali.
Dipartimenti ya boma ya vyakupharazga na propaganda yikagwira ntchito yakupanga zithuzithuzi vya Vargas nga ni mulongozgi uyo wakateŵeteranga ŵanthu. Sumu, mafilimu na vyakuchitika vya boma vikagwiliskirika ntchito pakuthandazga maghanoghano gha boma.
== Ntchito na chuma ==
Mu nyengo iyi, boma likawovwira kukura kwa mafakitale na ntchito za boma. Likakhazikiska na kukhozga mabungwe ghakupanga visulo, mafuta na vinthu vinyake vyakuzirwa.
Mu 1943, boma likalemba malango ghakusazgika gha ntchito, agho ghakakhazikiska ndondomeko zakupambanapambana za wanangwa wa ŵantchito. Malango agha ghakaŵa chigaŵa cha ndondomeko ya Vargas yakukhozga ubwezi pakati pa boma na ŵantchito.
== Brazil mu Nkhondo Yachiŵiri ya Charu Chose ==
Mu 1939, Nkhondo Yachiŵiri ya Charu Chose yikamba, ndipo Brazil pakwamba yikajipeleka kuŵa charu chambura kutora chigaŵa. Mu 1942, pamanyuma pa sitima za Brazil kuwukiridwa mu nyanja ya Atlantic, boma likapharazga nkhondo na vyaru vya Axis.
Brazil yikakolerana na Allies ndipo yikatuma ŵasilikari kukalimbana ku Italy. Ivi vikapangiska mphambano yakuwoneka pakati pa boma la wuzga wa ndyali ilo likawusanga mu charu na nkhondo ya kulimbana na maboma gha wuzga wa ndyali ku Europe.<ref>{{Cite web |url=https://academic.oup.com/edited-volume/61800/chapter-abstract/546364189 |title=The Estado Novo: Politics and Political Propaganda in Brazil, 1937–1945 |publisher=Oxford Research Encyclopedia of Latin American History}}</ref>
== Kumara kwa Estado Novo ==
Pamanyuma pa nkhondo, ŵanthu ŵanandi mu Brazil ŵakamba kudangizga kuti charu chiwelere ku ndondomeko ya demokilase. Ŵasilikari na magulu gha ndyali nawo ŵakamba kususka boma la Vargas.
Pa 29 Okutobala 1945, Vargas wakafumiskika pa mazaza na ŵasilikari. Ichi chikamara nyengo ya Estado Novo, ndipo mu 1946 boma liphya likakhazikiska dango liphya la charu.<ref>{{Cite web |url=https://www2.camara.leg.br/a-camara/conheca/historia/Ex_presidentesCD_Republica/republica3.html |title=3ª República (1937–1946) |publisher=Chamber of Deputies of Brazil}}</ref>
== Kufunika kwake mu mbiri ==
Estado Novo yikaŵa nyengo yakuzirwa mu mbiri ya Brazil chifukwa yikakhozga mazaza gha boma la pakati, yikakhwaska ntchito za mafakitale, na kusintha ubwezi pakati pa boma na ŵantchito. Kweni yikakumbukikaso chifukwa cha kukanizga magulu gha ndyali, kuwusa kwambura demokilase na kulamulira vyakupharazga.
== Vithuzithuzi ==
<gallery>
File:Getúlio Vargas - 1930.jpg|Getúlio Vargas mu 1930.
File:Getúlio Vargas - retrato oficial de 1930.JPG|Chithuzithuzi cha Vargas icho chikagwiliskirika ntchito mu nyengo yakwamba ya kuwusa kwake.
File:Retrato de Getúlio Vargas (1938).jpg|Chithuzithuzi cha Vargas cha mu 1938.
File:Estado Novo1 - 1935.jpg|Chithuzithuzi cha ndyali za Brazil mu vyaka vya m'ma 1930.
</gallery>
== Wonaniso ==
* [[Getúlio Vargas]]
* [[Mbiri ya Brazil]]
* [[Nkhondo Yachiŵiri ya Charu Chose]]
* [[Demokilase]]
* [[Petrobras]]
== Ukaboni ==
<references />
[[Category:Mbiri ya Brazil]]
[[Category:Wuzga wa ndyali]]
[[Category:1937]]
[[Category:1945]]
6v9l9znh9e74i75hkvnfoqgpgdw8965
Petrobras
0
50406
124323
2026-11-09T21:26:19Z
Tumbuka Arch
6863
Created page with "{{Short description|Kampani ya mafuta na gasi iyo yili pasi pa ulongozgi wa boma la Brazil}} [[File:Petrobras horizontal logo.svg|thumb|250px|Chimanyikwiro cha Petrobras.]] '''Petrobras''' (zina lose: ''Petróleo Brasileiro S.A.'') ni kampani ya mafuta na gasi ya ku [[Brazil]]. Yikugwira ntchito za kusanga, kufukura, kupanga, kusungira, kunyamula na kunozga mafuta na gasi. Kampani iyi yili pasi pa ulongozgi wa boma la Brazil, nangauli magawo ghake ghakuguliskika pa misik..."
124323
wikitext
text/x-wiki
{{Short description|Kampani ya mafuta na gasi iyo yili pasi pa ulongozgi wa boma la Brazil}}
[[File:Petrobras horizontal logo.svg|thumb|250px|Chimanyikwiro cha Petrobras.]]
'''Petrobras''' (zina lose: ''Petróleo Brasileiro S.A.'') ni kampani ya mafuta na gasi ya ku [[Brazil]]. Yikugwira ntchito za kusanga, kufukura, kupanga, kusungira, kunyamula na kunozga mafuta na gasi. Kampani iyi yili pasi pa ulongozgi wa boma la Brazil, nangauli magawo ghake ghakuguliskika pa misika ya ndalama.<ref>{{Cite web |url=https://petrobras.com.br/en/quem-somos/perfil |title=Profile: Learn more about our company |publisher=Petrobras}}</ref>
== Kukhazikiskika ==
Petrobras yikakhazikiskika pa 3 Okutobala 1953, apo pulezidenti [[Getúlio Vargas]] wakasayina dango nambara 2,004. Kukhazikiskika kwake kukalondezganga kampeni yakumanyikwa kuti ''O petróleo é nosso'', kung'anamura kuti mafuta ni ghithu.
Chilato cha kampani iyi chikaŵa kukhozga ntchito za mafuta mu Brazil na kuchepeska kuthemba vyaru vinyake pa vinthu vya mafuta. Petrobras yikamba milimo yake mu 1954.<ref>{{Cite web |url=https://petrobras.com.br/en/quem-somos/trajetoria |title=Our history |publisher=Petrobras}}</ref>
== Milimo yake ==
Petrobras yikugwira ntchito zakupambanapambana mu makampani gha mafuta na gasi, kusazgapo:
* Kupenja malo agho ghangasangikamo mafuta na gasi.
* Kufukura na kusanga mafuta mu malo gha pa mtunda na mu nyanja.
* Kunozga mafuta mu mafakitale ghake.
* Kusunga na kunyamula mafuta na gasi.
* Kupanga vinthu vinyake ivyo vikufuma mu mafuta, kusazgapo mafuta gha magalimoto na vinthu vya makampani.
== Mafuta gha mu nyanja ==
Petrobras yikumanyikwa chifukwa cha ntchito zake za kufukura mafuta mu maji ghakuzika chomene. Kampani iyi yikakura mu luso lwa kufukura mafuta mu malo gha mu nyanja agho ghali pasi pa maji ghakuzika na ghakuzika chomene.
Ntchito izi zikawovwira kuti Brazil yiŵe yimoza mwa vyaru vyakuzirwa pa kupanga mafuta gha mu nyanja. Kweni ntchito za mafuta mu nyanja ziliso na masuzgo ghakukhwaskana na chilengedwe na kusintha kwa nyengo.
== Umo kampani yili kupangikira ==
Petrobras ni kampani iyo boma la Brazil likulongozga, kweni magawo ghake ghakuguliskika pa misika ya ndalama. Ichi chikung'anamura kuti boma lili na mazaza gha kuwusa kampani, kweni ŵanthu na mabungwe ghanyake nawo ŵangaŵa na magawo ghake.
== Kufunika kwake pa chuma cha Brazil ==
Petrobras ni kampani yakuzirwa pa chuma cha Brazil. Yikupereka ntchito ku ŵanthu, yikugula vinthu na mauteŵeti kufuma ku makampani ghanyake, ndipo yikuwovwira pa kusanga mafuta na gasi agho ghakugwiliskirika ntchito mu charu.
Kweniso kampani iyi yikugwira ntchito pa kafukufuku wa sayansi na tekinoloje, chomenechomene pa nkhani ya kufukura mafuta mu nyanja.
== Vyakukhwaskana na chilengedwe ==
Ntchito za mafuta na gasi zingakhwaska chilengedwe kwizira mu kufipiska maji, mphepo na dongo. Chifukwa cha ichi, Petrobras yikuchita ntchito za kusamalira malo agho yikugwirako ntchito na kusintha ndondomeko zake kuti zichepeske masuzgo gha chilengedwe.
Kufuma apo, kampani iyi yikugwira ntchito zakukhwaskana na mphamvu zinyake na kusintha kwa nthowa zakupangira na kugwiliskira ntchito nkhongono.
== Vithuzithuzi ==
<gallery>
File:Petrobras horizontal logo.svg|Chimanyikwiro cha Petrobras.
File:PETROBRÁS LOGO 1.jpg|Chimanyikwiro chakale cha Petrobras.
File:Oil platform (Brazil) 1.jpg|Sitima yakugwiliskira ntchito pa mafuta mu nyanja.
File:Oil platform (Brazil) 2.jpg|Malo ghakufukurako mafuta mu nyanja.
File:Oil platform P-51 (Brazil).jpg|Pulatifomu ya mafuta ya P-51.
File:Arco-íris na plataforma de petróleo em Angra dos Reis.jpg|Pulatifomu ya mafuta ku Brazil.
</gallery>
== Wonaniso ==
* [[Brazil]]
* [[Mbiri ya Brazil]]
* [[Estado Novo]]
* [[Mafuta]]
* [[Gasi wa mu charu]]
== Ukaboni ==
<references />
[[Category:Makampani gha ku Brazil]]
[[Category:Makampani gha mafuta na gasi]]
[[Category:Chuma cha Brazil]]
px0nvb6hffz40hon0a196be9o0n6j8b
Demokilase
0
50407
124324
2026-11-09T21:26:58Z
Tumbuka Arch
6863
Created page with "{{Short description|Ndondomeko ya boma iyo ŵanthu ŵakuŵa na mazaza gha kusankha ŵalongozgi ŵawo}} [[File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|thumb|250px|Nyumba ya Nyumba ya Malango ya Brazil, iyo yili na milimo yakupanga malango mu ndondomeko ya demokilase.]] '''Demokilase''' ni ndondomeko ya boma iyo mazaza gha kuwusa ghakufuma ku ŵanthu. Mu ndondomeko iyi, ŵanthu ŵakutora chigaŵa pa kusankha ŵalongozgi ŵawo kwizira mu mavoti, kwen..."
124324
wikitext
text/x-wiki
{{Short description|Ndondomeko ya boma iyo ŵanthu ŵakuŵa na mazaza gha kusankha ŵalongozgi ŵawo}}
[[File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|thumb|250px|Nyumba ya Nyumba ya Malango ya Brazil, iyo yili na milimo yakupanga malango mu ndondomeko ya demokilase.]]
'''Demokilase''' ni ndondomeko ya boma iyo mazaza gha kuwusa ghakufuma ku ŵanthu. Mu ndondomeko iyi, ŵanthu ŵakutora chigaŵa pa kusankha ŵalongozgi ŵawo kwizira mu mavoti, kweniso ŵali na wanangwa wa kuyowoya, kuwungana na kutora chigaŵa mu nkhani za boma.<ref>{{Cite web |url=https://www.un.org/en/node/117711 |title=Democracy and Human Rights |publisher=United Nations}}</ref>
Lizgu lakuti demokilase likufuma ku Chigiriki chakale. Lili na fundo ya kuti boma likwenera kugwira ntchito mwakuyana na khumbo la ŵanthu.
== Vinthu vyakuzirwa mu demokilase ==
Ndondomeko ya demokilase yikuŵa na vinthu vinandi vyakuzirwa:
* Mavoti gha nyengo na nyengo agho ghakuchitika mwakufwatuka na mwaunenesko.
* Wanangwa wa kuyowoya na kusankha maghanoghano.
* Wanangwa wa kupanga magulu na kuwungana mwamtende.
* Malango agho ghakugwira ntchito kwa ŵanthu wose.
* Makhoti agho ghangagwira ntchito kwambura kulamulirika na ŵalara ŵa boma.
* Wanangwa wa vyakupharazga kuti ŵanthu ŵamanye ivyo vikuchitika.
* Kutora chigaŵa kwa ŵanthu mu nkhani za boma.
United Nations yikulongora kuti mavoti gha nyengo na nyengo, wanangwa wa ŵanthu na kulondezga dango ni vinthu vyakuzirwa mu demokilase.<ref>{{Cite web |url=https://www.un.org/en/node/117711 |title=Democracy and Human Rights |publisher=United Nations}}</ref>
== Mitundu ya demokilase ==
=== Demokilase ya mwakudunjika ===
Mu demokilase ya mwakudunjika, ŵanthu ŵakujumphira yayi pa ŵimiliri ŵawo kuti ŵatore chigaŵa pa nkhani zinyake za boma. Ŵangavota mwakudunjika pa fundo panji dango linyake, nga ni mu referendum.
=== Demokilase ya ŵimiliri ===
Mu demokilase ya ŵimiliri, ŵanthu ŵakusankha ŵimiliri awo ŵakuŵayimira mu nyumba ya malango panji mu mabungwe ghanyake gha boma. Ŵimiliri aŵa ŵakupanga malango na kusanda ntchito ya boma.
Vyaru vinandi vikugwiliskira ntchito ndondomeko iyi.
== Mabungwe gha demokilase ==
Mu vyaru vinandi vya demokilase, mazaza gha boma ghakagaŵika mu vigaŵa vitatu:
* '''Boma lakupangiska malango''' – likuwungana na kupanga malango.
* '''Boma lakuchita milimo''' – likugwira ntchito ya kulongozga charu na kulondezga malango.
* '''Makhoti''' – ghakupima malango na kugamula milandu.
Kugaŵa mazaza uku kukovwira kuti bungwe limoza lileke kuŵa na nkhongono zose pa boma.
== Demokilase na wanangwa wa ŵanthu ==
Demokilase yikukhumbikwira kuti ŵanthu ŵaŵe na wanangwa wakuyowoya maghanoghano, kusopa, kuwungana, kupanga mabungwe na kutora chigaŵa mu mavoti. Kweniso ŵanthu ŵakwenera kuŵa na wanangwa wakusanga nkhani zakukhwaskana na ntchito za boma.
Kweni demokilase yikung'anamura waka mavoti yayi. Yikukhumbikwiraso malango ghakuyana, makhoti agho ghakugwira ntchito mwakufwatuka, na mabungwe agho ghakupwelelera wanangwa wa ŵanthu.
== Demokilase pa charu chose ==
Vyaru vinandi vili na ndondomeko za demokilase, kweni umo vikugwiliskira ntchito ndondomeko izi vikupambana. Gulu la Organization of American States likakhazikiska Inter-American Democratic Charter mu 2001 kuti likhozge demokilase, wanangwa wa ŵanthu na mavoti ghaunenesko mu vyaru vya America.<ref>{{Cite web |url=https://www.oas.org/en/democratic-charter/ |title=Inter-American Democratic Charter |publisher=Organization of American States}}</ref>
== Masuzgo agho demokilase yingakumana nagho ==
Ndondomeko ya demokilase yingakumana na masuzgo nga ni:
* Kusazgikira kwa vimbundi.
* Kukanizgika kwa wanangwa wa kuyowoya.
* Kuleka kugomezga mabungwe gha boma.
* Kusankhana pakati pa ŵanthu.
* Kukanizgika kwa mavoti panji kusokonezga ndondomeko ya mavoti.
Kovwira mabungwe gha boma kuti ghagwire ntchito mwakufwatuka na kusunga malango ni vinthu vyakuzirwa pakukhozga demokilase.
== Vithuzithuzi ==
<gallery>
File:Constituição da República Federativa do Brasil 1988 (livro de bolso,exemplar especial pela Encyclopaedia Britannica do Brasil).JPG|Buku la dango la Brazil.
File:Constituição do Brasil de 1988 in exposition.JPG|Dango la Brazil ilo likulongora maziko gha ndondomeko ya boma.
File:Palácio Congresso Nacional.jpg|Nyumba ya malango ya Brazil.
File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|Nyumba ya Congress ku Brasília.
</gallery>
== Wonaniso ==
* [[Malango gha Brazil]]
* [[Brazil]]
* [[Ndyali]]
* [[Mavoti]]
* [[Wanangwa wa ŵanthu]]
== Ukaboni ==
<references />
[[Category:Demokilase]]
[[Category:Ndyali]]
[[Category:Maboma]]
58uchj7w4q5w9wy6esnopdezxr9iuj3
Ŵalongozgi ŵa Brazil
0
50408
124325
2026-11-09T21:27:21Z
Tumbuka Arch
6863
Created page with "{{Short description|Ŵalongozgi awo ŵawusa Brazil kufuma apo yikazgokera ufumu na republic}} '''Ŵalongozgi ŵa Brazil''' ni ŵanthu awo ŵalongozga charu cha [[Brazil]] mu nyengo ya ufumu na mu nyengo ya Republic. Brazil yikaŵa ufumu kufuma mu 1822 mpaka 1889, ndipo kufuma apo yikazgoka republic iyo yili na pulezidenti kuŵa mutu wa charu na wa boma. == Ŵafumu ŵa Brazil == Pambere Brazil yindazgoke republic, yikaŵa ufumu wa nyumba ya Braganza. {| class="wikitable..."
124325
wikitext
text/x-wiki
{{Short description|Ŵalongozgi awo ŵawusa Brazil kufuma apo yikazgokera ufumu na republic}}
'''Ŵalongozgi ŵa Brazil''' ni ŵanthu awo ŵalongozga charu cha [[Brazil]] mu nyengo ya ufumu na mu nyengo ya Republic. Brazil yikaŵa ufumu kufuma mu 1822 mpaka 1889, ndipo kufuma apo yikazgoka republic iyo yili na pulezidenti kuŵa mutu wa charu na wa boma.
== Ŵafumu ŵa Brazil ==
Pambere Brazil yindazgoke republic, yikaŵa ufumu wa nyumba ya Braganza.
{| class="wikitable"
! Fumu
! Nyengo ya kuwusa
|-
| [[Pedro I wa ku Brazil|Pedro I]]
| 1822–1831
|-
| [[Pedro II wa ku Brazil|Pedro II]]
| 1831–1889, na nyengo ya regency pakati pa 1831 na 1840
|}
Pedro I wakapharazga wanangwa wa Brazil kufuma ku Portugal pa 7 Seputembala 1822. Wakaleka chitengo mu 1831, ndipo mwana wake Pedro II wakakwera pa chitengo apo wakaŵa mwana. Mu nyengo ya ubwana wake, charu chikawusika na ŵalara awo ŵakateŵeteranga nga ni regents.
Pedro II wakawusa mpaka apo ufumu ukamara mu 1889.
== Ŵapulezidenti ŵa Brazil ==
Pa 15 Novembala 1889, Brazil yikazgoka republic ndipo Deodoro da Fonseca wakazgoka mulongozgi wakwamba wa boma liphya.
=== Republic yakwamba (1889–1930) ===
Ŵalongozgi ŵakuzirwa mu nyengo iyi ŵakaŵa:
* Deodoro da Fonseca (1889–1891)
* Floriano Peixoto (1891–1894)
* Prudente de Morais (1894–1898)
* Campos Sales (1898–1902)
* Rodrigues Alves (1902–1906)
* Afonso Pena (1906–1909)
* Nilo Peçanha (1909–1910)
* Hermes da Fonseca (1910–1914)
* Venceslau Brás (1914–1918)
* Epitácio Pessoa (1919–1922)
* Artur Bernardes (1922–1926)
* Washington Luís (1926–1930)
== Nyengo ya Getúlio Vargas ==
[[Getúlio Vargas]] wakatora mazaza mu 1930 ndipo wakawusa mpaka 1945. Wakawelera kuŵa pulezidenti kwizira mu mavoti mu 1951 ndipo wakalutilira mpaka mu 1954.
Mu 1937, wakakhazikiska boma la wuzga wa ndyali ilo likachemekanga [[Estado Novo]]. Nyengo iyi yikamara mu 1945 apo Vargas wakafumiskika pa mazaza.
== Nyengo ya demokilase ya 1946–1964 ==
Pamanyuma pa 1945, Brazil yikawelera ku ndondomeko ya mavoti. Ŵalongozgi ŵakuzirwa mu nyengo iyi ŵakaŵa:
* Eurico Gaspar Dutra (1946–1951)
* Getúlio Vargas (1951–1954)
* Juscelino Kubitschek (1956–1961)
* Jânio Quadros (1961)
* João Goulart (1961–1964)
Mu vyaka ivi, ŵalongozgi ŵanyake ŵakagwira ntchito ya pulezidenti kwa nyengo yichoko chifukwa cha kuleka ntchito, nyifwa panji kusintha kwa boma.
== Nyengo ya kuwusa kwa ŵasilikari (1964–1985) ==
Mu 1964, ŵasilikari ŵakatora mazaza kufuma kwa pulezidenti João Goulart. Ŵalongozgi awo ŵakawusa mu nyengo iyi ŵakaŵa:
* Humberto Castelo Branco (1964–1967)
* Artur da Costa e Silva (1967–1969)
* Emílio Garrastazu Médici (1969–1974)
* Ernesto Geisel (1974–1979)
* João Figueiredo (1979–1985)
Mu nyengo iyi, mavoti gha pulezidenti ghakaŵa ghambura kufwatuka nga umo ghakuchitikira mu demokilase, ndipo boma likakanizganga ŵanthu awo ŵakasuskanga ndondomeko za ŵasilikari.
== Brazil pamanyuma pa 1985 ==
Mu 1985, boma la ŵasilikari likamara ndipo Brazil yikamba kuwelera ku ndondomeko ya demokilase. Ŵalongozgi awo ŵakawusa mu nyengo iyi ŵakusazgapo:
* José Sarney (1985–1990)
* Fernando Collor de Mello (1990–1992)
* Itamar Franco (1992–1995)
* Fernando Henrique Cardoso (1995–2003)
* [[Luiz Inácio Lula da Silva]] (2003–2011)
* Dilma Rousseff (2011–2016)
* Michel Temer (2016–2019)
* Jair Bolsonaro (2019–2023)
* Luiz Inácio Lula da Silva (2023–2027)
Tancredo Neves wakasankhika na ŵimiliri mu 1985 kuti wazgoke pulezidenti, kweni wakafwa pambere wandalape. Ntheura José Sarney ndiyo wakamba udindo wa pulezidenti.
== Pulezidenti wa mazuŵa ghano na kusankhikaso kwa 2026 ==
Pa 9 Novembala 2026, Luiz Inácio Lula da Silva ndiyo wakalutilira kuŵa pulezidenti wa Brazil, mu nyengo yake ya kuwusa iyo yikamba mu 2023. Pa 25 Okutobala 2026 wakasankhikaso kuti wazakawuse nyengo yachinayi. Nyengo yake yiphya yikeneranga kwamba pa 5 Janyuwale 2027.<ref>{{Cite web |url=https://www12.senado.leg.br/noticias/materias/2026/10/25/lula-e-reeleito-para-quarto-mandato-de-presidente |title=Lula é reeleito para quarto mandato de presidente |publisher=Senado Federal do Brasil |date=25 October 2026}}</ref>
== Vithuzithuzi ==
<gallery>
File:DpedroI-brasil.png|Fumu Pedro I.
File:Retrato do Imperador Dom Pedro II.jpg|Fumu Pedro II.
File:Getúlio Vargas - 1930.jpg|Getúlio Vargas.
File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|Nyumba ya Congress ku Brasília.
File:Pedro Américo - Independência ou Morte - Google Art Project.jpg|Chithuzithuzi cha wanangwa wa Brazil mu 1822.
</gallery>
== Wonaniso ==
* [[Mbiri ya Brazil]]
* [[Brazil]]
* [[Estado Novo]]
* [[Demokilase]]
* [[Ŵalongozgi ŵa South America]]
== Ukaboni ==
<references>
<ref>{{Cite web |url=https://www.biblioteca.presidencia.gov.br/presidencia/ex-presidentes |title=Ex-Presidentes |publisher=Biblioteca da Presidência da República}}</ref>
<ref>{{Cite web |url=https://www.gov.br/cti/pt-br/trajetoria-historica/presidentes-da-republica-desde-a-criacao-do-cti |title=Presidentes da República |publisher=Governo do Brasil}}</ref>
</references>
[[Category:Ŵalongozgi ŵa Brazil]]
[[Category:Mbiri ya Brazil]]
[[Category:Nduna na mapulezidenti]]
8egq0pyg41qsr72xp90jvaz0dbsbdp8
Ndyali za ku South America
0
50409
124326
2026-11-09T21:27:48Z
Tumbuka Arch
6863
Created page with "{{Short description|Ndondomeko za boma, magulu gha ndyali na ubwezi wa vyaru vya South America}} [[File:South America political map.png|thumb|250px|Mapu gha vyaru vya South America.]] '''Ndyali za ku South America''' zikulongosora umo maboma, magulu gha ndyali na mabungwe gha vyaru vya [[South America]] ghakugwilira ntchito, kweniso umo vyaru ivi vikuchitira ubwezi pakati pawo na na vyaru vinyake pa charu chose. South America yili na vyaru 12 vyakujiyimira pawekha: Ar..."
124326
wikitext
text/x-wiki
{{Short description|Ndondomeko za boma, magulu gha ndyali na ubwezi wa vyaru vya South America}}
[[File:South America political map.png|thumb|250px|Mapu gha vyaru vya South America.]]
'''Ndyali za ku South America''' zikulongosora umo maboma, magulu gha ndyali na mabungwe gha vyaru vya [[South America]] ghakugwilira ntchito, kweniso umo vyaru ivi vikuchitira ubwezi pakati pawo na na vyaru vinyake pa charu chose.
South America yili na vyaru 12 vyakujiyimira pawekha: [[Argentina]], [[Bolivia]], [[Brazil]], [[Chile]], [[Colombia]], [[Ecuador]], [[Guyana]], [[Paraguay]], [[Peru]], [[Suriname]], [[Uruguay]] na [[Venezuela]]. Kweniso ku chigaŵa ichi kuli French Guiana, iyo ni chigaŵa cha France.
== Mbiri yakale ya ndyali ==
=== Nyengo ya ukoloni ===
Pambere vyaru vya ku Europe vindafike, South America mukaŵa mitundu yinandi ya ŵanthu ŵakwambilira. Ŵanthu aŵa ŵakaŵa na maboma, mitheto na ndondomeko zakupambanapambana zakulongozgera malo ghawo.
Mu vyaka vya m'ma 1500, Spain na Portugal zikapoka malo ghakuru mu South America. Spain yikalamuliranga vigaŵa vikuruvikuru vya kumanjiliro gha dazi, apo Portugal yikawusa chigaŵa chikuru icho sono ni Brazil. Ukoloni uwu ukakhwaska chomene viyowoyero, chisopa, chuma na ndyali za charu ichi.
=== Nkhondo za wanangwa ===
Mu vyaka vya m'ma 1800, magulu gha wanangwa ghakamba kulimbana na ufumu wa Spain na Portugal. Ŵalongozgi nga ni Simón Bolívar na José de San Martín ŵakawovwira mu nkhondo zakupoka wanangwa wa vyaru vinandi.
Brazil yikapokera wanangwa mu 1822, apo vigaŵa vinandi ivyo kale vikawusikanga na Spain vikazgoka vyaru vyakujiyimira pawekha pakati pa 1810 na 1830.
== Mitundu ya maboma ==
Vyaru vya South America vili na ndondomeko zakupambanapambana za boma. Vyaru vinandi ni ma republic gha pulezidenti, agho pulezidenti wakusankhika na ŵanthu ndipo ndiyo ni mutu wa boma na wa boma lakuchita milimo.
Mu vyaru ivi, mabungwe gha boma kanandi ghakusazgapo:
* Pulezidenti panji mulongozgi wa boma.
* Nyumba ya malango iyo yikupanga malango.
* Makhoti agho ghakupima malango na kugamula milandu.
* Maboma gha vigaŵa panji vya mu misumba.
Ndondomeko za mavoti, nyengo ya kuwusa kwa ŵalongozgi na mazaza gha nyumba ya malango vikupambana pakati pa charu na charu.
== Nyengo ya ŵasilikari na maboma gha wuzga wa ndyali ==
Mu vyaka vya m'ma 1960, 1970 na vigaŵa vinyake vya m'ma 1980, vyaru vinandi vya South America vikaŵa pasi pa maboma gha ŵasilikari panji maboma agho ghakakanizganga magulu gha kususka.
Maboma agha ghakaŵa mu vyaru nga ni Argentina, Brazil, Chile, Paraguay na Uruguay. Mu nyengo iyi, ŵanthu ŵanandi ŵakakumana na kukanizgika kwa wanangwa wa kuyowoya, kukakika na kusuzgika chifukwa cha maghanoghano ghawo gha ndyali.
Mu vyaka vya m'ma 1980, vyaru vinandi vikamba kuwelera ku ndondomeko za mavoti na maboma gha ŵanthu ŵambura kuŵa ŵasilikari.<ref>{{Cite web |url=https://www.oas.org/en/democratic-charter/ |title=Inter-American Democratic Charter |publisher=Organization of American States}}</ref>
== Ndyali za mazuŵa ghano ==
Mazuŵa ghano, vyaru vya South America vili na magulu gha ndyali agho ghakusiyana pa maghanoghano ghawo gha chuma, ntchito za boma, wanangwa wa ŵanthu na umo charu chikwenera kulongozgekera.
Nkhani izo zikuzunulika kanandi mu ndyali za mu chigaŵa ichi ni:
* Kusazgikira kwa chuma na kuchepeska ukavu.
* Masambiro na mauteŵeti gha umoyo wa ŵanthu.
* Kusamalira charu na nkhorongo.
* Wanangwa wa ŵanthu ŵakwambilira na magulu ghanyake.
* Ulimi, migodi na mafuta.
* Kusama kwa ŵanthu pakati pa vyaru.
* Vimbundi na kugomezgeka kwa mabungwe gha boma.
Nkhani izi zikukhwaska vyaru mwakupambanapambana, ndipo boma lililose likusankha ndondomeko zake kuyana na malango na ndyali za charu chake.
== Mabungwe gha vyaru vya chigaŵa ichi ==
=== MERCOSUR ===
MERCOSUR ni bungwe la chuma na malonda ilo likakhazikiskika na phangano la Asunción mu 1991. Vyaru vyakwambilira ivyo vikakhazikiska bungwe ili ni Argentina, Brazil, Paraguay na Uruguay.
Chilato chake chikuru nkhuwovwira malonda pakati pa vyaru vyake, kuchepeska mphaka za malonda na kukolerana pa ndondomeko za chuma na malonda.<ref>{{Cite web |url=https://www.mercosur.int/en/about-mercosur/objectives-of-mercosur |title=Objectives of MERCOSUR |publisher=MERCOSUR}}</ref>
=== Organization of American States ===
Organization of American States (OAS) ni bungwe ilo lili na vyaru vya mu North America, Central America, South America na Caribbean. Likugwira ntchito pa nkhani za demokilase, wanangwa wa ŵanthu, mtende na kukolerana kwa vyaru.
Mu 2001, OAS yikazomerezga Inter-American Democratic Charter, iyo yikulongosora fundo za demokilase na kuvikilira mabungwe gha demokilase mu vyaru vya America.<ref>{{Cite web |url=https://www.oas.org/en/democratic-charter/ |title=Inter-American Democratic Charter |publisher=Organization of American States}}</ref>
== Ubwezi pakati pa vyaru ==
Vyaru vya South America vikuchita mapangano gha malonda, maungano gha ŵalongozgi na milimo ya kukolerana pa nkhani za chuma, chitetezo, vyakufumiska vinthu na kusamalira chilengedwe.
Kukolerana uku kukovwira kuti vyaru viwonane umo vingagwilira ntchito pamoza pa nkhani izo vikukhwaskana na chigaŵa chose.
== Vithuzithuzi ==
<gallery>
File:South America political map.png|Mapu gha vyaru vya South America.
File:South America laea location map.svg|Malo gha South America pa mapu.
File:South America Location.svg|South America pa mapu gha charu chose.
File:Palácio do Congresso Nacional - Brasília - 20250924230924.jpg|Nyumba ya malango ya Brazil, yimoza mwa nyumba za boma mu chigaŵa ichi.
</gallery>
== Wonaniso ==
* [[South America]]
* [[Brazil]]
* [[Argentina]]
* [[Chile]]
* [[Demokilase]]
* [[MERCOSUR]]
* [[Organization of American States]]
== Ukaboni ==
<references />
[[Category:Ndyali za South America]]
[[Category:Mbiri ya South America]]
[[Category:Ndyali]]
45yf5ic77xce3bosa2elxcoct43m1lw
Nikola Tesla
0
50410
124327
2026-11-09T21:29:30Z
Tumbuka Arch
6863
Created page with "{{Short description|Mwasayansi na munthu wakupanga vinthu viphya wa ku Serbia na United States}} [[File:Nikola Tesla around 1890.jpg|thumb|200px|Nikola Tesla mu chithuzithuzi cha pafupifupi 1890.]] '''Nikola Tesla''' (10 Julayi 1856 – 7 Janyuwale 1943) wakaŵa mwasayansi, munthu wakupanga vinthu viphya, na injiniya wa vya magetsi na makina. Wakababikira ku Smiljan, mu Ufumu wa Austria, uko sono ni chigaŵa cha [[Croatia]]. Wakaŵa wa mtundu wa Serbia, ndipo pamanyuma w..."
124327
wikitext
text/x-wiki
{{Short description|Mwasayansi na munthu wakupanga vinthu viphya wa ku Serbia na United States}}
[[File:Nikola Tesla around 1890.jpg|thumb|200px|Nikola Tesla mu chithuzithuzi cha pafupifupi 1890.]]
'''Nikola Tesla''' (10 Julayi 1856 – 7 Janyuwale 1943) wakaŵa mwasayansi, munthu wakupanga vinthu viphya, na injiniya wa vya magetsi na makina. Wakababikira ku Smiljan, mu Ufumu wa Austria, uko sono ni chigaŵa cha [[Croatia]]. Wakaŵa wa mtundu wa Serbia, ndipo pamanyuma wakazgoka mwanangwa wa charu cha [[United States]]. Tesla wakumanyikwa chomene chifukwa cha ntchito zake pa kupanga na kugwiliskira ntchito magetsi gha current yakusintha nthowa (AC), mota wa magetsi wa induction, na Tesla coil.<ref>[https://tesla-museum.org/en/extraordinary-world/birthplace/ Birthplace], Nikola Tesla Museum.</ref>
Ntchito zake zikawovwira kusintha umo magetsi ghakupangikira, kutolekera ku malo ghanyake na kugwiliskirika ntchito mu nyumba na mafakitale. Wakagwiriraso ntchito pa kafukufuku wa mawayilesi, ungweru wa magetsi na nthowa zakutumizgira uthenga kwambura wayaya.<ref>[https://www.eia.gov/kids/history-of-energy/famous-people/tesla.php Tesla (1856)], U.S. Energy Information Administration.</ref>
== Umoyo wake wa apo wakaŵa mwana ==
Tesla wakababika pa 10 Julayi 1856 mu muzi wa Smiljan, mu chigaŵa cha Lika, icho pa nyengo iyo chikaŵa pasi pa Ufumu wa Austria. Awiske ŵakaŵa Milutin Tesla, uyo wakaŵa wasembe wa chisopa cha Serbian Orthodox, ndipo amama ŵake ŵakaŵa Georgina (Đuka) Mandić. Amama ŵake ŵakamanyikwanga chifukwa cha luso lawo lwa kupanga na kunozga vinthu vya pa nyumba.<ref>[https://tesla-museum.org/en/extraordinary-world/birthplace/ Birthplace], Nikola Tesla Museum.</ref>
Tesla wakaŵa na ŵakuru ŵake na ŵadumbu ŵake, ndipo apo wakaŵa mwana wakalongora kutemwa masambiro na vinthu vya sayansi. Wakasambira mu sukulu ya sekondale ku Karlovac, uko wakamalizga masambiro mu 1873.
Mu 1875, wakamba masambiro gha vya injiniya wa magetsi ku Austrian Polytechnic ku Graz. Pamanyuma wakaluta ku Prague, uko wakasambira pa yunivesite, kweni wakamalizga yayi digiri ya yunivesite.
== Kwamba kwa ntchito yake ==
Mu vyaka vya m'ma 1880, Tesla wakagwira ntchito zakupambanapambana mu vyaru vya ku Europe. Mu Budapest, Hungary, wakagwira ntchito ku Central Telephone Exchange. Mu 1882, apo wakaŵa ku Budapest, wakamba kughanaghanira vya mota iyo yingagwiliskira ntchito munda wa magineti uwo ukuzungulira.
Mu 1882, wakasamira ku Paris, uko wakagwira ntchito ku kampani ya Continental Edison. Ntchito yake yikaŵa yakunozga na kunozgaso makina gha magetsi.
Mu Juni 1884, Tesla wakasamukira ku New York, ku United States. Wakaŵa na kalata yakumupharazga kwa munthu wakumanyikwa wa kupanga vinthu viphya, [[Thomas Edison]], ndipo wakamba kugwira ntchito ku Edison Machine Works.<ref>[https://www.eia.gov/kids/history-of-energy/famous-people/tesla.php Tesla (1856)], U.S. Energy Information Administration.</ref>
== Mota wa magetsi na current yakusintha nthowa ==
Chimoza mwa vinthu vikuru ivyo Tesla wakachita chikaŵa kupanga mota wa magetsi wa induction uwo ukagwiliskiranga ntchito current yakusintha nthowa. Mu 1887 na 1888, wakalemba mapatenti ghakukhwaskana na mota uwu na ndondomeko ya kugawira current ya magetsi mu vigaŵa vinandi.
Mu 1888, George Westinghouse, uyo wakaŵa mulongozgi wa Westinghouse Electric Company, wakagura wanangwa wa kugwiliskira ntchito mapatenti ghanyake gha Tesla. Tesla wakagwiriraso ntchito na kampani iyi kuti ndondomeko ya magetsi gha AC yigwiliskike ntchito mu mafakitale na mu misumba.<ref>[https://www.eia.gov/kids/history-of-energy/famous-people/tesla.php Tesla (1856)], U.S. Energy Information Administration.</ref>
Current yakusintha nthowa yikovwira kutoleka pa mtunda utali na kusintha voltage yake kwizira mu transformer. Ichi chikawovwira kuti magetsi ghafikenge ku nyumba na mafakitale agho ghali kutali na malo agho ghakupangikirako.
== Nkhondo ya current ==
Mu vyaka vya m'ma 1880 na 1890, kukakhalanga kupambana maghanoghano pa nthowa yiwemi yakupangira na kugawira magetsi. Thomas Edison wakakhozgeranga current yambura kusintha nthowa (DC), apo Tesla na George Westinghouse ŵakakhozgeranga current yakusintha nthowa (AC).
Kupambana uku kukamanyikwa kuti ''War of Currents'', kung'anamura nkhondo ya current. Tesla na Westinghouse ŵakawovwira kuti ndondomeko ya AC yimanyikwe na kugwiliskika ntchito chomene pa kutoleka kwa magetsi pa mtunda utali.
Mu 1893, ndondomeko ya AC ya Westinghouse na Tesla yikagwiliskirika ntchito ku Chicago pa chiphikiro chikuru cha vyakuwonetska cha World's Columbian Exposition. Magetsi agha ghakawovwira kuŵoneska umo current ya AC yingagwiliskikira ntchito pa malo ghakuru.<ref>[https://www.eia.gov/kids/history-of-energy/famous-people/tesla.php Tesla (1856)], U.S. Energy Information Administration.</ref>
== Tesla coil ==
Mu 1891, Tesla wakapanga chipangizo icho chikamanyikwa pamanyuma kuti Tesla coil. Chipangizo ichi chikugwiliskira ntchito transformer kuti chipange current ya ma frequency ghapachanya na voltage yikuru.
Tesla coil yikazgoka yakuzirwa pa viyezgelero vya magetsi na pa kafukufuku wa tekinoloje ya mawayilesi. Mpaka mazuŵa ghano, ma coil gha mtundu uwu ghakugwiliskirika ntchito mu viyezgelero vya sayansi na mu vyakuwoneskera vya magetsi.<ref>[https://www.eia.gov/kids/history-of-energy/famous-people/tesla.php Tesla (1856)], U.S. Energy Information Administration.</ref>
== Chicago na Niagara Falls ==
Mu 1893, Tesla na Westinghouse ŵakawovwira kuŵoneska ndondomeko yawo ya AC pa World's Columbian Exposition ku Chicago.
Mu 1895, malo ghakupangira magetsi gha maji ghakazengeka pa [[Niagara Falls]]. Malo agha ghakagwiliskira ntchito ndondomeko ya AC iyo Tesla wakawovwira kupanga. Mu 1896, magetsi ghakufuma ku Niagara Falls ghakafika ku Buffalo, New York. Ichi chikaŵa chinthu chakuzirwa chomene pa mbiri ya kupanga na kutolera magetsi pa mtunda utali.<ref>[https://americanhistory.si.edu/lighting/scripts/s19e.htm Lighting a Revolution: Consequences of 19th Century Lighting], Smithsonian National Museum of American History.</ref>
== Laboratory ya Colorado Springs ==
Mu 1899, Tesla wakasamukira ku Colorado Springs, ku United States, uko wakanozga laboratory kuti wachite viyezgelero vya magetsi gha voltage yikuru, current ya ma frequency ghapachanya na nthowa zakutumizgira nkhongono kwambura wayaya.
Mu laboratory iyi, wakagwiliskira ntchito chipangizo chikuru icho wakachemanga magnifying transmitter. Chipangizo ichi chikapangiska kuti magetsi ghapange mazaza gha ungweru wakuthwa agho ghakawonekanga nga ni vimwemwe vya ŵaleza.
Mu nyengo iyi Tesla wakalembaso vyakukumbukira vyake vya kafukufuku mu buku ilo likumanyikwa kuti ''Colorado Springs Notes''.<ref>[https://tesla-museum.org/en/extraordinary-world/teslas-tower/ Tesla's tower], Nikola Tesla Museum.</ref>
== Wardenclyffe Tower ==
Mu 1901, Tesla wakamba kuzenga malo ghakuchitirako kafukufuku na nsanja ya Wardenclyffe Tower pa Long Island, ku New York. Chilato chake chikaŵa kupanga ndondomeko yakutumizgira uthenga na nkhongono za magetsi kwambura kugwiliskira ntchito wayaya.
Tesla wakakhumbanga kuti nsanja iyi yiŵe chiyambi cha ndondomeko iyo yikatenge yitumizgenge uthenga, mazgu, vithuzithuzi na nkhongono za magetsi pa mtunda utali. Kweni ntchito iyi yikakumana na masuzgo gha ndalama, ndipo ŵanthu awo ŵakamupenge ndalama ŵakaleka kumovwira.
Ntchito ya nsanja iyi yikamara pambere yindamalizgike. Mu 1917, nsanja yikabwangandulika na kuguliskika nga ni vyuma kuti ndalama zake zigwiriskike ntchito kulipira ngongoli. Nyumba ya laboratory ya Wardenclyffe yicalipo mpaka mazuŵa ghano.<ref>[https://tesla-museum.org/en/extraordinary-world/teslas-tower/ Tesla's tower], Nikola Tesla Museum.</ref>
== Vinthu vinyake ivyo wakachita ==
Tesla wakachita kafukufuku pa nkhani zinandi za sayansi na tekinoloje, kusazgapo:
* Mota wa magetsi wa induction.
* Ndondomeko ya current yakusintha nthowa (AC).
* Tesla coil.
* Ungweru wa fluorescent na viyezgelero vya ungweru wa magetsi.
* Kafukufuku wa mawayilesi na kutumizgira uthenga kwambura wayaya.
* Kafukufuku wa X-ray.
* Chipangizo chakulongozgera sitima yichoko kwizira mu mawoneskero gha wayilesi.
Mu 1898, Tesla wakalongora sitima yichoko ya pa maji iyo wakayilongozganga kwizira mu mawoneskero gha wayilesi pa chiwoneskero cha ku New York. Ichi chikaŵa chimanyikwiro chakuzirwa pa kukura kwa nthowa zakulongozgera makina kwambura kukhumbikwa kukhwasira na mawoko.
== Umoyo wake waumaliro ==
Mu vyaka vyake vyaumaliro, Tesla wakakhalanga chomene mu mahoteli gha ku New York. Nangauli wakalutilira kughanaghanira vya sayansi na kupanga vinthu viphya, wakakumana na masuzgo gha ndalama ndipo ntchito zinandi izo wakakhumbanga kuchita zikaleka kumara.
Tesla wakafwa pa 7 Janyuwale 1943 mu chipinda chake cha hotelo ya New Yorker ku New York City, apo wakaŵa na vyaka 86.<ref>[https://www.history.com/articles/nikola-tesla Nikola Tesla], HISTORY.com.</ref>
== Chiharo chake ==
Nikola Tesla wakukumbukika nga ni yumoza mwa ŵanthu ŵakuzirwa chomene pa mbiri ya sayansi na tekinoloje. Ntchito zake zikawovwira kuti ndondomeko ya current yakusintha nthowa yizgoke nthowa yikuru yakugwiliskira ntchito magetsi pa charu chose.
Mota wa induction na ndondomeko ya AC vikugwiliskirika ntchito mu mafakitale, nyumba na makina gha mazuŵa ghano. Zina lake likagwiliskirikaso ntchito pa kupereka zina ku chipimo cha magineti icho chikuchemeka tesla (T).
== Vithuzithuzi ==
<gallery>
File:Nikola Tesla around 1890.jpg|Nikola Tesla mu chithuzithuzi cha pafupifupi 1890.
File:Nikola Tesla, with his equipment Wellcome M0014782.jpg|Tesla mu laboratory yake ya Colorado Springs. Chithuzithuzi ichi chikapangika mwa kusazga vithuzithuzi viŵiri.
File:Tesla Colorado Springs lab-12 million volts.jpg|Chipangizo cha Tesla icho chikapanga current ya voltage yikuru.
File:Tesla Colorado Springs laboratory exterior.jpg|Nyumba ya laboratory ya Tesla ku Colorado Springs.
File:Tesla's laboratory in Colorado.jpg|Chigaŵa cha mukati mwa laboratory ya Tesla.
File:Experiment in wireless power transmission by Nikola Tesla at his laboratory in Colorado Springs in 1899.png|Chiyezgelero cha kutumizgira nkhongono za magetsi kwambura wayaya mu 1899.
File:Tesla Colorado Springs lab-resonance between coils.jpg|Chiyezgelero cha resonance mu laboratory ya Tesla.
</gallery>
== Wonaniso ==
* [[Thomas Edison]]
* [[George Westinghouse]]
* [[Current yakusintha nthowa]]
* [[Mota wa magetsi]]
* [[Tesla coil]]
* [[Sayansi ya magetsi]]
* [[Niagara Falls]]
* [[Wardenclyffe Tower]]
== Ukaboni ==
<references />
[[Category:Ŵakubabika mu 1856]]
[[Category:Ŵakufwa mu 1943]]
[[Category:Ŵanthu ŵa ku Serbia]]
[[Category:Ŵasayansi ŵa ku United States]]
[[Category:Ŵanthu awo ŵakapanga vinthu viphya]]
[[Category:Ŵainjiniya ŵa magetsi]]
[[Category:Mbiri ya sayansi]]
5bj28hwd0wberfkgs6mujk1q0l2cn76
Category:Ŵakubabika mu 1856
14
50411
124328
2026-11-09T21:30:24Z
Tumbuka Arch
6863
Created blank page
124328
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵanthu ŵa ku Serbia
14
50412
124329
2026-11-09T21:30:26Z
Tumbuka Arch
6863
Created blank page
124329
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵasayansi ŵa ku United States
14
50413
124330
2026-11-09T21:30:29Z
Tumbuka Arch
6863
Created blank page
124330
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵainjiniya ŵa magetsi
14
50414
124331
2026-11-09T21:30:31Z
Tumbuka Arch
6863
Created blank page
124331
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵanthu awo ŵakapanga vinthu viphya
14
50415
124332
2026-11-09T21:30:34Z
Tumbuka Arch
6863
Created blank page
124332
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Mbiri ya sayansi
14
50416
124333
2026-11-09T21:30:37Z
Tumbuka Arch
6863
Created blank page
124333
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1
Category:Ŵakufwa mu 1943
14
50417
124334
2026-11-09T21:30:56Z
Tumbuka Arch
6863
Created blank page
124334
wikitext
text/x-wiki
phoiac9h4m842xq45sp7s6u21eteeq1