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("&#35;", "#") -- 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;', '#'), '&#35;', '#'), ';') 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("&#35;", "#") -- 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;', '#'), '&#35;', '#'), ';') 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]', { ['['] = '&#91;', [']'] = '&#93;', ['\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 .. '&nbsp;', '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("&mdash;", 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 ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; 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&#035') or url:match ('%.pdf&#035'); 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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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]', { ['['] = '&#91;', [']'] = '&#93;', ['\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 .. '&nbsp;', '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("&mdash;", 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 ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; 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&#035') or url:match ('%.pdf&#035'); 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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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 .. '&nbsp;', '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&nbsp;ed.)', ['episode'] = 'Episode $1', ['et al'] = 'et&nbsp;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">&#124;$1=</code> / <code class="cs1-code">&#124;$2=</code> mismatch', -- $1 is year param name; $2 is date param name ['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]:&nbsp;$1', ['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none ['original'] = 'the original', ['origdate'] = ' [$1]', ['retrieved'] = 'Retrieved $1', ['season'] = 'Season $1', ['section'] = '§&nbsp;$1', ['sections'] = '§§&nbsp;$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.&nbsp;$2', -- $1 is sepc; bold journal style volume is in presentation{} ['vol-no'] = '$1 Vol.&nbsp;$2, no.&nbsp;$3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization) ['issue'] = '$1 No.&nbsp;$2', -- $1 is sepc ['art'] = '$1 Art.&nbsp;$2', -- $1 is sepc; for {{cite conference}} only ['vol-art'] = '$1 Vol.&nbsp;$2, art.&nbsp;$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.&nbsp;$2", -- $1 is sepc ['pp-prefix'] = "$1 pp.&nbsp;$2", -- $1 is sepc ['j-page(s)'] = ': $1', -- same for page and pages ['sheet'] = '$1 Sheet&nbsp;$2', -- $1 is sepc ['sheets'] = '$1 Sheets&nbsp;$2', -- $1 is sepc ['j-sheet'] = ': Sheet&nbsp;$1', ['j-sheets'] = ': Sheets&nbsp;$1', ['language'] = '(in $1)', ['via'] = " &ndash; 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;">&#123;{$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;">&#123;{$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 &#8239; 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">&#124;$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'] = "&#91;''$1''&#93;", ['trans-quoted-title'] = "&#91;$1&#93;", -- 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]?%.&nbsp;', -- 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">&#124;access-date=</code> requires <code class="cs1-code">&#124;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">&#124;$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">&#124;archive-date=</code> requires <code class="cs1-code">&#124;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">&#124;archive-date=</code> / <code class="cs1-code">&#124;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">&#124;archive-url=</code> requires <code class="cs1-code">&#124;archive-date=</code>', anchor = 'archive_missing_date', category = 'CS1 errors: archive-url', hidden = false }, err_archive_missing_url = { message = '<code class="cs1-code">&#124;archive-url=</code> requires <code class="cs1-code">&#124;url=</code>', anchor = 'archive_missing_url', category = 'CS1 errors: archive-url', hidden = false }, err_archive_url = { message = '<code class="cs1-code">&#124;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">&#124;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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;arxiv=</code> value', anchor = 'bad_arxiv', category = 'CS1 errors: arXiv', hidden = false }, err_bad_asin = { message = 'Check <code class="cs1-code">&#124;asin=</code> value', anchor = 'bad_asin', category ='CS1 errors: ASIN', hidden = false }, err_bad_asin_tld = { message = 'Check <code class="cs1-code">&#124;asin-tld=</code> value', anchor = 'bad_asin_tld', category ='CS1 errors: ASIN TLD', hidden = false }, err_bad_bibcode = { message = 'Check <code class="cs1-code">&#124;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">&#124;biorxiv=</code> value', anchor = 'bad_biorxiv', category = 'CS1 errors: bioRxiv', hidden = false }, err_bad_citeseerx = { message = 'Check <code class="cs1-code">&#124;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">&#124;doi=</code> value', anchor = 'bad_doi', category = 'CS1 errors: DOI', hidden = false }, err_bad_hdl = { message = 'Check <code class="cs1-code">&#124;hdl=</code> value', anchor = 'bad_hdl', category = 'CS1 errors: HDL', hidden = false }, err_bad_isbn = { message = 'Check <code class="cs1-code">&#124;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">&#124;ismn=</code> value', anchor = 'bad_ismn', category = 'CS1 errors: ISMN', hidden = false }, err_bad_issn = { message = 'Check <code class="cs1-code">&#124;$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">&#124;jfm=</code> value', anchor = 'bad_jfm', category = 'CS1 errors: JFM', hidden = false }, err_bad_jstor = { message = 'Check <code class="cs1-code">&#124;jstor=</code> value', anchor = 'bad_jstor', category = 'CS1 errors: JSTOR', hidden = false }, err_bad_lccn = { message = 'Check <code class="cs1-code">&#124;lccn=</code> value', anchor = 'bad_lccn', category = 'CS1 errors: LCCN', hidden = false }, err_bad_medrxiv = { message = 'Check <code class="cs1-code">&#124;medrxiv=</code> value', anchor = 'bad_medrxiv', category = 'CS1 errors: medRxiv', hidden = false }, err_bad_mr = { message = 'Check <code class="cs1-code">&#124;mr=</code> value', anchor = 'bad_mr', category = 'CS1 errors: MR', hidden = false }, err_bad_oclc = { message = 'Check <code class="cs1-code">&#124;oclc=</code> value', anchor = 'bad_oclc', category = 'CS1 errors: OCLC', hidden = false }, err_bad_ol = { message = 'Check <code class="cs1-code">&#124;ol=</code> value', anchor = 'bad_ol', category = 'CS1 errors: OL', hidden = false }, err_bad_osti = { message = 'Check <code class="cs1-code">&#124;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">&#124;$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">&#124;pmc=</code> value', anchor = 'bad_pmc', category = 'CS1 errors: PMC', hidden = false }, err_bad_pmid = { message = 'Check <code class="cs1-code">&#124;pmid=</code> value', anchor = 'bad_pmid', category = 'CS1 errors: PMID', hidden = false }, err_bad_rfc = { message = 'Check <code class="cs1-code">&#124;rfc=</code> value', anchor = 'bad_rfc', category = 'CS1 errors: RFC', hidden = false }, err_bad_s2cid = { message = 'Check <code class="cs1-code">&#124;s2cid=</code> value', anchor = 'bad_s2cid', category = 'CS1 errors: S2CID', hidden = false }, err_bad_sbn = { message = 'Check <code class="cs1-code">&#124;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">&#124;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">&#124;message-id=</code> value', anchor = 'bad_message_id', category = 'CS1 errors: message-id', hidden = false }, err_bad_zbl = { message = 'Check <code class="cs1-code">&#124;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">&#124;biorxiv=</code> required', anchor = 'biorxiv_missing', category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv hidden = false }, err_chapter_ignored = { message = '<code class="cs1-code">&#124;$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">&#124;$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">&#124;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">&#124;url=</code>', anchor = 'cite_web_url', category = 'CS1 errors: requires URL', hidden = false }, err_class_ignored = { message = '<code class="cs1-code">&#124;class=</code> ignored', anchor = 'class_ignored', category = 'CS1 errors: class', hidden = false }, err_contributor_ignored = { message = '<code class="cs1-code">&#124;contributor=</code> ignored', anchor = 'contributor_ignored', category = 'CS1 errors: contributor', hidden = false }, err_contributor_missing_required_param = { message = '<code class="cs1-code">&#124;contributor=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;$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">&#124;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">&#124;$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">&#124;$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">&#124;$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">&#124;$1=</code> missing <code class="cs1-code">&#124;$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">&#124;$1=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;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">&#124;$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">&#124;$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">&#124;$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">&#124;$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">&#124;$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">&#124;$1-access=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$1=</code> ignored (<code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;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">&#124;trans-$1=</code> requires <code class="cs1-code">&#124;$1=</code> or <code class="cs1-code">&#124;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">&#124;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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, } --[[--------------------------< 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&nbsp;ed.)', ['episode'] = 'Episode $1', ['et al'] = 'et&nbsp;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">&#124;$1=</code> / <code class="cs1-code">&#124;$2=</code> mismatch', -- $1 is year param name; $2 is date param name ['newsgroup'] = '[[Usenet newsgroup|Newsgroup]]:&nbsp;$1', ['notitle'] = 'No title', -- for |title=(()) and (in the future) |title=none ['original'] = 'the original', ['origdate'] = ' [$1]', ['retrieved'] = 'Retrieved $1', ['season'] = 'Season $1', ['section'] = '§&nbsp;$1', ['sections'] = '§§&nbsp;$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.&nbsp;$2', -- $1 is sepc; bold journal style volume is in presentation{} ['vol-no'] = '$1 Vol.&nbsp;$2, no.&nbsp;$3', -- sepc, volume, issue (alternatively insert $1 after $2, but then we'd also have to change capitalization) ['issue'] = '$1 No.&nbsp;$2', -- $1 is sepc ['art'] = '$1 Art.&nbsp;$2', -- $1 is sepc; for {{cite conference}} only ['vol-art'] = '$1 Vol.&nbsp;$2, art.&nbsp;$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.&nbsp;$2", -- $1 is sepc ['pp-prefix'] = "$1 pp.&nbsp;$2", -- $1 is sepc ['j-page(s)'] = ': $1', -- same for page and pages ['sheet'] = '$1 Sheet&nbsp;$2', -- $1 is sepc ['sheets'] = '$1 Sheets&nbsp;$2', -- $1 is sepc ['j-sheet'] = ': Sheet&nbsp;$1', ['j-sheets'] = ': Sheets&nbsp;$1', ['language'] = '(in $1)', ['via'] = " &ndash; 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;">&#123;{$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;">&#123;{$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 &#8239; 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">&#124;$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'] = "&#91;''$1''&#93;", ['trans-quoted-title'] = "&#91;$1&#93;", -- 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]?%.&nbsp;', -- 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">&#124;access-date=</code> requires <code class="cs1-code">&#124;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">&#124;$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">&#124;archive-date=</code> requires <code class="cs1-code">&#124;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">&#124;archive-date=</code> / <code class="cs1-code">&#124;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">&#124;archive-url=</code> requires <code class="cs1-code">&#124;archive-date=</code>', anchor = 'archive_missing_date', category = 'CS1 errors: archive-url', hidden = false }, err_archive_missing_url = { message = '<code class="cs1-code">&#124;archive-url=</code> requires <code class="cs1-code">&#124;url=</code>', anchor = 'archive_missing_url', category = 'CS1 errors: archive-url', hidden = false }, err_archive_url = { message = '<code class="cs1-code">&#124;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">&#124;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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;arxiv=</code> value', anchor = 'bad_arxiv', category = 'CS1 errors: arXiv', hidden = false }, err_bad_asin = { message = 'Check <code class="cs1-code">&#124;asin=</code> value', anchor = 'bad_asin', category ='CS1 errors: ASIN', hidden = false }, err_bad_asin_tld = { message = 'Check <code class="cs1-code">&#124;asin-tld=</code> value', anchor = 'bad_asin_tld', category ='CS1 errors: ASIN TLD', hidden = false }, err_bad_bibcode = { message = 'Check <code class="cs1-code">&#124;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">&#124;biorxiv=</code> value', anchor = 'bad_biorxiv', category = 'CS1 errors: bioRxiv', hidden = false }, err_bad_citeseerx = { message = 'Check <code class="cs1-code">&#124;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">&#124;doi=</code> value', anchor = 'bad_doi', category = 'CS1 errors: DOI', hidden = false }, err_bad_hdl = { message = 'Check <code class="cs1-code">&#124;hdl=</code> value', anchor = 'bad_hdl', category = 'CS1 errors: HDL', hidden = false }, err_bad_isbn = { message = 'Check <code class="cs1-code">&#124;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">&#124;ismn=</code> value', anchor = 'bad_ismn', category = 'CS1 errors: ISMN', hidden = false }, err_bad_issn = { message = 'Check <code class="cs1-code">&#124;$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">&#124;jfm=</code> value', anchor = 'bad_jfm', category = 'CS1 errors: JFM', hidden = false }, err_bad_jstor = { message = 'Check <code class="cs1-code">&#124;jstor=</code> value', anchor = 'bad_jstor', category = 'CS1 errors: JSTOR', hidden = false }, err_bad_lccn = { message = 'Check <code class="cs1-code">&#124;lccn=</code> value', anchor = 'bad_lccn', category = 'CS1 errors: LCCN', hidden = false }, err_bad_medrxiv = { message = 'Check <code class="cs1-code">&#124;medrxiv=</code> value', anchor = 'bad_medrxiv', category = 'CS1 errors: medRxiv', hidden = false }, err_bad_mr = { message = 'Check <code class="cs1-code">&#124;mr=</code> value', anchor = 'bad_mr', category = 'CS1 errors: MR', hidden = false }, err_bad_oclc = { message = 'Check <code class="cs1-code">&#124;oclc=</code> value', anchor = 'bad_oclc', category = 'CS1 errors: OCLC', hidden = false }, err_bad_ol = { message = 'Check <code class="cs1-code">&#124;ol=</code> value', anchor = 'bad_ol', category = 'CS1 errors: OL', hidden = false }, err_bad_osti = { message = 'Check <code class="cs1-code">&#124;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">&#124;$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">&#124;pmc=</code> value', anchor = 'bad_pmc', category = 'CS1 errors: PMC', hidden = false }, err_bad_pmid = { message = 'Check <code class="cs1-code">&#124;pmid=</code> value', anchor = 'bad_pmid', category = 'CS1 errors: PMID', hidden = false }, err_bad_rfc = { message = 'Check <code class="cs1-code">&#124;rfc=</code> value', anchor = 'bad_rfc', category = 'CS1 errors: RFC', hidden = false }, err_bad_s2cid = { message = 'Check <code class="cs1-code">&#124;s2cid=</code> value', anchor = 'bad_s2cid', category = 'CS1 errors: S2CID', hidden = false }, err_bad_sbn = { message = 'Check <code class="cs1-code">&#124;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">&#124;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">&#124;message-id=</code> value', anchor = 'bad_message_id', category = 'CS1 errors: message-id', hidden = false }, err_bad_zbl = { message = 'Check <code class="cs1-code">&#124;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">&#124;biorxiv=</code> required', anchor = 'biorxiv_missing', category = 'CS1 errors: bioRxiv', -- same as bad bioRxiv hidden = false }, err_chapter_ignored = { message = '<code class="cs1-code">&#124;$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">&#124;$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">&#124;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">&#124;url=</code>', anchor = 'cite_web_url', category = 'CS1 errors: requires URL', hidden = false }, err_class_ignored = { message = '<code class="cs1-code">&#124;class=</code> ignored', anchor = 'class_ignored', category = 'CS1 errors: class', hidden = false }, err_contributor_ignored = { message = '<code class="cs1-code">&#124;contributor=</code> ignored', anchor = 'contributor_ignored', category = 'CS1 errors: contributor', hidden = false }, err_contributor_missing_required_param = { message = '<code class="cs1-code">&#124;contributor=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;$1=</code> requires <code class="cs1-code">&#124;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">&#124;$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">&#124;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">&#124;$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">&#124;$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">&#124;$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">&#124;$1=</code> missing <code class="cs1-code">&#124;$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">&#124;$1=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;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">&#124;$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">&#124;$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">&#124;$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">&#124;$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">&#124;$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">&#124;$1-access=</code> requires <code class="cs1-code">&#124;$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">&#124;$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">&#124;$1=</code> ignored (<code class="cs1-code">&#124;$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">&#124;$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">&#124;$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">&#124;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">&#124;trans-$1=</code> requires <code class="cs1-code">&#124;$1=</code> or <code class="cs1-code">&#124;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">&#124;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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', 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 = '&nbsp;', 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 = '&nbsp;', }, ['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 = '&nbsp;', }, } --[[--------------------------< 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 (&ndash; etc.) with hyphens; do we need to replace numerical entities like &#32; 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;">&#39;(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s value = value:gsub ('&nbsp;', ' '); -- replace &nbsp; 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 ('&zwj;', ''); -- remove &zwj; 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 (&ndash; etc.) with hyphens; do we need to replace numerical entities like &#32; 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;">&#39;(s?)</span>', "'%1"); -- replace {{'}} or {{'s}} with simple apostrophe or apostrophe-s value = value:gsub ('&nbsp;', ' '); -- replace &nbsp; 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 ('&zwj;', ''); -- remove &zwj; 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 = "&nbsp;" 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.."&params="..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 = "&nbsp;" 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.."&params="..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&#x20;%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&#x20;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&#x20;%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&#x20;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&params=1_2_N_3_4_W_ or //tools.wmflabs.org/geohack/geohack.php?pagename=Example&params=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&params=1_2_N_3_4_W_ or //tools.wmflabs.org/geohack/geohack.php?pagename=Example&params=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 == "&#123;&#123;&#123;coordinates&#125;&#125;&#125;" 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 == "&#123;&#123;&#123;coordinates&#125;&#125;&#125;" 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) .. '&lt;' .. tag .. '&gt;...&lt;/' .. tag .. '&gt;') 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) .. '&lt;' .. tag .. '&gt;...&lt;/' .. tag .. '&gt;') 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&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;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' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; 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&nbsp;policy on&nbsp;the&nbsp;biographies" .. ' of&nbsp;living&nbsp;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' .. ' &#123;&#123;[[Template:unblock|unblock]]&#125;&#125; 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 ghakupimiki­ra.<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 ghakupimiki­ra.<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|}}}|&nbsp;(in {{{visitors_year}}})}}}} | label13 = Beginning&nbsp;date | data13 = {{{begin|}}} | label14 = Completion&nbsp;date | data14 = {{{complete|}}} | label15 = Opening&nbsp;date | data15 = {{{open|}}} | label16 = Dedicated&nbsp;date | data16 = {{{dedicated|}}} | label17 = Inauguration&nbsp;date | data17 = {{{inaugurated|}}} | label18 = Restored&nbsp;date | data18 = {{{restore|}}} | label19 = Dedicated&nbsp;to | data19 = {{{dedicated_to|}}} | label20 = Dismantled&nbsp;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|}}}|&nbsp;(in {{{visitors_year}}})}}}} | label13 = Beginning&nbsp;date | data13 = {{{begin|}}} | label14 = Completion&nbsp;date | data14 = {{{complete|}}} | label15 = Opening&nbsp;date | data15 = {{{open|}}} | label16 = Dedicated&nbsp;date | data16 = {{{dedicated|}}} | label17 = Inauguration&nbsp;date | data17 = {{{inaugurated|}}} | label18 = Restored&nbsp;date | data18 = {{{restore|}}} | label19 = Dedicated&nbsp;to | data19 = {{{dedicated_to|}}} | label20 = Dismantled&nbsp;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&nbsp;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&nbsp;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&nbsp;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&nbsp;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>]]'''&nbsp;•&nbsp;[[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/&#126;2026-22816-44|&#126;2026-22816-44]] ([[User talk:&#126;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>]]'''&nbsp;•&nbsp;[[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/&#126;2026-22816-44|&#126;2026-22816-44]] ([[User talk:&#126;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|}}}&#x20;{{{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|}}}&#x20;{{{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''' &ndash; the formal name of the occupation. Can be <nowiki>{{PAGENAME}}</nowiki>. * '''image''' &ndash; ''optional'' &ndash; 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''' &ndash; ''optional'' &ndash; the text to be placed below the image. * '''official_names''' &ndash; ''optional'' &ndash; the names or synonyms for the particular occupation, including the principal name (which can be <nowiki>{{PAGENAME}}</nowiki>). * '''type''' &ndash; ''optional'' &ndash; the type of occupation (e.g. "[[profession]]", "[[employment]]", "[[vocation]]", "[[performing arts]]", "[[military]]", etc.). * '''activity_sector''' &ndash; ''optional'' &ndash; the main activity sectors of the occupation (e.g. "[[management]]", "[[science]]", "[[laboratory]]", "[[circus]]", "[[Forms of government|government]]", "[[show business]]", etc.). * '''competencies''' &ndash; ''optional'' &ndash; competencies and qualities required. * '''formation''' &ndash; ''optional'' &ndash; formation and education necessary. * '''employment_field''' &ndash; ''optional'' &ndash; fields of employment and places we can encounter someone with the occupation. * '''related_occupation''' &ndash; ''optional'' &ndash; 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''' &ndash; the formal name of the occupation. Can be <nowiki>{{PAGENAME}}</nowiki>. * '''image''' &ndash; ''optional'' &ndash; 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''' &ndash; ''optional'' &ndash; the text to be placed below the image. * '''official_names''' &ndash; ''optional'' &ndash; the names or synonyms for the particular occupation, including the principal name (which can be <nowiki>{{PAGENAME}}</nowiki>). * '''type''' &ndash; ''optional'' &ndash; the type of occupation (e.g. "[[profession]]", "[[employment]]", "[[vocation]]", "[[performing arts]]", "[[military]]", etc.). * '''activity_sector''' &ndash; ''optional'' &ndash; the main activity sectors of the occupation (e.g. "[[management]]", "[[science]]", "[[laboratory]]", "[[circus]]", "[[Forms of government|government]]", "[[show business]]", etc.). * '''competencies''' &ndash; ''optional'' &ndash; competencies and qualities required. * '''formation''' &ndash; ''optional'' &ndash; formation and education necessary. * '''employment_field''' &ndash; ''optional'' &ndash; fields of employment and places we can encounter someone with the occupation. * '''related_occupation''' &ndash; ''optional'' &ndash; 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